Skip to content

Commit 1a41fe5

Browse files
authored
Merge pull request #289 from magento-performance/ACPT-745
[Performance] Async Order Stock Reservation
2 parents f32b8f5 + 48c75bc commit 1a41fe5

20 files changed

+1132
-97
lines changed
+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\InventorySales\Model;
9+
10+
use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;
11+
use Magento\InventorySalesApi\Api\Data\SalesChannelInterfaceFactory;
12+
use Magento\InventorySalesApi\Api\Data\SalesEventExtensionFactory;
13+
use Magento\InventorySalesApi\Api\Data\SalesEventInterface;
14+
use Magento\InventorySalesApi\Api\Data\SalesEventInterfaceFactory;
15+
use Magento\InventorySalesApi\Api\PlaceReservationsForSalesEventInterface;
16+
use Magento\InventorySalesApi\Model\StockByWebsiteIdResolverInterface;
17+
use Magento\Store\Api\WebsiteRepositoryInterface;
18+
19+
/**
20+
* Append Reservation after Order is placed
21+
*/
22+
class AppendReservations
23+
{
24+
/**
25+
* @var PlaceReservationsForSalesEventInterface
26+
*/
27+
private $placeReservationsForSalesEvent;
28+
29+
/**
30+
* @var WebsiteRepositoryInterface
31+
*/
32+
private $websiteRepository;
33+
34+
/**
35+
* @var SalesChannelInterfaceFactory
36+
*/
37+
private $salesChannelFactory;
38+
39+
/**
40+
* @var SalesEventInterfaceFactory
41+
*/
42+
private $salesEventFactory;
43+
44+
/**
45+
* @var CheckItemsQuantity
46+
*/
47+
private $checkItemsQuantity;
48+
49+
/**
50+
* @var StockByWebsiteIdResolverInterface
51+
*/
52+
private $stockByWebsiteIdResolver;
53+
54+
/**
55+
* @var SalesEventExtensionFactory;
56+
*/
57+
private $salesEventExtensionFactory;
58+
59+
/**
60+
* @param PlaceReservationsForSalesEventInterface $placeReservationsForSalesEvent
61+
* @param WebsiteRepositoryInterface $websiteRepository
62+
* @param SalesChannelInterfaceFactory $salesChannelFactory
63+
* @param SalesEventInterfaceFactory $salesEventFactory
64+
* @param CheckItemsQuantity $checkItemsQuantity
65+
* @param StockByWebsiteIdResolverInterface $stockByWebsiteIdResolver
66+
* @param SalesEventExtensionFactory $salesEventExtensionFactory
67+
*/
68+
public function __construct(
69+
PlaceReservationsForSalesEventInterface $placeReservationsForSalesEvent,
70+
WebsiteRepositoryInterface $websiteRepository,
71+
SalesChannelInterfaceFactory $salesChannelFactory,
72+
SalesEventInterfaceFactory $salesEventFactory,
73+
CheckItemsQuantity $checkItemsQuantity,
74+
StockByWebsiteIdResolverInterface $stockByWebsiteIdResolver,
75+
SalesEventExtensionFactory $salesEventExtensionFactory
76+
) {
77+
$this->placeReservationsForSalesEvent = $placeReservationsForSalesEvent;
78+
$this->websiteRepository = $websiteRepository;
79+
$this->salesChannelFactory = $salesChannelFactory;
80+
$this->salesEventFactory = $salesEventFactory;
81+
$this->checkItemsQuantity = $checkItemsQuantity;
82+
$this->stockByWebsiteIdResolver = $stockByWebsiteIdResolver;
83+
$this->salesEventExtensionFactory = $salesEventExtensionFactory;
84+
}
85+
86+
/**
87+
* Create reservations upon a sale event.
88+
*
89+
* @param int $websiteId
90+
* @param array $itemsBySku
91+
* @param mixed $order
92+
* @param array $itemsToSell
93+
* @return array
94+
* @throws \Exception
95+
*/
96+
public function reserve($websiteId, $itemsBySku, $order, $itemsToSell)
97+
{
98+
$websiteCode = $this->websiteRepository->getById($websiteId)->getCode();
99+
$stockId = (int)$this->stockByWebsiteIdResolver->execute((int)$websiteId)->getStockId();
100+
101+
$this->checkItemsQuantity->execute($itemsBySku, $stockId);
102+
103+
/** @var SalesEventExtensionInterface */
104+
$salesEventExtension = $this->salesEventExtensionFactory->create([
105+
'data' => ['objectIncrementId' => (string)$order->getIncrementId()]
106+
]);
107+
108+
/** @var SalesEventInterface $salesEvent */
109+
$salesEvent = $this->salesEventFactory->create([
110+
'type' => SalesEventInterface::EVENT_ORDER_PLACED,
111+
'objectType' => SalesEventInterface::OBJECT_TYPE_ORDER,
112+
'objectId' => (string)$order->getEntityId()
113+
]);
114+
$salesEvent->setExtensionAttributes($salesEventExtension);
115+
$salesChannel = $this->salesChannelFactory->create([
116+
'data' => [
117+
'type' => SalesChannelInterface::TYPE_WEBSITE,
118+
'code' => $websiteCode
119+
]
120+
]);
121+
122+
$this->placeReservationsForSalesEvent->execute($itemsToSell, $salesChannel, $salesEvent);
123+
return [$salesChannel, $salesEventExtension];
124+
}
125+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\InventorySales\Model;
9+
10+
/**
11+
* Defer inventory reservation for synchronous orders.
12+
*/
13+
class ReservationExecution implements ReservationExecutionInterface
14+
{
15+
/**
16+
* Always defer placing inventory reservation.
17+
*
18+
* @return bool
19+
*/
20+
public function isDeferred(): bool
21+
{
22+
return true;
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\InventorySales\Model;
9+
10+
/**
11+
* Strategy interface to define if to defer placing inventory reservation or not.
12+
*/
13+
interface ReservationExecutionInterface
14+
{
15+
/**
16+
* Defer to place inventory reservation or not.
17+
*
18+
* @return bool
19+
*/
20+
public function isDeferred(): bool;
21+
}

0 commit comments

Comments
 (0)