Skip to content

Commit

Permalink
Merge pull request #289 from magento-performance/ACPT-745
Browse files Browse the repository at this point in the history
[Performance] Async Order Stock Reservation
  • Loading branch information
sidolov authored Dec 15, 2022
2 parents f32b8f5 + 48c75bc commit 1a41fe5
Show file tree
Hide file tree
Showing 20 changed files with 1,132 additions and 97 deletions.
125 changes: 125 additions & 0 deletions InventorySales/Model/AppendReservations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventorySales\Model;

use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;
use Magento\InventorySalesApi\Api\Data\SalesChannelInterfaceFactory;
use Magento\InventorySalesApi\Api\Data\SalesEventExtensionFactory;
use Magento\InventorySalesApi\Api\Data\SalesEventInterface;
use Magento\InventorySalesApi\Api\Data\SalesEventInterfaceFactory;
use Magento\InventorySalesApi\Api\PlaceReservationsForSalesEventInterface;
use Magento\InventorySalesApi\Model\StockByWebsiteIdResolverInterface;
use Magento\Store\Api\WebsiteRepositoryInterface;

/**
* Append Reservation after Order is placed
*/
class AppendReservations
{
/**
* @var PlaceReservationsForSalesEventInterface
*/
private $placeReservationsForSalesEvent;

/**
* @var WebsiteRepositoryInterface
*/
private $websiteRepository;

/**
* @var SalesChannelInterfaceFactory
*/
private $salesChannelFactory;

/**
* @var SalesEventInterfaceFactory
*/
private $salesEventFactory;

/**
* @var CheckItemsQuantity
*/
private $checkItemsQuantity;

/**
* @var StockByWebsiteIdResolverInterface
*/
private $stockByWebsiteIdResolver;

/**
* @var SalesEventExtensionFactory;
*/
private $salesEventExtensionFactory;

/**
* @param PlaceReservationsForSalesEventInterface $placeReservationsForSalesEvent
* @param WebsiteRepositoryInterface $websiteRepository
* @param SalesChannelInterfaceFactory $salesChannelFactory
* @param SalesEventInterfaceFactory $salesEventFactory
* @param CheckItemsQuantity $checkItemsQuantity
* @param StockByWebsiteIdResolverInterface $stockByWebsiteIdResolver
* @param SalesEventExtensionFactory $salesEventExtensionFactory
*/
public function __construct(
PlaceReservationsForSalesEventInterface $placeReservationsForSalesEvent,
WebsiteRepositoryInterface $websiteRepository,
SalesChannelInterfaceFactory $salesChannelFactory,
SalesEventInterfaceFactory $salesEventFactory,
CheckItemsQuantity $checkItemsQuantity,
StockByWebsiteIdResolverInterface $stockByWebsiteIdResolver,
SalesEventExtensionFactory $salesEventExtensionFactory
) {
$this->placeReservationsForSalesEvent = $placeReservationsForSalesEvent;
$this->websiteRepository = $websiteRepository;
$this->salesChannelFactory = $salesChannelFactory;
$this->salesEventFactory = $salesEventFactory;
$this->checkItemsQuantity = $checkItemsQuantity;
$this->stockByWebsiteIdResolver = $stockByWebsiteIdResolver;
$this->salesEventExtensionFactory = $salesEventExtensionFactory;
}

/**
* Create reservations upon a sale event.
*
* @param int $websiteId
* @param array $itemsBySku
* @param mixed $order
* @param array $itemsToSell
* @return array
* @throws \Exception
*/
public function reserve($websiteId, $itemsBySku, $order, $itemsToSell)
{
$websiteCode = $this->websiteRepository->getById($websiteId)->getCode();
$stockId = (int)$this->stockByWebsiteIdResolver->execute((int)$websiteId)->getStockId();

$this->checkItemsQuantity->execute($itemsBySku, $stockId);

/** @var SalesEventExtensionInterface */
$salesEventExtension = $this->salesEventExtensionFactory->create([
'data' => ['objectIncrementId' => (string)$order->getIncrementId()]
]);

/** @var SalesEventInterface $salesEvent */
$salesEvent = $this->salesEventFactory->create([
'type' => SalesEventInterface::EVENT_ORDER_PLACED,
'objectType' => SalesEventInterface::OBJECT_TYPE_ORDER,
'objectId' => (string)$order->getEntityId()
]);
$salesEvent->setExtensionAttributes($salesEventExtension);
$salesChannel = $this->salesChannelFactory->create([
'data' => [
'type' => SalesChannelInterface::TYPE_WEBSITE,
'code' => $websiteCode
]
]);

$this->placeReservationsForSalesEvent->execute($itemsToSell, $salesChannel, $salesEvent);
return [$salesChannel, $salesEventExtension];
}
}
24 changes: 24 additions & 0 deletions InventorySales/Model/ReservationExecution.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventorySales\Model;

/**
* Defer inventory reservation for synchronous orders.
*/
class ReservationExecution implements ReservationExecutionInterface
{
/**
* Always defer placing inventory reservation.
*
* @return bool
*/
public function isDeferred(): bool
{
return true;
}
}
21 changes: 21 additions & 0 deletions InventorySales/Model/ReservationExecutionInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventorySales\Model;

/**
* Strategy interface to define if to defer placing inventory reservation or not.
*/
interface ReservationExecutionInterface
{
/**
* Defer to place inventory reservation or not.
*
* @return bool
*/
public function isDeferred(): bool;
}
Loading

0 comments on commit 1a41fe5

Please sign in to comment.