Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
GetShippedItemsPerSourceByPriority.php
Go to the documentation of this file.
1 <?php
6 declare(strict_types=1);
7 
9 
14 use Magento\InventorySalesApi\Model\ReturnProcessor\Result\SourceDeductedOrderItemFactory;
16 use Magento\InventorySalesApi\Model\ReturnProcessor\Result\SourceDeductedOrderItemsResultFactory;
22 
24 {
28  private $getSourceCodeByShipmentId;
29 
33  private $stockByWebsiteIdResolver;
34 
38  private $getSourcesAssignedToStockOrderedByPriority;
39 
43  private $sourceDeductedOrderItemFactory;
44 
48  private $sourceDeductedOrderItemsResultFactory;
49 
53  private $getItemsToDeductFromShipment;
54 
63  public function __construct(
64  GetSourceCodeByShipmentId $getSourceCodeByShipmentId,
65  StockByWebsiteIdResolverInterface $stockByWebsiteIdResolver,
66  GetSourcesAssignedToStockOrderedByPriorityInterface $getSourcesAssignedToStockOrderedByPriority,
67  SourceDeductedOrderItemFactory $sourceDeductedOrderItemFactory,
68  SourceDeductedOrderItemsResultFactory $sourceDeductedOrderItemsResultFactory,
69  GetItemsToDeductFromShipment $getItemsToDeductFromShipment
70  ) {
71  $this->getSourceCodeByShipmentId = $getSourceCodeByShipmentId;
72  $this->stockByWebsiteIdResolver = $stockByWebsiteIdResolver;
73  $this->getSourcesAssignedToStockOrderedByPriority = $getSourcesAssignedToStockOrderedByPriority;
74  $this->sourceDeductedOrderItemFactory = $sourceDeductedOrderItemFactory;
75  $this->sourceDeductedOrderItemsResultFactory = $sourceDeductedOrderItemsResultFactory;
76  $this->getItemsToDeductFromShipment = $getItemsToDeductFromShipment;
77  }
78 
86  public function execute(OrderInterface $order, array $returnToStockItems): array
87  {
88  $sources = [];
90  foreach ($order->getShipmentsCollection() as $shipment) {
91  $sourceCode = $this->getSourceCodeByShipmentId->execute((int)$shipment->getId());
92  $shippedItems = $this->getItemsToDeductFromShipment->execute($shipment);
93  foreach ($shippedItems as $item) {
94  $sku = $item->getSku();
95  $sources[$sourceCode][$sku] = ($sources[$sourceCode][$sku] ?? 0) + $item->getQty();
96  }
97  }
98  $websiteId = $order->getStore()->getWebsiteId();
99 
100  // Sort items by source priority
101  $sources = $this->sortSourcesByPriority($sources, (int)$websiteId);
102 
103  // Group items by SKU
104  $sources = $this->groupItemsBySku($sources);
105 
106  return $this->getSourceDeductedItemsResult($sources);
107  }
108 
113  private function getSourceDeductedItemsResult(array $shippedItems): array
114  {
115  $result = [];
116  foreach ($shippedItems as $sourceCode => $items) {
117  $deductedItems = [];
118  foreach ($items as $sku => $qty) {
119  $deductedItems[] = $this->sourceDeductedOrderItemFactory->create([
120  'sku' => $sku,
121  'quantity' => $qty
122  ]);
123  }
124  $result[] = $this->sourceDeductedOrderItemsResultFactory->create([
125  'sourceCode' => $sourceCode,
126  'items' => $deductedItems
127  ]);
128  }
129 
130  return $result;
131  }
132 
139  private function groupItemsBySku(array $sources): array
140  {
141  $skuPerSource = $itemsGroupedBySku = [];
142  foreach ($sources as $sourceCode => $data) {
143  foreach ($data as $sku => $qty) {
144  if (empty($skuPerSource[$sku])) {
145  $itemsGroupedBySku[$sourceCode][$sku] = $qty;
146  $skuPerSource[$sku] = $sourceCode;
147  } else {
148  $existingSourceCode = $skuPerSource[$sku];
149  $itemsGroupedBySku[$existingSourceCode][$sku] += $qty;
150  }
151  }
152  }
153 
154  return $itemsGroupedBySku;
155  }
156 
164  private function sortSourcesByPriority(array $sources, int $websiteId): array
165  {
166  $sourcesByPriority = [];
167  try {
168  $stockId = (int)$this->stockByWebsiteIdResolver->execute($websiteId)->getStockId();
169  $assignedSourcesToStock = $this->getSourcesAssignedToStockOrderedByPriority->execute($stockId);
170  } catch (LocalizedException $e) {
171  $assignedSourcesToStock = [];
172  }
173 
174  foreach ($assignedSourcesToStock as $source) {
175  if (!empty($sources[$source->getSourceCode()])) {
176  $sourcesByPriority[$source->getSourceCode()] = $sources[$source->getSourceCode()];
177  unset($sources[$source->getSourceCode()]);
178  }
179  }
180 
181  foreach ($sources as $sourceCode => $data) {
182  $sourcesByPriority[$sourceCode] = $data;
183  }
184 
185  return $sourcesByPriority;
186  }
187 }
__construct(GetSourceCodeByShipmentId $getSourceCodeByShipmentId, StockByWebsiteIdResolverInterface $stockByWebsiteIdResolver, GetSourcesAssignedToStockOrderedByPriorityInterface $getSourcesAssignedToStockOrderedByPriority, SourceDeductedOrderItemFactory $sourceDeductedOrderItemFactory, SourceDeductedOrderItemsResultFactory $sourceDeductedOrderItemsResultFactory, GetItemsToDeductFromShipment $getItemsToDeductFromShipment)
$source
Definition: source.php:23
$order
Definition: order.php:55
$sourceCode
Definition: inventory.phtml:11
foreach($order->getItems() as $orderItem) $shipment
$items