Skip to content

Commit cf3a156

Browse files
committed
Merge branch 'ACP2E-368' of https://github.com/magento-l3/magento2ce into PR1-21-01-2022
2 parents 3f59cae + 10ffde7 commit cf3a156

File tree

2 files changed

+302
-54
lines changed

2 files changed

+302
-54
lines changed

app/code/Magento/Quote/Model/Cart/AddProductsToCart.php

Lines changed: 88 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
use Magento\Catalog\Api\ProductRepositoryInterface;
1111
use Magento\Framework\Exception\NoSuchEntityException;
1212
use Magento\Quote\Api\CartRepositoryInterface;
13-
use Magento\Quote\Api\Data\CartInterface;
1413
use Magento\Quote\Model\Cart\BuyRequest\BuyRequestBuilder;
1514
use Magento\Quote\Model\Cart\Data\AddProductsToCartOutput;
1615
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
@@ -51,11 +50,6 @@ class AddProductsToCart
5150
*/
5251
private $productRepository;
5352

54-
/**
55-
* @var array
56-
*/
57-
private $errors = [];
58-
5953
/**
6054
* @var CartRepositoryInterface
6155
*/
@@ -101,87 +95,128 @@ public function execute(string $maskedCartId, array $cartItems): AddProductsToCa
10195
{
10296
$cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId);
10397
$cart = $this->cartRepository->get($cartId);
104-
105-
foreach ($cartItems as $cartItemPosition => $cartItem) {
106-
$this->addItemToCart($cart, $cartItem, $cartItemPosition);
107-
}
108-
98+
$allErrors = [];
10999
if ($cart->getData('has_error')) {
110100
$errors = $cart->getErrors();
111101

112102
/** @var MessageInterface $error */
113103
foreach ($errors as $error) {
114-
$this->addError($error->getText());
104+
$allErrors[] = $this->createError($error->getText());
115105
}
116106
}
117107

118-
if (count($this->errors) !== 0) {
108+
$failedCartItems = $this->addItemsToCart($cart, $cartItems);
109+
$saveCart = empty($failedCartItems);
110+
if (!empty($failedCartItems)) {
111+
/* Check if some cart items were successfully added to the cart */
112+
if (count($failedCartItems) < count($cartItems)) {
113+
/* Revert changes introduced by add to cart processes in case of an error */
114+
$cart->getItemsCollection()->clear();
115+
$newFailedCartItems = $this->addItemsToCart($cart, array_diff_key($cartItems, $failedCartItems));
116+
$failedCartItems += $newFailedCartItems;
117+
$saveCart = empty($newFailedCartItems);
118+
}
119+
foreach (array_keys($cartItems) as $cartItemPosition) {
120+
if (isset($failedCartItems[$cartItemPosition])) {
121+
array_push($allErrors, ...$failedCartItems[$cartItemPosition]);
122+
}
123+
}
124+
}
125+
126+
if ($saveCart) {
127+
$this->cartRepository->save($cart);
128+
}
129+
130+
if (count($allErrors) !== 0) {
119131
/* Revert changes introduced by add to cart processes in case of an error */
120132
$cart->getItemsCollection()->clear();
121133
}
122134

123-
return $this->prepareErrorOutput($cart);
135+
return $this->prepareErrorOutput($cart, $allErrors);
136+
}
137+
138+
/**
139+
* Add cart items to cart
140+
*
141+
* @param Quote $cart
142+
* @param array $cartItems
143+
* @return array
144+
*/
145+
public function addItemsToCart(Quote $cart, array $cartItems): array
146+
{
147+
$failedCartItems = [];
148+
149+
foreach ($cartItems as $cartItemPosition => $cartItem) {
150+
$errors = $this->addItemToCart($cart, $cartItem, $cartItemPosition);
151+
if ($errors) {
152+
$failedCartItems[$cartItemPosition] = $errors;
153+
}
154+
}
155+
156+
return $failedCartItems;
124157
}
125158

126159
/**
127160
* Adds a particular item to the shopping cart
128161
*
129-
* @param CartInterface|Quote $cart
162+
* @param Quote $cart
130163
* @param Data\CartItem $cartItem
131164
* @param int $cartItemPosition
165+
* @return array
132166
*/
133-
private function addItemToCart(CartInterface $cart, Data\CartItem $cartItem, int $cartItemPosition): void
167+
private function addItemToCart(Quote $cart, Data\CartItem $cartItem, int $cartItemPosition): array
134168
{
135169
$sku = $cartItem->getSku();
170+
$errors = [];
171+
$result = null;
172+
$product = null;
136173

137174
if ($cartItem->getQuantity() <= 0) {
138-
$this->addError(__('The product quantity should be greater than 0')->render());
139-
140-
return;
141-
}
142-
143-
try {
144-
$product = $this->productRepository->get($sku, false, null, true);
145-
} catch (NoSuchEntityException $e) {
146-
$this->addError(
147-
__('Could not find a product with SKU "%sku"', ['sku' => $sku])->render(),
175+
$errors[] = $this->createError(
176+
__('The product quantity should be greater than 0')->render(),
148177
$cartItemPosition
149178
);
179+
} else {
180+
try {
181+
$product = $this->productRepository->get($sku, false, null, true);
182+
} catch (NoSuchEntityException $e) {
183+
$errors[] = $this->createError(
184+
__('Could not find a product with SKU "%sku"', ['sku' => $sku])->render(),
185+
$cartItemPosition
186+
);
187+
}
150188

151-
return;
152-
}
153-
154-
try {
155-
$result = $cart->addProduct($product, $this->requestBuilder->build($cartItem));
156-
$this->cartRepository->save($cart);
157-
} catch (\Throwable $e) {
158-
$this->addError(
159-
__($e->getMessage())->render(),
160-
$cartItemPosition
161-
);
162-
$cart->setHasError(false);
163-
164-
return;
165-
}
189+
if ($product !== null) {
190+
try {
191+
$result = $cart->addProduct($product, $this->requestBuilder->build($cartItem));
192+
} catch (\Throwable $e) {
193+
$errors[] = $this->createError(
194+
__($e->getMessage())->render(),
195+
$cartItemPosition
196+
);
197+
}
166198

167-
if (is_string($result)) {
168-
$errors = array_unique(explode("\n", $result));
169-
foreach ($errors as $error) {
170-
$this->addError(__($error)->render(), $cartItemPosition);
199+
if (is_string($result)) {
200+
foreach (array_unique(explode("\n", $result)) as $error) {
201+
$errors[] = $this->createError(__($error)->render(), $cartItemPosition);
202+
}
203+
}
171204
}
172205
}
206+
207+
return $errors;
173208
}
174209

175210
/**
176-
* Add order line item error
211+
* Returns an error object
177212
*
178213
* @param string $message
179214
* @param int $cartItemPosition
180-
* @return void
215+
* @return Data\Error
181216
*/
182-
private function addError(string $message, int $cartItemPosition = 0): void
217+
private function createError(string $message, int $cartItemPosition = 0): Data\Error
183218
{
184-
$this->errors[] = new Data\Error(
219+
return new Data\Error(
185220
$message,
186221
$this->getErrorCode($message),
187222
$cartItemPosition
@@ -211,13 +246,13 @@ private function getErrorCode(string $message): string
211246
/**
212247
* Creates a new output from existing errors
213248
*
214-
* @param CartInterface $cart
249+
* @param Quote $cart
250+
* @param array $errors
215251
* @return AddProductsToCartOutput
216252
*/
217-
private function prepareErrorOutput(CartInterface $cart): AddProductsToCartOutput
253+
private function prepareErrorOutput(Quote $cart, array $errors = []): AddProductsToCartOutput
218254
{
219-
$output = new AddProductsToCartOutput($cart, $this->errors);
220-
$this->errors = [];
255+
$output = new AddProductsToCartOutput($cart, $errors);
221256
$cart->setHasError(false);
222257

223258
return $output;

0 commit comments

Comments
 (0)