Skip to content

Commit 13b80b4

Browse files
committed
MC-33400: [Improvement] Magento\Checkout\Model\Cart::addOrderItem
1 parent bb7e08f commit 13b80b4

File tree

1 file changed

+91
-40
lines changed

1 file changed

+91
-40
lines changed

app/code/Magento/Sales/Model/Reorder/Reorder.php

Lines changed: 91 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,22 @@
66
declare(strict_types=1);
77
namespace Magento\Sales\Model\Reorder;
88

9+
use Magento\Catalog\Api\Data\ProductInterface;
910
use Magento\Catalog\Api\ProductRepositoryInterface;
1011
use Magento\Catalog\Model\Product;
12+
use Magento\Framework\Api\SearchCriteriaBuilder;
13+
use Magento\Framework\App\ObjectManager;
1114
use Magento\Framework\Exception\InputException;
1215
use Magento\Framework\Exception\NoSuchEntityException;
1316
use Magento\Quote\Api\CartRepositoryInterface;
1417
use Magento\Quote\Api\Data\CartInterface;
1518
use Magento\Quote\Model\Cart\CustomerCartResolver;
19+
use Magento\Quote\Model\Quote as Quote;
20+
use Magento\Sales\Api\Data\OrderItemInterface;
1621
use Magento\Sales\Helper\Reorder as ReorderHelper;
1722
use Magento\Sales\Model\Order\Item;
1823
use Magento\Sales\Model\OrderFactory;
24+
use Magento\Sales\Model\ResourceModel\Order\Item\Collection as ItemCollection;
1925

2026
/**
2127
* Allows customer quickly to reorder previously added products and put them to the Cart
@@ -81,28 +87,37 @@ class Reorder
8187
*/
8288
private $customerCartProvider;
8389

90+
/**
91+
* @var SearchCriteriaBuilder
92+
*/
93+
private $searchCriteriaBuilder;
94+
8495
/**
8596
* @param OrderFactory $orderFactory
8697
* @param CustomerCartResolver $customerCartProvider
8798
* @param CartRepositoryInterface $cartRepository
8899
* @param ProductRepositoryInterface $productRepository
89100
* @param ReorderHelper $reorderHelper
90101
* @param \Psr\Log\LoggerInterface $logger
102+
* @param SearchCriteriaBuilder $searchCriteriaBuilder = null
91103
*/
92104
public function __construct(
93105
OrderFactory $orderFactory,
94106
CustomerCartResolver $customerCartProvider,
95107
CartRepositoryInterface $cartRepository,
96108
ProductRepositoryInterface $productRepository,
97109
ReorderHelper $reorderHelper,
98-
\Psr\Log\LoggerInterface $logger
110+
\Psr\Log\LoggerInterface $logger,
111+
SearchCriteriaBuilder $searchCriteriaBuilder = null
99112
) {
100113
$this->orderFactory = $orderFactory;
101114
$this->cartRepository = $cartRepository;
102115
$this->productRepository = $productRepository;
103116
$this->reorderHelper = $reorderHelper;
104117
$this->logger = $logger;
105118
$this->customerCartProvider = $customerCartProvider;
119+
$this->searchCriteriaBuilder = $searchCriteriaBuilder ?:
120+
ObjectManager::getInstance()->get(SearchCriteriaBuilder::class);
106121
}
107122

108123
/**
@@ -133,66 +148,102 @@ public function execute(string $orderNumber, string $storeId): Data\ReorderOutpu
133148
return $this->prepareOutput($cart);
134149
}
135150

136-
$items = $order->getItemsCollection();
137-
foreach ($items as $item) {
138-
$this->addOrderItem($cart, $item);
139-
}
151+
$cartWithItems = $this->addItemsToCart($cart, $order->getItemsCollection());
140152

141153
try {
142-
$this->cartRepository->save($cart);
154+
$this->cartRepository->save($cartWithItems);
143155
} catch (\Magento\Framework\Exception\LocalizedException $e) {
144156
// handle exception from \Magento\Quote\Model\QuoteRepository\SaveHandler::save
145157
$this->addError($e->getMessage());
146158
}
147159

148-
$cart = $this->cartRepository->get($cart->getId());
160+
$savedCart = $this->cartRepository->get($cartWithItems->getId());
149161

150-
return $this->prepareOutput($cart);
162+
return $this->prepareOutput($savedCart);
151163
}
152164

153165
/**
154-
* Convert order item to quote item
166+
* Add collections of order items to cart.
155167
*
156-
* @param \Magento\Quote\Model\Quote $cart
157-
* @param Item $orderItem
158-
* @return void
168+
* @param Quote $cart
169+
* @param ItemCollection $orderItems
170+
* @return Quote
159171
*/
160-
private function addOrderItem(\Magento\Quote\Model\Quote $cart, $orderItem): void
172+
private function addItemsToCart(Quote $cart, ItemCollection $orderItems): Quote
161173
{
162-
/* @var $orderItem Item */
163-
if ($orderItem->getParentItem() === null) {
164-
$info = $orderItem->getProductOptionByCode('info_buyRequest');
165-
$info = new \Magento\Framework\DataObject($info);
166-
$info->setQty($orderItem->getQtyOrdered());
167-
168-
try {
169-
/** @var Product $product */
170-
$product = $this->productRepository->getById($orderItem->getProductId(), false, null, true);
171-
} catch (NoSuchEntityException $e) {
174+
$orderItemProductIds = [];
175+
/** @var \Magento\Sales\Model\Order\Item[] $orderItemsByProductId */
176+
$orderItemsByProductId = [];
177+
178+
/** @var \Magento\Sales\Model\Order\Item $item */
179+
foreach ($orderItems as $item) {
180+
if ($item->getParentItem() === null) {
181+
$orderItemProductIds[] = $item->getProductId();
182+
$orderItemsByProductId[$item->getProductId()] = $item;
183+
}
184+
}
185+
186+
$criteria = $this->searchCriteriaBuilder
187+
->addFilter('entity_id', $orderItemProductIds, 'in')
188+
->create();
189+
190+
/** @var \Magento\Catalog\Api\Data\ProductInterface $products */
191+
$products = $this->productRepository->getList($criteria)->getItems();
192+
193+
// compare founded products and throw an error if some product not exists
194+
$productsNotFound = array_diff($orderItemProductIds, array_keys($products));
195+
if (!empty($productsNotFound)) {
196+
foreach ($productsNotFound as $productId) {
197+
/** @var \Magento\Sales\Model\Order\Item $orderItemProductNotFound */
172198
$this->addError(
173-
(string)__('Could not find a product with ID "%1"', $orderItem->getProductId()),
199+
(string)__('Could not find a product with ID "%1"', $productId),
174200
self::ERROR_PRODUCT_NOT_FOUND
175201
);
176-
return;
177-
}
178-
$addProductResult = null;
179-
try {
180-
$addProductResult = $cart->addProduct($product, $info);
181-
} catch (\Magento\Framework\Exception\LocalizedException $e) {
182-
$this->addError($this->getCartItemErrorMessage($orderItem, $product, $e->getMessage()));
183-
} catch (\Throwable $e) {
184-
$this->logger->critical($e);
185-
$this->addError($this->getCartItemErrorMessage($orderItem, $product), self::ERROR_UNDEFINED);
186202
}
203+
}
187204

188-
// error happens in case the result is string
189-
if (is_string($addProductResult)) {
190-
$errors = array_unique(explode("\n", $addProductResult));
191-
foreach ($errors as $error) {
192-
$this->addError($this->getCartItemErrorMessage($orderItem, $product, $error));
193-
}
205+
/** @var ProductInterface $product */
206+
foreach ($products as $product) {
207+
$orderItem = $orderItemsByProductId[$product->getId()];
208+
$this->addItemToCart($orderItem, $cart, $product);
209+
}
210+
211+
return $cart;
212+
}
213+
214+
/**
215+
* Adds order item product to cart.
216+
*
217+
* @param OrderItemInterface $orderItem
218+
* @param Quote $cart
219+
* @param ProductInterface $product
220+
* @return Quote
221+
*/
222+
private function addItemToCart(OrderItemInterface $orderItem, Quote $cart, ProductInterface $product): Quote
223+
{
224+
$info = $orderItem->getProductOptionByCode('info_buyRequest');
225+
$info = new \Magento\Framework\DataObject($info);
226+
$info->setQty($orderItem->getQtyOrdered());
227+
228+
$addProductResult = null;
229+
try {
230+
$addProductResult = $cart->addProduct($product, $info);
231+
} catch (\Magento\Framework\Exception\LocalizedException $e) {
232+
$this->addError($this->getCartItemErrorMessage($orderItem, $product, $e->getMessage()));
233+
} catch (\Throwable $e) {
234+
$this->logger->critical($e);
235+
$this->addError($this->getCartItemErrorMessage($orderItem, $product), self::ERROR_UNDEFINED);
236+
}
237+
238+
// error happens in case the result is string
239+
if (is_string($addProductResult)) {
240+
$errors = array_unique(explode("\n", $addProductResult));
241+
foreach ($errors as $error) {
242+
$this->addError($this->getCartItemErrorMessage($orderItem, $product, $error));
194243
}
195244
}
245+
246+
return $cart;
196247
}
197248

198249
/**

0 commit comments

Comments
 (0)