Skip to content

Commit b7fb23c

Browse files
committed
ACP2E-2055: Duplicate orders with same Quote Id at same time with few time difference
1 parent 55d25c1 commit b7fb23c

File tree

4 files changed

+61
-12
lines changed

4 files changed

+61
-12
lines changed

app/code/Magento/Quote/Model/QuoteRepository.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,25 +177,70 @@ public function getForCustomer($customerId, array $sharedStoreIds = [])
177177
*/
178178
public function getActive($cartId, array $sharedStoreIds = [])
179179
{
180+
$this->validateCachedActiveQuote((int)$cartId);
180181
$quote = $this->get($cartId, $sharedStoreIds);
181182
if (!$quote->getIsActive()) {
182183
throw NoSuchEntityException::singleField('cartId', $cartId);
183184
}
184185
return $quote;
185186
}
186187

188+
/**
189+
* Validates if cached quote is still active.
190+
*
191+
* @param int $cartId
192+
* @return void
193+
* @throws NoSuchEntityException
194+
*/
195+
private function validateCachedActiveQuote(int $cartId): void
196+
{
197+
if (isset($this->quotesById[$cartId])) {
198+
$quote = $this->cartFactory->create();
199+
if (is_callable([$quote, 'setSharedStoreIds'])) {
200+
$quote->setSharedStoreIds(['*']);
201+
}
202+
$quote->loadActive($cartId);
203+
if (!$quote->getIsActive()) {
204+
throw NoSuchEntityException::singleField('cartId', $cartId);
205+
}
206+
}
207+
}
208+
187209
/**
188210
* @inheritdoc
189211
*/
190212
public function getActiveForCustomer($customerId, array $sharedStoreIds = [])
191213
{
214+
$this->validateCachedCustomerActiveQuote((int)$customerId);
192215
$quote = $this->getForCustomer($customerId, $sharedStoreIds);
193216
if (!$quote->getIsActive()) {
194217
throw NoSuchEntityException::singleField('customerId', $customerId);
195218
}
196219
return $quote;
197220
}
198221

222+
/**
223+
* Validates if cached customer quote is still active.
224+
*
225+
* @param int $customerId
226+
* @return void
227+
* @throws NoSuchEntityException
228+
*/
229+
private function validateCachedCustomerActiveQuote(int $customerId): void
230+
{
231+
if (isset($this->quotesByCustomerId[$customerId])) {
232+
$quoteId = $this->quotesByCustomerId[$customerId]->getId();
233+
$quote = $this->cartFactory->create();
234+
if (is_callable([$quote, 'setSharedStoreIds'])) {
235+
$quote->setSharedStoreIds(['*']);
236+
}
237+
$quote->loadActive($quoteId);
238+
if (!$quote->getIsActive()) {
239+
throw NoSuchEntityException::singleField('customerId', $customerId);
240+
}
241+
}
242+
}
243+
199244
/**
200245
* @inheritdoc
201246
*/

app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ protected function setUp(): void
117117
[
118118
'load',
119119
'loadByIdWithoutStore',
120+
'loadActive',
120121
'loadByCustomer',
121122
'getIsActive',
122123
'getId',
@@ -244,6 +245,7 @@ public function testGetForCustomerAfterGet(int $quoteId, int $customerQuoteId, b
244245
[
245246
'load',
246247
'loadByIdWithoutStore',
248+
'loadActive',
247249
'loadByCustomer',
248250
'getIsActive',
249251
'getId',
@@ -486,16 +488,21 @@ public function testGetActiveForCustomer()
486488
$cartId = 17;
487489
$customerId = 23;
488490

489-
$this->cartFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock);
490-
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock);
491+
$this->cartFactoryMock->method('create')->willReturn($this->quoteMock);
492+
$this->storeManagerMock->method('getStore')->willReturn($this->storeMock);
491493
$this->storeMock->expects($this->once())->method('getId')->willReturn(1);
492-
$this->quoteMock->expects($this->never())->method('setSharedStoreIds');
494+
$this->quoteMock->expects($this->once())->method('setSharedStoreIds');
493495
$this->quoteMock->expects($this->once())
494496
->method('loadByCustomer')
495497
->with($customerId)
496498
->willReturn($this->storeMock);
497-
$this->quoteMock->expects($this->exactly(2))->method('getId')->willReturn($cartId);
498-
$this->quoteMock->expects($this->exactly(2))->method('getIsActive')->willReturn(1);
499+
$this->quoteMock->expects($this->once())
500+
->method('loadActive')
501+
->with($cartId)
502+
->willReturn($this->storeMock);
503+
504+
$this->quoteMock->method('getId')->willReturn($cartId);
505+
$this->quoteMock->method('getIsActive')->willReturn(1);
499506

500507
$this->loadHandlerMock->expects($this->once())
501508
->method('load')

dev/tests/integration/testsuite/Magento/Checkout/Api/ShippingInformationManagementTest.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ class ShippingInformationManagementTest extends TestCase
2626
*/
2727
private $management;
2828

29-
/**
30-
* @var CartRepositoryInterface
31-
*/
32-
private $cartRepo;
33-
3429
/**
3530
* @var CustomerRepositoryInterface
3631
*/
@@ -48,7 +43,6 @@ protected function setUp(): void
4843
{
4944
$objectManager = Bootstrap::getObjectManager();
5045
$this->management = $objectManager->get(ShippingInformationManagementInterface::class);
51-
$this->cartRepo = $objectManager->get(CartRepositoryInterface::class);
5246
$this->customerRepo = $objectManager->get(CustomerRepositoryInterface::class);
5347
$this->shippingFactory = $objectManager->get(ShippingInformationInterfaceFactory::class);
5448
}
@@ -65,7 +59,8 @@ protected function setUp(): void
6559
*/
6660
public function testDifferentAddresses(bool $swapShipping): void
6761
{
68-
$cart = $this->cartRepo->getForCustomer(1);
62+
$cartRepository = Bootstrap::getObjectManager()->create(CartRepositoryInterface::class);
63+
$cart = $cartRepository->getForCustomer(1);
6964
$otherCustomer = $this->customerRepo->get('[email protected]');
7065
$otherAddresses = $otherCustomer->getAddresses();
7166
$otherAddress = array_pop($otherAddresses);

dev/tests/integration/testsuite/Magento/Checkout/Model/SessionTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ public function testGetQuoteNotInitializedCustomerSet(): void
141141
$this->checkoutSession->setCustomerData($customer);
142142
$quote = $this->checkoutSession->getQuote();
143143
$this->validateCustomerDataInQuote($quote);
144+
$this->quoteRepository->delete($quote);
144145
}
145146

146147
/**
@@ -158,6 +159,7 @@ public function testGetQuoteNotInitializedCustomerLoggedIn(): void
158159
$this->customerSession->setCustomerDataObject($customer);
159160
$quote = $this->checkoutSession->getQuote();
160161
$this->validateCustomerDataInQuote($quote);
162+
$this->quoteRepository->delete($quote);
161163
}
162164

163165
/**

0 commit comments

Comments
 (0)