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);
         }
     }
 }