GetItemsToCancelFromOrderItem.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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\InventorySales\Model;
  8. use Magento\InventorySalesApi\Api\Data\ItemToSellInterface;
  9. use Magento\Sales\Model\Order\Item as OrderItem;
  10. use Magento\InventorySalesApi\Model\GetSkuFromOrderItemInterface;
  11. use Magento\InventorySalesApi\Api\Data\ItemToSellInterfaceFactory;
  12. use Magento\Framework\Serialize\Serializer\Json;
  13. class GetItemsToCancelFromOrderItem
  14. {
  15. /**
  16. * @var GetSkuFromOrderItemInterface
  17. */
  18. private $getSkuFromOrderItem;
  19. /**
  20. * @var ItemToSellInterfaceFactory
  21. */
  22. private $itemsToSellFactory;
  23. /**
  24. * @var Json
  25. */
  26. private $jsonSerializer;
  27. /**
  28. * @param GetSkuFromOrderItemInterface $getSkuFromOrderItem
  29. * @param ItemToSellInterfaceFactory $itemsToSellFactory
  30. * @param Json $jsonSerializer
  31. */
  32. public function __construct(
  33. GetSkuFromOrderItemInterface $getSkuFromOrderItem,
  34. ItemToSellInterfaceFactory $itemsToSellFactory,
  35. Json $jsonSerializer
  36. ) {
  37. $this->getSkuFromOrderItem = $getSkuFromOrderItem;
  38. $this->itemsToSellFactory = $itemsToSellFactory;
  39. $this->jsonSerializer = $jsonSerializer;
  40. }
  41. /**
  42. * @param OrderItem $orderItem
  43. * @return ItemToSellInterface[]
  44. */
  45. public function execute(OrderItem $orderItem): array
  46. {
  47. $itemsToCancel = [];
  48. if ($orderItem->getHasChildren()) {
  49. if (!$orderItem->isDummy(true)) {
  50. foreach ($this->processComplexItem($orderItem) as $item) {
  51. $itemsToCancel[] = $item;
  52. }
  53. }
  54. } elseif (!$orderItem->isDummy(true)) {
  55. $itemSku = $this->getSkuFromOrderItem->execute($orderItem);
  56. $itemsToCancel[] = $this->itemsToSellFactory->create([
  57. 'sku' => $itemSku,
  58. 'qty' => $this->getQtyToCancel($orderItem)
  59. ]);
  60. }
  61. return $this->groupItemsBySku($itemsToCancel);
  62. }
  63. /**
  64. * @param ItemToSellInterface[] $itemsToCancel
  65. * @return ItemToSellInterface[]
  66. */
  67. private function groupItemsBySku(array $itemsToCancel): array
  68. {
  69. $processingItems = $groupedItems = [];
  70. foreach ($itemsToCancel as $item) {
  71. if ($item->getQuantity() == 0) {
  72. continue;
  73. }
  74. if (empty($processingItems[$item->getSku()])) {
  75. $processingItems[$item->getSku()] = $item->getQuantity();
  76. } else {
  77. $processingItems[$item->getSku()] += $item->getQuantity();
  78. }
  79. }
  80. foreach ($processingItems as $sku => $qty) {
  81. $groupedItems[] = $this->itemsToSellFactory->create([
  82. 'sku' => $sku,
  83. 'qty' => $qty
  84. ]);
  85. }
  86. return $groupedItems;
  87. }
  88. /**
  89. * @param OrderItem $orderItem
  90. * @return ItemToSellInterface[]
  91. */
  92. private function processComplexItem(OrderItem $orderItem): array
  93. {
  94. $itemsToCancel = [];
  95. foreach ($orderItem->getChildrenItems() as $item) {
  96. $productOptions = $item->getProductOptions();
  97. if (isset($productOptions['bundle_selection_attributes'])) {
  98. $bundleSelectionAttributes = $this->jsonSerializer->unserialize(
  99. $productOptions['bundle_selection_attributes']
  100. );
  101. if ($bundleSelectionAttributes) {
  102. $shippedQty = $bundleSelectionAttributes['qty'] * $orderItem->getQtyShipped();
  103. $qty = $item->getQtyOrdered() - max($shippedQty, $item->getQtyInvoiced()) - $item->getQtyCanceled();
  104. $itemSku = $this->getSkuFromOrderItem->execute($item);
  105. $itemsToCancel[] = $this->itemsToSellFactory->create([
  106. 'sku' => $itemSku,
  107. 'qty' => $qty
  108. ]);
  109. }
  110. } else {
  111. // configurable product
  112. $itemSku = $this->getSkuFromOrderItem->execute($orderItem);
  113. $itemsToCancel[] = $this->itemsToSellFactory->create([
  114. 'sku' => $itemSku,
  115. 'qty' => $this->getQtyToCancel($orderItem)
  116. ]);
  117. }
  118. }
  119. return $itemsToCancel;
  120. }
  121. /**
  122. * @param OrderItem $item
  123. * @return float
  124. */
  125. private function getQtyToCancel(OrderItem $item): float
  126. {
  127. return $item->getQtyOrdered() - max($item->getQtyShipped(), $item->getQtyInvoiced()) - $item->getQtyCanceled();
  128. }
  129. }