Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ProcessRefundItems.php
Go to the documentation of this file.
1 <?php
6 declare(strict_types=1);
7 
9 
10 use Magento\InventorySalesApi\Api\Data\ItemToSellInterfaceFactory;
12 use Magento\InventorySalesApi\Api\Data\SalesEventInterfaceFactory;
13 use Magento\InventorySalesApi\Api\Data\SalesChannelInterfaceFactory;
20 use Magento\InventorySourceDeductionApi\Model\ItemToDeductFactory;
21 use Magento\InventorySourceDeductionApi\Model\SourceDeductionRequestFactory;
23 
25 {
29  private $websiteRepository;
30 
34  private $salesChannelFactory;
35 
39  private $salesEventFactory;
40 
44  private $itemsToSellFactory;
45 
49  private $placeReservationsForSalesEvent;
50 
54  private $getSourceDeductedOrderItems;
55 
59  private $itemToDeductFactory;
60 
64  private $sourceDeductionRequestFactory;
65 
69  private $sourceDeductionService;
70 
82  public function __construct(
83  WebsiteRepositoryInterface $websiteRepository,
84  SalesChannelInterfaceFactory $salesChannelFactory,
85  SalesEventInterfaceFactory $salesEventFactory,
86  ItemToSellInterfaceFactory $itemsToSellFactory,
87  PlaceReservationsForSalesEventInterface $placeReservationsForSalesEvent,
88  GetSourceDeductedOrderItemsInterface $getSourceDeductedOrderItems,
89  ItemToDeductFactory $itemToDeductFactory,
90  SourceDeductionRequestFactory $sourceDeductionRequestFactory,
91  SourceDeductionService $sourceDeductionService
92  ) {
93  $this->websiteRepository = $websiteRepository;
94  $this->salesChannelFactory = $salesChannelFactory;
95  $this->salesEventFactory = $salesEventFactory;
96  $this->itemsToSellFactory = $itemsToSellFactory;
97  $this->placeReservationsForSalesEvent = $placeReservationsForSalesEvent;
98  $this->getSourceDeductedOrderItems = $getSourceDeductedOrderItems;
99  $this->itemToDeductFactory = $itemToDeductFactory;
100  $this->sourceDeductionRequestFactory = $sourceDeductionRequestFactory;
101  $this->sourceDeductionService = $sourceDeductionService;
102  }
103 
108  public function execute(
110  array $itemsToRefund,
111  array $returnToStockItems
112  ) {
113  $salesChannel = $this->getSalesChannelForOrder($order);
114  $deductedItems = $this->getSourceDeductedOrderItems->execute($order, $returnToStockItems);
115  $itemToSell = $backItemsPerSource = [];
116 
117  foreach ($itemsToRefund as $item) {
118  $sku = $item->getSku();
119 
120  $totalDeductedQty = $this->getTotalDeductedQty($item, $deductedItems);
121  $processedQty = $item->getProcessedQuantity() - $totalDeductedQty;
122  $qtyBackToSource = ($processedQty > 0) ? $item->getQuantity() - $processedQty : $item->getQuantity();
123  $qtyBackToStock = ($qtyBackToSource > 0) ? $item->getQuantity() - $qtyBackToSource : $item->getQuantity();
124 
125  if ($qtyBackToStock > 0) {
126  $itemToSell[] = $this->itemsToSellFactory->create([
127  'sku' => $sku,
128  'qty' => (float)$qtyBackToStock
129  ]);
130  }
131 
132  foreach ($deductedItems as $deductedItemResult) {
133  $sourceCode = $deductedItemResult->getSourceCode();
134  foreach ($deductedItemResult->getItems() as $deductedItem) {
135  if ($sku != $deductedItem->getSku() || $this->isZero((float)$qtyBackToSource)) {
136  continue;
137  }
138 
139  $backQty = min($deductedItem->getQuantity(), $qtyBackToSource);
140 
141  $backItemsPerSource[$sourceCode][] = $this->itemToDeductFactory->create([
142  'sku' => $deductedItem->getSku(),
143  'qty' => -$backQty
144  ]);
145  $qtyBackToSource -= $backQty;
146  }
147  }
148  }
149 
151  $salesEvent = $this->salesEventFactory->create([
154  'objectId' => (string)$order->getEntityId()
155  ]);
156 
157  foreach ($backItemsPerSource as $sourceCode => $items) {
158  $sourceDeductionRequest = $this->sourceDeductionRequestFactory->create([
159  'sourceCode' => $sourceCode,
160  'items' => $items,
161  'salesChannel' => $salesChannel,
162  'salesEvent' => $salesEvent
163  ]);
164  $this->sourceDeductionService->execute($sourceDeductionRequest);
165  }
166 
167  $this->placeReservationsForSalesEvent->execute($itemToSell, $salesChannel, $salesEvent);
168  }
169 
175  private function getTotalDeductedQty($item, array $deductedItems): float
176  {
177  $result = 0;
178 
179  foreach ($deductedItems as $deductedItemResult) {
180  foreach ($deductedItemResult->getItems() as $deductedItem) {
181  if ($item->getSku() != $deductedItem->getSku()) {
182  continue;
183  }
184  $result += $deductedItem->getQuantity();
185  }
186  }
187 
188  return $result;
189  }
190 
195  private function getSalesChannelForOrder(OrderInterface $order): SalesChannelInterface
196  {
197  $websiteId = (int)$order->getStore()->getWebsiteId();
198  $websiteCode = $this->websiteRepository->getById($websiteId)->getCode();
199 
200  return $this->salesChannelFactory->create([
201  'data' => [
203  'code' => $websiteCode
204  ]
205  ]);
206  }
207 
215  private function isZero(float $floatNumber): bool
216  {
217  return $floatNumber < 0.0000001;
218  }
219 }
$order
Definition: order.php:55
execute(OrderInterface $order, array $itemsToRefund, array $returnToStockItems)
__construct(WebsiteRepositoryInterface $websiteRepository, SalesChannelInterfaceFactory $salesChannelFactory, SalesEventInterfaceFactory $salesEventFactory, ItemToSellInterfaceFactory $itemsToSellFactory, PlaceReservationsForSalesEventInterface $placeReservationsForSalesEvent, GetSourceDeductedOrderItemsInterface $getSourceDeductedOrderItems, ItemToDeductFactory $itemToDeductFactory, SourceDeductionRequestFactory $sourceDeductionRequestFactory, SourceDeductionService $sourceDeductionService)
$sourceCode
Definition: inventory.phtml:11
if(!isset($_GET['website_code'])) $websiteCode
Definition: website.php:11
$items