public function testInitializeWithoutSubitem() { $qty = 3; $websiteId = 1; $productId = 1; $stockItem = $this->getMockBuilder('Magento\\CatalogInventory\\Model\\Stock\\Item')->setMethods(['checkQuoteItemQty', 'setProductName', 'setIsChildItem', 'hasIsChildItem', '__wakeup'])->disableOriginalConstructor()->getMock(); $storeMock = $this->getMockBuilder('Magento\\Store\\Model\\Store')->disableOriginalConstructor()->getMock(); $storeMock->expects($this->any())->method('getWebsiteId')->willReturn($websiteId); $quoteItem = $this->getMockBuilder('Magento\\Quote\\Model\\Quote\\Item')->setMethods(['getProduct', 'getParentItem', 'getQtyToAdd', 'getId', 'getQuoteId', '__wakeup'])->disableOriginalConstructor()->getMock(); $product = $this->getMockBuilder('Magento\\Catalog\\Model\\Product')->disableOriginalConstructor()->getMock(); $productTypeCustomOption = $this->getMockBuilder('Magento\\Catalog\\Model\\Product\\Configuration\\Item\\Option')->disableOriginalConstructor()->getMock(); $result = $this->getMockBuilder('Magento\\Framework\\Object')->setMethods(['getItemIsQtyDecimal', 'getHasQtyOptionUpdate', 'getItemUseOldQty', 'getMessage', 'getItemBackorders'])->disableOriginalConstructor()->getMock(); $product->expects($this->any())->method('getStore')->willReturn($storeMock); $product->expects($this->any())->method('getId')->willReturn($productId); $quoteItem->expects($this->once())->method('getParentItem')->will($this->returnValue(false)); $quoteItem->expects($this->once())->method('getQtyToAdd')->will($this->returnValue(false)); $quoteItem->expects($this->any())->method('getProduct')->will($this->returnValue($product)); $quoteItem->expects($this->once())->method('getId')->will($this->returnValue('quote_item_id')); $quoteItem->expects($this->once())->method('getQuoteId')->will($this->returnValue('quote_id')); $this->quoteItemQtyList->expects($this->any())->method('getQty')->with($productId, 'quote_item_id', 'quote_id', $qty)->will($this->returnValue('summary_qty')); $this->stockStateMock->expects($this->once())->method('checkQuoteItemQty')->withAnyParameters()->will($this->returnValue($result)); $product->expects($this->once())->method('getCustomOption')->with('product_type')->will($this->returnValue($productTypeCustomOption)); $productTypeCustomOption->expects($this->once())->method('getValue')->will($this->returnValue('option_value')); $this->typeConfig->expects($this->once())->method('isProductSet')->with('option_value')->will($this->returnValue(true)); $product->expects($this->once())->method('getName')->will($this->returnValue('product_name')); $stockItem->expects($this->once())->method('setProductName')->with('product_name')->will($this->returnSelf()); $stockItem->expects($this->once())->method('setIsChildItem')->with(true)->will($this->returnSelf()); $stockItem->expects($this->once())->method('hasIsChildItem')->will($this->returnValue(false)); $result->expects($this->once())->method('getItemIsQtyDecimal')->will($this->returnValue(null)); $result->expects($this->once())->method('getHasQtyOptionUpdate')->will($this->returnValue(false)); $result->expects($this->once())->method('getItemUseOldQty')->will($this->returnValue(null)); $result->expects($this->once())->method('getMessage')->will($this->returnValue(null)); $result->expects($this->once())->method('getItemBackorders')->will($this->returnValue(null)); $this->model->initialize($stockItem, $quoteItem, $qty); }
/** * Check product inventory data when quote item quantity declaring * * @param \Magento\Framework\Event\Observer $observer * * @return void * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function validate(\Magento\Framework\Event\Observer $observer) { /* @var $quoteItem \Magento\Quote\Model\Quote\Item */ $quoteItem = $observer->getEvent()->getItem(); if (!$quoteItem || !$quoteItem->getProductId() || !$quoteItem->getQuote() || $quoteItem->getQuote()->getIsSuperMode()) { return; } $qty = $quoteItem->getQty(); /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */ $stockItem = $this->stockRegistry->getStockItem($quoteItem->getProduct()->getId(), $quoteItem->getProduct()->getStore()->getWebsiteId()); /* @var $stockItem \Magento\CatalogInventory\Api\Data\StockItemInterface */ if (!$stockItem instanceof \Magento\CatalogInventory\Api\Data\StockItemInterface) { throw new \Magento\Framework\Exception\LocalizedException(__('The stock item for Product is not valid.')); } $parentStockItem = false; /** * Check if product in stock. For composite products check base (parent) item stock status */ if ($quoteItem->getParentItem()) { $product = $quoteItem->getParentItem()->getProduct(); $parentStockItem = $this->stockRegistry->getStockItem($product->getId(), $product->getStore()->getWebsiteId()); } if ($stockItem) { if (!$stockItem->getIsInStock() || $parentStockItem && !$parentStockItem->getIsInStock()) { $quoteItem->addErrorInfo('cataloginventory', \Magento\CatalogInventory\Helper\Data::ERROR_QTY, __('This product is out of stock.')); $quoteItem->getQuote()->addErrorInfo('stock', 'cataloginventory', \Magento\CatalogInventory\Helper\Data::ERROR_QTY, __('Some of the products are out of stock.')); return; } else { // Delete error from item and its quote, if it was set due to item out of stock $this->_removeErrorsFromQuoteAndItem($quoteItem, \Magento\CatalogInventory\Helper\Data::ERROR_QTY); } } /** * Check item for options */ if (($options = $quoteItem->getQtyOptions()) && $qty > 0) { $qty = $quoteItem->getProduct()->getTypeInstance()->prepareQuoteItemQty($qty, $quoteItem->getProduct()); $quoteItem->setData('qty', $qty); if ($stockItem) { $result = $this->stockState->checkQtyIncrements($quoteItem->getProduct()->getId(), $qty, $quoteItem->getProduct()->getStore()->getWebsiteId()); if ($result->getHasError()) { $quoteItem->addErrorInfo('cataloginventory', \Magento\CatalogInventory\Helper\Data::ERROR_QTY_INCREMENTS, $result->getMessage()); $quoteItem->getQuote()->addErrorInfo($result->getQuoteMessageIndex(), 'cataloginventory', \Magento\CatalogInventory\Helper\Data::ERROR_QTY_INCREMENTS, $result->getQuoteMessage()); } else { // Delete error from item and its quote, if it was set due to qty problems $this->_removeErrorsFromQuoteAndItem($quoteItem, \Magento\CatalogInventory\Helper\Data::ERROR_QTY_INCREMENTS); } } foreach ($options as $option) { $result = $this->optionInitializer->initialize($option, $quoteItem, $qty); if ($result->getHasError()) { $option->setHasError(true); $quoteItem->addErrorInfo('cataloginventory', \Magento\CatalogInventory\Helper\Data::ERROR_QTY, $result->getMessage()); $quoteItem->getQuote()->addErrorInfo($result->getQuoteMessageIndex(), 'cataloginventory', \Magento\CatalogInventory\Helper\Data::ERROR_QTY, $result->getQuoteMessage()); } else { // Delete error from item and its quote, if it was set due to qty lack $this->_removeErrorsFromQuoteAndItem($quoteItem, \Magento\CatalogInventory\Helper\Data::ERROR_QTY); } } } else { $result = $this->stockItemInitializer->initialize($stockItem, $quoteItem, $qty); if ($result->getHasError()) { $quoteItem->addErrorInfo('cataloginventory', \Magento\CatalogInventory\Helper\Data::ERROR_QTY, $result->getMessage()); $quoteItem->getQuote()->addErrorInfo($result->getQuoteMessageIndex(), 'cataloginventory', \Magento\CatalogInventory\Helper\Data::ERROR_QTY, $result->getQuoteMessage()); } else { // Delete error from item and its quote, if it was set due to qty lack $this->_removeErrorsFromQuoteAndItem($quoteItem, \Magento\CatalogInventory\Helper\Data::ERROR_QTY); } } }