GetItemsToDeductFromShipment.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\InventoryShipping\Model;
  8. use Magento\Sales\Model\Order\Shipment\Item;
  9. use Magento\Sales\Model\Order\Item as OrderItem;
  10. use Magento\Framework\Serialize\Serializer\Json;
  11. use Magento\InventorySalesApi\Model\GetSkuFromOrderItemInterface;
  12. use Magento\InventorySourceDeductionApi\Model\ItemToDeductInterface;
  13. use Magento\InventorySourceDeductionApi\Model\ItemToDeductInterfaceFactory;
  14. use Magento\Sales\Model\Order\Shipment;
  15. use Magento\Framework\Exception\NoSuchEntityException;
  16. class GetItemsToDeductFromShipment
  17. {
  18. /**
  19. * @var GetSkuFromOrderItemInterface
  20. */
  21. private $getSkuFromOrderItem;
  22. /**
  23. * @var Json
  24. */
  25. private $jsonSerializer;
  26. /**
  27. * @var ItemToDeductInterfaceFactory
  28. */
  29. private $itemToDeduct;
  30. /**
  31. * @param GetSkuFromOrderItemInterface $getSkuFromOrderItem
  32. * @param Json $jsonSerializer
  33. * @param ItemToDeductInterfaceFactory $itemToDeduct
  34. */
  35. public function __construct(
  36. GetSkuFromOrderItemInterface $getSkuFromOrderItem,
  37. Json $jsonSerializer,
  38. ItemToDeductInterfaceFactory $itemToDeduct
  39. ) {
  40. $this->jsonSerializer = $jsonSerializer;
  41. $this->itemToDeduct = $itemToDeduct;
  42. $this->getSkuFromOrderItem = $getSkuFromOrderItem;
  43. }
  44. /**
  45. * @param Shipment $shipment
  46. * @return ItemToDeductInterface[]
  47. * @throws NoSuchEntityException
  48. */
  49. public function execute(Shipment $shipment): array
  50. {
  51. $itemsToShip = [];
  52. /** @var \Magento\Sales\Model\Order\Shipment\Item $shipmentItem */
  53. foreach ($shipment->getAllItems() as $shipmentItem) {
  54. $orderItem = $shipmentItem->getOrderItem();
  55. // This code was added as quick fix for merge mainline
  56. // https://github.com/magento-engcom/msi/issues/1586
  57. if (null === $orderItem) {
  58. continue;
  59. }
  60. if ($orderItem->getHasChildren()) {
  61. if (!$orderItem->isDummy(true)) {
  62. foreach ($this->processComplexItem($shipmentItem) as $item) {
  63. $itemsToShip[] = $item;
  64. }
  65. }
  66. } else {
  67. $itemSku = $this->getSkuFromOrderItem->execute($orderItem);
  68. $qty = $this->castQty($orderItem, $shipmentItem->getQty());
  69. $itemsToShip[] = $this->itemToDeduct->create([
  70. 'sku' => $itemSku,
  71. 'qty' => $qty
  72. ]);
  73. }
  74. }
  75. return $this->groupItemsBySku($itemsToShip);
  76. }
  77. /**
  78. * @param array $shipmentItems
  79. * @return array
  80. */
  81. private function groupItemsBySku(array $shipmentItems): array
  82. {
  83. $processingItems = $groupedItems = [];
  84. foreach ($shipmentItems as $shipmentItem) {
  85. if (empty($processingItems[$shipmentItem->getSku()])) {
  86. $processingItems[$shipmentItem->getSku()] = $shipmentItem->getQty();
  87. } else {
  88. $processingItems[$shipmentItem->getSku()] += $shipmentItem->getQty();
  89. }
  90. }
  91. foreach ($processingItems as $sku => $qty) {
  92. $groupedItems[] = $this->itemToDeduct->create([
  93. 'sku' => $sku,
  94. 'qty' => $qty
  95. ]);
  96. }
  97. return $groupedItems;
  98. }
  99. /**
  100. * @param Item $shipmentItem
  101. * @return array
  102. */
  103. private function processComplexItem(Item $shipmentItem): array
  104. {
  105. $orderItem = $shipmentItem->getOrderItem();
  106. $itemsToShip = [];
  107. foreach ($orderItem->getChildrenItems() as $item) {
  108. if ($item->getIsVirtual() || $item->getLockedDoShip()) {
  109. continue;
  110. }
  111. $productOptions = $item->getProductOptions();
  112. if (isset($productOptions['bundle_selection_attributes'])) {
  113. $bundleSelectionAttributes = $this->jsonSerializer->unserialize(
  114. $productOptions['bundle_selection_attributes']
  115. );
  116. if ($bundleSelectionAttributes) {
  117. $qty = $bundleSelectionAttributes['qty'] * $shipmentItem->getQty();
  118. $qty = $this->castQty($item, $qty);
  119. $itemSku = $this->getSkuFromOrderItem->execute($item);
  120. $itemsToShip[] = $this->itemToDeduct->create([
  121. 'sku' => $itemSku,
  122. 'qty' => $qty
  123. ]);
  124. continue;
  125. }
  126. } else {
  127. // configurable product
  128. $itemSku = $this->getSkuFromOrderItem->execute($orderItem);
  129. $qty = $this->castQty($orderItem, $shipmentItem->getQty());
  130. $itemsToShip[] = $this->itemToDeduct->create([
  131. 'sku' => $itemSku,
  132. 'qty' => $qty
  133. ]);
  134. }
  135. }
  136. return $itemsToShip;
  137. }
  138. /**
  139. * @param OrderItem $item
  140. * @param string|int|float $qty
  141. * @return float|int
  142. */
  143. private function castQty(OrderItem $item, $qty)
  144. {
  145. if ($item->getIsQtyDecimal()) {
  146. $qty = (double)$qty;
  147. } else {
  148. $qty = (int)$qty;
  149. }
  150. return $qty > 0 ? $qty : 0;
  151. }
  152. }