From f24eccc5f618f389aa68dce491895021a728ebe7 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Thu, 11 Mar 2021 13:43:28 +0200 Subject: [PATCH 1/5] MC-41122: Inventory reservation compensation does not handle partial shippements --- ...tOrderItemsDataForOrdersInNotFinalState.php | 10 +++++++++- .../AddExpectedReservations.php | 18 +++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/InventoryReservationCli/Model/ResourceModel/GetOrderItemsDataForOrdersInNotFinalState.php b/InventoryReservationCli/Model/ResourceModel/GetOrderItemsDataForOrdersInNotFinalState.php index 000d296a366b..4605c1f4e7be 100644 --- a/InventoryReservationCli/Model/ResourceModel/GetOrderItemsDataForOrdersInNotFinalState.php +++ b/InventoryReservationCli/Model/ResourceModel/GetOrderItemsDataForOrdersInNotFinalState.php @@ -85,7 +85,15 @@ public function execute(int $bunchSize = 50, int $page = 1): array ->join( ['item' => $orderItemTableName], 'item.order_id = main_table.entity_id', - ['item.sku', 'item.qty_ordered'] + [ + 'item.sku', + 'item.is_virtual', + 'item.qty_ordered', + 'item.qty_canceled', + 'item.qty_invoiced', + 'item.qty_refunded', + 'item.qty_shipped' + ] ) ->where('main_table.entity_id IN (?)', $entityIds) ->where('item.product_type IN (?)', $this->allowedProductTypesForSourceItemManagement->execute()); diff --git a/InventoryReservationCli/Model/SalableQuantityInconsistency/AddExpectedReservations.php b/InventoryReservationCli/Model/SalableQuantityInconsistency/AddExpectedReservations.php index 88e999c5d005..2d0f25c77f2a 100644 --- a/InventoryReservationCli/Model/SalableQuantityInconsistency/AddExpectedReservations.php +++ b/InventoryReservationCli/Model/SalableQuantityInconsistency/AddExpectedReservations.php @@ -72,7 +72,7 @@ public function execute(Collector $collector, int $bunchSize = 50, int $page = 1 $reservation = $this->reservationBuilder ->setSku($data['sku']) - ->setQuantity((float)$data['qty_ordered']) + ->setQuantity($this->calculateReservationQty($data)) ->setStockId($stockId) ->setMetadata($this->serializer->serialize( [ @@ -86,4 +86,20 @@ public function execute(Collector $collector, int $bunchSize = 50, int $page = 1 $collector->addOrderData($data); } } + + /** + * Return reservation qty amount + * + * @param array $data + * @return float + */ + private function calculateReservationQty(array $data): float + { + $qty = $data['qty_ordered']; + $qty -= $data['qty_canceled']; + $qty -= $data['qty_refunded']; + $qty -= $data['is_virtual'] ? $data['qty_invoiced'] : $data['qty_shipped']; + + return (float)$qty; + } } From c0dc88f1b96ace6bd06c9b51408a4909ba409354 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Fri, 12 Mar 2021 15:24:09 +0200 Subject: [PATCH 2/5] MC-41122: Inventory reservation compensation does not handle partial shippements --- .../GetSalableQuantityInconsistenciesTest.php | 13 +++++++ .../_files/create_partially_shipped_order.php | 38 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 InventoryReservationCli/Test/Integration/_files/create_partially_shipped_order.php diff --git a/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php b/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php index d7593533a4d7..5d2ce23c7934 100644 --- a/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php +++ b/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php @@ -100,6 +100,19 @@ public function testCompletedOrderWithMissingReservations(): void self::assertCount(1, $inconsistencies); } + /** + * Verify inventory:reservations:list-inconsistencies will return correct items qty for a partially shipped order. + * + * @magentoDataFixture Magento_InventoryReservationCli::Test/Integration/_files/create_partially_shipped_order.php + * @magentoDataFixture Magento_InventoryReservationCli::Test/Integration/_files/delete_reservations.php + * @throws \Magento\Framework\Validation\ValidationException + */ + public function testPartiallyShippedOrderWithMissingReservations(): void + { + $inconsistencies = $this->getSalableQuantityInconsistencies(); + self::assertCount(1, $inconsistencies); + } + /** * Verify inventory:reservations:list-inconsistencies will return correct qty for configurable product. * diff --git a/InventoryReservationCli/Test/Integration/_files/create_partially_shipped_order.php b/InventoryReservationCli/Test/Integration/_files/create_partially_shipped_order.php new file mode 100644 index 000000000000..0adc83285b32 --- /dev/null +++ b/InventoryReservationCli/Test/Integration/_files/create_partially_shipped_order.php @@ -0,0 +1,38 @@ +requireDataFixture('Magento/Sales/_files/order.php'); + +$objectManager = Bootstrap::getObjectManager(); +/** @var Order $order */ +$order = Bootstrap::getObjectManager() + ->create(Order::class); +$order->loadByIncrementId('100000001'); + +$order->setData( + 'is_virtual', + 0 +)->save(); + +$orderItems = $order->getItems(); +/** @var OrderItemInterface $orderItem */ +$orderItem = array_values($orderItems)[0]; + +/** @var ShipmentItemCreationInterface $shipmentItem */ +$shipmentItem = $objectManager->create(ShipmentItemCreationInterface::class); +$shipmentItem->setOrderItemId($orderItem->getItemId()); +$shipmentItem->setQty($orderItem->getQtyOrdered()/2); +/** @var ShipOrderInterface $shipOrder */ +$shipOrder = $objectManager->create(ShipOrderInterface::class); +$shipOrder->execute($order->getEntityId(), [$shipmentItem]); From 430b4642c8b7bec9c27d0970a7b317d2d412aed5 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Fri, 12 Mar 2021 17:50:40 +0200 Subject: [PATCH 3/5] MC-41122: Inventory reservation compensation does not handle partial shippements --- .../Integration/Model/GetSalableQuantityInconsistenciesTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php b/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php index 5d2ce23c7934..d2376315c955 100644 --- a/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php +++ b/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php @@ -104,7 +104,6 @@ public function testCompletedOrderWithMissingReservations(): void * Verify inventory:reservations:list-inconsistencies will return correct items qty for a partially shipped order. * * @magentoDataFixture Magento_InventoryReservationCli::Test/Integration/_files/create_partially_shipped_order.php - * @magentoDataFixture Magento_InventoryReservationCli::Test/Integration/_files/delete_reservations.php * @throws \Magento\Framework\Validation\ValidationException */ public function testPartiallyShippedOrderWithMissingReservations(): void From 32dafcc25294779527b3abba92a1dc38d2323cd1 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Fri, 12 Mar 2021 21:02:16 +0200 Subject: [PATCH 4/5] MC-41122: Inventory reservation compensation does not handle partial shippements --- .../GetSalableQuantityInconsistenciesTest.php | 8 ++- .../_files/create_partially_shipped_order.php | 49 ++++++++++--------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php b/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php index d2376315c955..7c975976e511 100644 --- a/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php +++ b/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php @@ -101,15 +101,19 @@ public function testCompletedOrderWithMissingReservations(): void } /** - * Verify inventory:reservations:list-inconsistencies will return correct items qty for a partially shipped order. + * Verify inventory:reservations:list-inconsistencies will return correct items qty for a partially shipped order * * @magentoDataFixture Magento_InventoryReservationCli::Test/Integration/_files/create_partially_shipped_order.php + * @magentoDataFixture Magento_InventoryReservationCli::Test/Integration/_files/delete_reservations.php + * @magentoDbIsolation disabled * @throws \Magento\Framework\Validation\ValidationException */ public function testPartiallyShippedOrderWithMissingReservations(): void { $inconsistencies = $this->getSalableQuantityInconsistencies(); - self::assertCount(1, $inconsistencies); + $items = reset($inconsistencies) + ->getItems(); + self::assertEquals(1, $items['simple']); } /** diff --git a/InventoryReservationCli/Test/Integration/_files/create_partially_shipped_order.php b/InventoryReservationCli/Test/Integration/_files/create_partially_shipped_order.php index 0adc83285b32..a38268e7531f 100644 --- a/InventoryReservationCli/Test/Integration/_files/create_partially_shipped_order.php +++ b/InventoryReservationCli/Test/Integration/_files/create_partially_shipped_order.php @@ -3,11 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); -use Magento\Sales\Api\Data\OrderItemInterface; -use Magento\Sales\Api\Data\ShipmentItemCreationInterface; -use Magento\Sales\Api\ShipOrderInterface; +use Magento\Framework\DB\Transaction; +use Magento\Sales\Api\OrderManagementInterface; use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\ShipmentFactory; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; @@ -15,24 +16,26 @@ ->requireDataFixture('Magento/Sales/_files/order.php'); $objectManager = Bootstrap::getObjectManager(); + /** @var Order $order */ -$order = Bootstrap::getObjectManager() - ->create(Order::class); -$order->loadByIncrementId('100000001'); - -$order->setData( - 'is_virtual', - 0 -)->save(); - -$orderItems = $order->getItems(); -/** @var OrderItemInterface $orderItem */ -$orderItem = array_values($orderItems)[0]; - -/** @var ShipmentItemCreationInterface $shipmentItem */ -$shipmentItem = $objectManager->create(ShipmentItemCreationInterface::class); -$shipmentItem->setOrderItemId($orderItem->getItemId()); -$shipmentItem->setQty($orderItem->getQtyOrdered()/2); -/** @var ShipOrderInterface $shipOrder */ -$shipOrder = $objectManager->create(ShipOrderInterface::class); -$shipOrder->execute($order->getEntityId(), [$shipmentItem]); +$order = $objectManager->create(Order::class) + ->loadByIncrementId('100000001'); + +/** @var OrderManagementInterface $orderManagement */ +$orderManagement = $objectManager->create(OrderManagementInterface::class); +$orderManagement->place($order); + +/** @var Transaction $transaction */ +$transaction = $objectManager->create(Transaction::class); + +$items = []; +foreach ($order->getItems() as $orderItem) { + $items[$orderItem->getId()] = $orderItem->getQtyOrdered()/2; +} +$shipment = $objectManager->get(ShipmentFactory::class) + ->create($order, $items); +$shipment->register(); + +$transaction->addObject($shipment) + ->addObject($order) + ->save(); From 4921344cf925ff60246a6ef4e8c61830aadda464 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Mon, 15 Mar 2021 17:38:07 +0200 Subject: [PATCH 5/5] MC-41122: Inventory reservation compensation does not handle partial shippements --- .../GetSalableQuantityInconsistenciesTest.php | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php b/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php index 7c975976e511..f894efdccd6b 100644 --- a/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php +++ b/InventoryReservationCli/Test/Integration/Model/GetSalableQuantityInconsistenciesTest.php @@ -100,22 +100,6 @@ public function testCompletedOrderWithMissingReservations(): void self::assertCount(1, $inconsistencies); } - /** - * Verify inventory:reservations:list-inconsistencies will return correct items qty for a partially shipped order - * - * @magentoDataFixture Magento_InventoryReservationCli::Test/Integration/_files/create_partially_shipped_order.php - * @magentoDataFixture Magento_InventoryReservationCli::Test/Integration/_files/delete_reservations.php - * @magentoDbIsolation disabled - * @throws \Magento\Framework\Validation\ValidationException - */ - public function testPartiallyShippedOrderWithMissingReservations(): void - { - $inconsistencies = $this->getSalableQuantityInconsistencies(); - $items = reset($inconsistencies) - ->getItems(); - self::assertEquals(1, $items['simple']); - } - /** * Verify inventory:reservations:list-inconsistencies will return correct qty for configurable product. * @@ -168,6 +152,22 @@ public function testExecuteEmptyWithPagination() } } + /** + * Verify inventory:reservations:list-inconsistencies will return correct items qty for a partially shipped order + * + * @magentoDataFixture Magento_InventoryReservationCli::Test/Integration/_files/create_partially_shipped_order.php + * @magentoDataFixture Magento_InventoryReservationCli::Test/Integration/_files/delete_reservations.php + * @magentoDbIsolation disabled + * @throws \Magento\Framework\Validation\ValidationException + */ + public function testPartiallyShippedOrderWithMissingReservations(): void + { + $inconsistencies = $this->getSalableQuantityInconsistencies(); + $items = reset($inconsistencies) + ->getItems(); + self::assertEquals(1, $items['simple']); + } + /** * Load current Inconsistencies *