setData($field, $request->getData($field)); } } public function addProduct( \Magento\Catalog\Model\Product $product, $request = null, $processMode = \Magento\Catalog\Model\Product\Type\AbstractType::PROCESS_MODE_FULL ) { if ($request === null) { $request = 1; } if (is_numeric($request)) { $request = $this->objectFactory->create(['qty' => $request]); } if (!$request instanceof \Magento\Framework\DataObject) { throw new \Magento\Framework\Exception\LocalizedException( __('We found an invalid request for adding product to quote.') ); } if (!$product->isSalable()) { throw new \Magento\Framework\Exception\LocalizedException( __('Product that you are trying to add is not available.') ); } $cartCandidates = $product->getTypeInstance()->prepareForCartAdvanced($request, $product, $processMode); /** * Error message */ if (is_string($cartCandidates) || $cartCandidates instanceof \Magento\Framework\Phrase) { return (string)$cartCandidates; } /** * If prepare process return one object */ if (!is_array($cartCandidates)) { $cartCandidates = [$cartCandidates]; } $parentItem = null; $errors = []; $item = null; $items = []; foreach ($cartCandidates as $candidate) { // Child items can be sticked together only within their parent $stickWithinParent = $candidate->getParentProductId() ? $parentItem : null; $candidate->setStickWithinParent($stickWithinParent); $item = $this->getItemByProduct($candidate); if (!$item) { $item = $this->itemProcessor->init($candidate, $request); $item->setQuote($this); $item->setOptions($candidate->getCustomOptions()); $item->setProduct($candidate); $this->addCustomDataToItem($item, $request); // Add only item that is not in quote already $this->addItem($item); } $items[] = $item; /** * As parent item we should always use the item of first added product */ if (!$parentItem) { $parentItem = $item; } if ($parentItem && $candidate->getParentProductId() && !$item->getParentItem()) { $item->setParentItem($parentItem); } $this->itemProcessor->prepare($item, $request, $candidate); // collect errors instead of throwing first one if ($item->getHasError()) { $this->deleteItem($item); foreach ($item->getMessage(false) as $message) { if (!in_array($message, $errors)) { // filter duplicate messages $errors[] = $message; } } break; } } if (!empty($errors)) { throw new \Magento\Framework\Exception\LocalizedException(__(implode("\n", $errors))); } $this->_eventManager->dispatch('sales_quote_product_add_after', ['items' => $items]); return $parentItem; } public function getItemsCollection($useCache = true) { if ($this->hasItemsCollection() && $useCache) { return $this->getData('items_collection'); } if (null === $this->_items || !$useCache) { $this->_items = $this->_quoteItemCollectionFactory->create(); $this->_items->setOrder('item_sort', 'asc'); $this->extensionAttributesJoinProcessor->process($this->_items); $this->_items->setQuote($this); } return $this->_items; } }