Skip to content

Commit b4e6dd5

Browse files
committed
ACP2E-2174: allow qty change for cart items without errors
1 parent 7a8bf20 commit b4e6dd5

File tree

3 files changed

+75
-30
lines changed

3 files changed

+75
-30
lines changed

app/code/Magento/Checkout/Controller/Cart/UpdateItemQty.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,11 @@ private function updateItemQuantity(Item $item, float $qty)
131131
if ($qty > 0) {
132132
$item->clearMessage();
133133
$item->setHasError(false);
134+
$oldQty = $item->getQty();
134135
$item->setQty($qty);
135136

136137
if ($item->getHasError()) {
138+
$item->setQty($oldQty);
137139
throw new LocalizedException(__($item->getMessage()));
138140
}
139141
}

app/code/Magento/Checkout/Model/Cart.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
2020
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2121
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
22+
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
2223
* @deprecated 100.1.0 Use \Magento\Quote\Model\Quote instead
2324
* @see \Magento\Quote\Api\Data\CartInterface
2425
* @since 100.0.2
@@ -535,6 +536,9 @@ public function updateItems($data)
535536

536537
$qty = isset($itemInfo['qty']) ? (double)$itemInfo['qty'] : false;
537538
if ($qty > 0) {
539+
if ($item->getHasError()) {
540+
$item->setUseOldQty(true);
541+
}
538542
$item->clearMessage();
539543
$item->setHasError(false);
540544
$item->setQty($qty);

dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php

Lines changed: 69 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
use Magento\Customer\Model\ResourceModel\CustomerRepository;
1818
use Magento\Framework\Data\Form\FormKey;
1919
use Magento\Framework\Api\SearchCriteriaBuilder;
20+
use Magento\Framework\Exception\LocalizedException;
21+
use Magento\Framework\Exception\NoSuchEntityException;
22+
use Magento\Quote\Api\Data\CartInterface;
23+
use Magento\Quote\Api\Data\CartItemInterface;
2024
use Magento\Quote\Model\Quote;
2125
use Magento\Quote\Api\CartRepositoryInterface;
2226
use Magento\Quote\Model\QuoteRepository;
@@ -468,6 +472,10 @@ private function prepareRequest(string $method)
468472
}
469473
}
470474

475+
/**
476+
* @throws NoSuchEntityException
477+
* @throws LocalizedException
478+
*/
471479
#[
472480
DataFixture(ProductFixture::class, ['sku' => 's1', 'stock_item' => ['is_in_stock' => true]], 'p1'),
473481
DataFixture(ProductFixture::class, ['sku' => 's2','stock_item' => ['is_in_stock' => true]], 'p2'),
@@ -483,7 +491,8 @@ private function prepareRequest(string $method)
483491
'item2'
484492
)
485493
]
486-
public function testUpdatePostActionWithMultipleProducts() {
494+
public function testUpdatePostActionWithMultipleProducts()
495+
{
487496
$cartId = (int)$this->fixtures->get('cart')->getId();
488497
if (!$cartId) {
489498
$this->fail('quote fixture failed');
@@ -513,52 +522,82 @@ public function testUpdatePostActionWithMultipleProducts() {
513522
$updatedQuantity = 2;
514523

515524
$this->assertEquals(
516-
$quote->getItemsQty(),
517525
$originalQuantity + $originalQuantity,
518-
"Precondition failed: invalid quote item quantity"
526+
$quote->getItemsQty(),
527+
"Precondition failed: quote totals does not match."
519528
);
520529

521-
/** @var FormKey $formKey */
522-
$formKey = Bootstrap::getObjectManager()->get(FormKey::class);
530+
$response = $this->updatePostRequest($quote, $item1, $item2, $updatedQuantity, $updatedQuantity, true);
523531

524-
$request = [
525-
'form_key' => $formKey->getFormKey(),
526-
'cart' => [
527-
$item1->getId() => ['qty' => $updatedQuantity],
528-
$item2->getId() => ['qty' => $updatedQuantity]
529-
]
530-
];
532+
$this->assertContains(
533+
'[{"error":"There are no source items with the in stock status","itemId":'.$item1->getId().'}]',
534+
$response
535+
);
531536

532-
$this->getRequest()->setMethod(HttpRequest::METHOD_POST);
533-
$this->getRequest()->setPostValue($request);
534-
$this->dispatch('checkout/cart/updateItemQty');
535-
$response = $this->getResponse()->getBody();
536-
$response = json_decode($response, true);
537+
$response = $this->updatePostRequest($quote, $item1, $item2, $originalQuantity, $updatedQuantity, false);
538+
539+
$this->assertContains(
540+
'[{"error":"There are no source items with the in stock status","itemId":'.$item1->getId().'}]',
541+
$response
542+
);
543+
$this->assertEquals(
544+
$originalQuantity + $updatedQuantity,
545+
$quote->getItemsQty(),
546+
"Precondition failed: quote totals does not match."
547+
);
537548

538-
$this->assertContains('[{"error":"There are no source items with the in stock status","itemId":'.$item1->getId().'}]', $response);
549+
$response = $this->updatePostRequest($quote, $item1, $item2, $updatedQuantity, $updatedQuantity, false);
550+
551+
$this->assertContains(
552+
'[{"error":"There are no source items with the in stock status","itemId":'.$item1->getId().'}]',
553+
$response
554+
);
555+
$this->assertEquals(
556+
$originalQuantity + $updatedQuantity,
557+
$quote->getItemsQty(),
558+
"Precondition failed: quote totals does not match."
559+
);
560+
}
561+
562+
/**
563+
* @param CartInterface $quote
564+
* @param CartItemInterface $item1
565+
* @param CartItemInterface $item2
566+
* @param float $qty1
567+
* @param float $qty2
568+
* @param bool $updateQty
569+
* @return mixed
570+
* @throws LocalizedException
571+
*/
572+
private function updatePostRequest(
573+
CartInterface $quote,
574+
CartItemInterface $item1,
575+
CartItemInterface $item2,
576+
float $qty1,
577+
float $qty2,
578+
bool $updateQty = true
579+
): array {
580+
/** @var FormKey $formKey */
581+
$formKey = Bootstrap::getObjectManager()->get(FormKey::class);
539582

540583
$request = [
541584
'cart' => [
542-
$item1->getId() => ['qty' => $originalQuantity],
543-
$item2->getId() => ['qty' => $updatedQuantity]
585+
$item1->getId() => ['qty' => $qty1],
586+
$item2->getId() => ['qty' => $qty2]
544587
],
545588
'update_cart_action' => 'update_qty',
546589
'form_key' => $formKey->getFormKey(),
547590
];
548591
$this->getRequest()->setMethod(HttpRequest::METHOD_POST);
549592
$this->getRequest()->setPostValue($request);
550-
$this->dispatch('checkout/cart/updatePost');
593+
if ($updateQty) {
594+
$this->dispatch('checkout/cart/updateItemQty');
595+
} else {
596+
$this->dispatch('checkout/cart/updatePost');
597+
}
551598
$response = $this->getResponse()->getBody();
552599
$response = json_decode($response, true);
553-
554-
$this->assertContains('[{"error":"There are no source items with the in stock status","itemId":'.$item1->getId().'}]', $response);
555-
556600
$quote->collectTotals();
557-
558-
$this->assertEquals(
559-
$quote->getItemsQty(),
560-
$originalQuantity + $updatedQuantity,
561-
"Precondition failed: invalid quote item quantity"
562-
);
601+
return $response;
563602
}
564603
}

0 commit comments

Comments
 (0)