Inventory Reserveration order_placed
- Dominant language
- PHP
- Stars
- 357
- Forks
- 262
- PR merge metrics
- No merged PRs in 30d
Description
### Preconditions (*)
1. version 2.4.3 - 2.4.6
### Steps to reproduce (*)
1. Create any order.
### Expected result (*)
1. The object_id is populated in inventory_reservation.meta_key
2. {"event_type":"order_placed","object_type":"order","object_id":"14","object_increment_id":"000000022"}
3. I am currently on version 2.4.3 in my development but the object_id is missing on a 2.4.6. The idea is that populating this id would make the processing of the inventory reservations and cleaning up missing reservations much quicker. I also have a request the inventory reservation and testing quantity available is done in one transaction. I've attached the full log sql of creating test orders.
4. The above example was produced by moving the sale event to after the Proceed. $order = $proceed($order);
5. Here is my update to AppendReservationsAfterOrderPlacementPlugin:
\var\www\html\vendor\magento\module-inventory-sales\Plugin\Sales\OrderManagement\AppendReservationsAfterOrderPlacementPlugin.php
`public function aroundPlace(
OrderManagementInterface $subject,
callable $proceed,
OrderInterface $order
): OrderInterface {
$itemsById = $itemsBySku = $itemsToSell = [];
foreach ($order->getItems() as $item) {
if (!isset($itemsById[$item->getProductId()])) {
$itemsById[$item->getProductId()] = 0;
}
$itemsById[$item->getProductId()] += $item->getQtyOrdered();
}
$productSkus = $this->getSkusByProductIds->execute(array_keys($itemsById));
$productTypes = $this->getProductTypesBySkus->execute($productSkus);
foreach ($productSkus as $productId => $sku) {
if (false === $this->isSourceItemManagementAllowedForProductType->execute($productTypes[$sku])) {
continue;
}
$itemsBySku[$sku] = (float)$itemsById[$productId];
$itemsToSell[] = $this->itemsToSellFactory->create([
'sku' => $sku,
'qty' => -(float)$itemsById[$productId]
]);
}
$websiteId = (int)$order->getStore()->getWebsiteId();
$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()]
]);
try {
$order = $proceed($order);
/** @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);
} catch (\Exception $e) {
//add compensation
foreach ($itemsToSell as $item) {
$item->setQuantity(-(float)$item->getQuantity());
}
/** @var SalesEventInterface $salesEvent */
$salesEvent = $this->salesEventFactory->create([
'type' => SalesEventInterface::EVENT_ORDER_PLACE_FAILED,
'objectType' => SalesEventInterface::OBJECT_TYPE_ORDER,
'objectId' => (string)$order->getEntityId()
]);
$salesEvent->setExtensionAttributes($salesEventExtension);
$this->placeReservationsForSalesEvent->execute($itemsToSell, $salesChannel, $salesEvent);
throw $e;
}
return $order;
}`
### Actual result (*)
1. The object_id is empty on event_type +order_placed.
2. {"event_type":"order_placed","object_type":"order","object_id":"","object_increment_id":"000000022"}
[Magento 2 order placed.txt](https://github.com/magento/inventory/files/12074230/Magento.2.order.placed.txt)
Contributor guide
Research direction
Start with vendor/magento/module-inventory-sales/Plugin/Sales/OrderManagement/AppendReservationsAfterOrderPlacementPlugin.php and reproduce order placement on the listed Magento versions. Review the attached SQL log and reservation event data to trace why order_placed has an empty object_id. Done means the reservation records contain the expected order entity ID, with the transaction behavior clarified and covered by appropriate tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100