Skip to content

Commit 1df163e

Browse files
committed
AC-15054: Product Add to Cart issue in Rest API
1 parent a933434 commit 1df163e

File tree

4 files changed

+341
-120
lines changed

4 files changed

+341
-120
lines changed

app/code/Magento/Quote/Plugin/UpdateCartId.php

Lines changed: 86 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
use Magento\Framework\Exception\LocalizedException;
1313
use Magento\Framework\Exception\NoSuchEntityException;
1414
use Magento\Framework\Webapi\Rest\Request as RestRequest;
15+
use Magento\Quote\Api\CartRepositoryInterface;
1516
use Magento\Quote\Api\Data\CartItemInterface;
1617
use Magento\Quote\Api\GuestCartItemRepositoryInterface;
1718
use Magento\Quote\Model\QuoteIdMaskFactory;
1819
use Magento\Store\Model\StoreManagerInterface;
1920

2021
/**
21-
* Update cart id from request param
22+
* Plugin to update cart ID from request and validate product website assignment
2223
*/
2324
class UpdateCartId
2425
{
@@ -27,42 +28,42 @@ class UpdateCartId
2728
* @param ProductRepositoryInterface $productRepository
2829
* @param StoreManagerInterface $storeManager
2930
* @param QuoteIdMaskFactory $quoteIdMaskFactory
31+
* @param CartRepositoryInterface $cartRepository
3032
*/
3133
public function __construct(
3234
private readonly RestRequest $request,
3335
private readonly ProductRepositoryInterface $productRepository,
34-
private readonly StoreManagerInterface $storeManager,
35-
private readonly QuoteIdMaskFactory $quoteIdMaskFactory
36+
private readonly StoreManagerInterface $storeManager,
37+
private readonly QuoteIdMaskFactory $quoteIdMaskFactory,
38+
private readonly CartRepositoryInterface $cartRepository
3639
) {
3740
}
3841

3942
/**
40-
* Update id from request if param cartId exist
43+
* Before saving a guest cart item, set quote ID from request and validate website assignment
4144
*
42-
* @param GuestCartItemRepositoryInterface $guestCartItemRepository
45+
* @param GuestCartItemRepositoryInterface $subject
4346
* @param CartItemInterface $cartItem
44-
* @return array
47+
* @return void
48+
* @throws LocalizedException
49+
*
4550
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
4651
*/
4752
public function beforeSave(
48-
GuestCartItemRepositoryInterface $guestCartItemRepository,
53+
GuestCartItemRepositoryInterface $subject,
4954
CartItemInterface $cartItem
50-
): array {
51-
$cartId = $this->request->getParam('cartId');
52-
53-
if ($cartId) {
55+
): void {
56+
if ($cartId = $this->request->getParam('cartId')) {
5457
$cartItem->setQuoteId($cartId);
5558
}
59+
5660
$this->validateProductWebsiteAssignment($cartItem);
57-
return [$cartItem];
5861
}
5962

6063
/**
61-
* Validate that product is assigned to the current website
64+
* Validate product's website assignment for guest cart item
6265
*
63-
* @param CartItemInterface $cartItem
6466
* @throws LocalizedException
65-
* @throws NoSuchEntityException
6667
*/
6768
private function validateProductWebsiteAssignment(CartItemInterface $cartItem): void
6869
{
@@ -71,29 +72,84 @@ private function validateProductWebsiteAssignment(CartItemInterface $cartItem):
7172
return;
7273
}
7374

74-
// Get current website ID from the masked cart ID
7575
$maskedQuoteId = $cartItem->getQuoteId();
7676
$quoteIdMask = $this->quoteIdMaskFactory->create()->load($maskedQuoteId, 'masked_id');
77+
$quoteId = $quoteIdMask->getQuoteId();
7778

78-
if (!$quoteIdMask->getQuoteId()) {
79+
if (!$quoteId) {
7980
return;
8081
}
81-
$currentWebsiteId = $this->storeManager->getStore()->getWebsiteId();
82-
try {
83-
$product = $this->productRepository->get($sku, false, null);
8482

85-
$productWebsiteIds = $product->getWebsiteIds();
83+
try {
84+
$quote = $this->cartRepository->get($quoteId);
85+
$storeId = $quote->getStoreId();
8686

87-
// Validate website assignment
88-
if (!is_array($productWebsiteIds) || !in_array($currentWebsiteId, $productWebsiteIds)) {
89-
throw new LocalizedException(
90-
__('Product that you are trying to add is not available.')
91-
);
87+
foreach ($quote->getAllItems() as $item) {
88+
if ($sku === $item->getSku()) {
89+
$this->validateWebsiteAssignment($item->getProductId(), $storeId);
90+
return;
91+
}
9292
}
93-
} catch (NoSuchEntityException $e) {
94-
throw new LocalizedException(
95-
__('Product that you are trying to add is not available.')
96-
);
93+
94+
// Product not in quote yet
95+
$this->validateWebsiteAssignmentBySku($sku, $storeId);
96+
97+
} catch (NoSuchEntityException) {
98+
throw new LocalizedException(__('Product that you are trying to add is not available.'));
99+
}
100+
}
101+
102+
/**
103+
* Validate by SKU for new items
104+
*
105+
* @param string $sku
106+
* @param int $storeId
107+
* @return void
108+
* @throws LocalizedException
109+
*/
110+
private function validateWebsiteAssignmentBySku(string $sku, int $storeId): void
111+
{
112+
try {
113+
$product = $this->productRepository->get($sku, false, $storeId);
114+
$this->checkProductInWebsite($product->getWebsiteIds(), $storeId);
115+
} catch (NoSuchEntityException) {
116+
throw new LocalizedException(__('Product that you are trying to add is not available.'));
117+
}
118+
}
119+
120+
/**
121+
* Validate by product ID for existing items
122+
*
123+
* @param int $productId
124+
* @param int $storeId
125+
* @return void
126+
* @throws LocalizedException
127+
*/
128+
private function validateWebsiteAssignment(int $productId, int $storeId): void
129+
{
130+
try {
131+
$product = $this->productRepository->getById($productId, false, $storeId);
132+
$this->checkProductInWebsite($product->getWebsiteIds(), $storeId);
133+
} catch (NoSuchEntityException) {
134+
throw new LocalizedException(__('Product that you are trying to add is not available.'));
135+
}
136+
}
137+
138+
/**
139+
* Validate by product ID for existing items
140+
*
141+
* @param array|null $websiteIds
142+
* @param int $storeId
143+
* @return void
144+
* @throws LocalizedException
145+
* @throws NoSuchEntityException
146+
*/
147+
private function checkProductInWebsite(?array $websiteIds, int $storeId): void
148+
{
149+
$websiteId = $this->storeManager->getStore($storeId)->getWebsiteId();
150+
151+
if (empty($websiteIds) || !in_array($websiteId, $websiteIds, true)) {
152+
throw new LocalizedException(__('Product that you are trying to add is not available.'));
97153
}
98154
}
99155
}

app/code/Magento/Quote/Plugin/Webapi/ValidateProductWebsiteAssignment.php

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,55 +37,85 @@ public function __construct(
3737
*
3838
* @param CartItemRepositoryInterface $subject
3939
* @param CartItemInterface $cartItem
40-
* @return array
40+
* @return void
4141
* @throws LocalizedException
42-
* @throws NoSuchEntityException
4342
*
4443
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
4544
*/
4645
public function beforeSave(
4746
CartItemRepositoryInterface $subject,
4847
CartItemInterface $cartItem
49-
): array {
50-
$this->validateProductWebsiteAssignment($cartItem);
51-
return [$cartItem];
48+
): void {
49+
$sku = $cartItem->getSku();
50+
if (!$sku) {
51+
return;
52+
}
53+
54+
try {
55+
$quote = $this->cartRepository->getActive($cartItem->getQuoteId());
56+
57+
foreach ($quote->getAllItems() as $item) {
58+
if ($sku === $item->getSku()) {
59+
$this->checkProductWebsiteAssignment($item->getProductId(), $item->getStoreId());
60+
return;
61+
}
62+
}
63+
64+
// Fallback: product not in quote items yet
65+
$this->checkProductWebsiteAssignmentBySku($sku, $quote->getStoreId());
66+
67+
} catch (NoSuchEntityException $e) {
68+
throw new LocalizedException(__('Product that you are trying to add is not available.'));
69+
}
5270
}
5371

5472
/**
55-
* Validate that product is assigned to the current website
73+
* Check product website assignment by SKU
5674
*
57-
* @param CartItemInterface $cartItem
75+
* @param string $sku
76+
* @param int $storeId
5877
* @throws LocalizedException
59-
* @throws NoSuchEntityException
6078
*/
61-
private function validateProductWebsiteAssignment(CartItemInterface $cartItem): void
79+
private function checkProductWebsiteAssignmentBySku(string $sku, int $storeId): void
6280
{
63-
$sku = $cartItem->getSku();
64-
if (!$sku) {
65-
return;
81+
try {
82+
$product = $this->productRepository->get($sku, false, $storeId);
83+
$this->validateWebsiteAssignment($product->getWebsiteIds(), $storeId);
84+
} catch (NoSuchEntityException $e) {
85+
throw new LocalizedException(__('Product that you are trying to add is not available.'));
6686
}
87+
}
6788

68-
// Get current website ID from the cart's store
69-
$quote = $this->cartRepository->get($cartItem->getQuoteId());
70-
$storeId = $quote->getStoreId();
71-
$currentWebsiteId = $this->storeManager->getStore($storeId)->getWebsiteId();
72-
89+
/**
90+
* Check product website assignment by product ID
91+
*
92+
* @param int $productId
93+
* @param int|null $storeId
94+
* @throws LocalizedException
95+
*/
96+
private function checkProductWebsiteAssignment($productId, $storeId): void
97+
{
7398
try {
74-
// Load product to check website assignment
75-
$product = $this->productRepository->get($sku, false, $storeId);
99+
$product = $this->productRepository->getById($productId, false, $storeId);
100+
$this->validateWebsiteAssignment($product->getWebsiteIds(), $storeId);
101+
} catch (NoSuchEntityException $e) {
102+
throw new LocalizedException(__('Product that you are trying to add is not available.'));
103+
}
104+
}
76105

77-
$productWebsiteIds = $product->getWebsiteIds();
106+
/**
107+
* Validate product website assignment
108+
*
109+
* @param array|null $websiteIds
110+
* @param int $storeId
111+
* @throws LocalizedException
112+
*/
113+
private function validateWebsiteAssignment(?array $websiteIds, int $storeId): void
114+
{
115+
$websiteId = $this->storeManager->getStore($storeId)->getWebsiteId();
78116

79-
// Validate website assignment
80-
if (!is_array($productWebsiteIds) || !in_array($currentWebsiteId, $productWebsiteIds)) {
81-
throw new LocalizedException(
82-
__('Product that you are trying to add is not available.')
83-
);
84-
}
85-
} catch (NoSuchEntityException $e) {
86-
throw new LocalizedException(
87-
__('Product that you are trying to add is not available.')
88-
);
117+
if (empty($websiteIds) || !in_array($websiteId, $websiteIds, true)) {
118+
throw new LocalizedException(__('Product that you are trying to add is not available.'));
89119
}
90120
}
91121
}

0 commit comments

Comments
 (0)