itemRequestFactory = $itemRequestFactory; $this->getDefaultSourceSelectionAlgorithmCode = $getDefaultSourceSelectionAlgorithmCode; $this->sourceSelectionService = $sourceSelectionService; $this->getSkuFromOrderItem = $getSkuFromOrderItem; $this->getInventoryRequestFromOrder = $getInventoryRequestFromOrder ?: ObjectManager::getInstance()->get(GetInventoryRequestFromOrder::class); } /** * Get source selection result from invoice * * @param InvoiceInterface $invoice * @return SourceSelectionResultInterface */ public function execute(InvoiceInterface $invoice): SourceSelectionResultInterface { /** @var OrderInterface $order */ $order = $invoice->getOrder(); $inventoryRequest = $this->getInventoryRequestFromOrder->execute( (int) $order->getEntityId(), $this->getSelectionRequestItems($invoice->getItems()) ); $selectionAlgorithmCode = $this->getDefaultSourceSelectionAlgorithmCode->execute(); return $this->sourceSelectionService->execute($inventoryRequest, $selectionAlgorithmCode); } /** * Get selection request items * * @param InvoiceItemInterface[]|Traversable $invoiceItems * @return array */ private function getSelectionRequestItems(iterable $invoiceItems): array { $selectionRequestItems = []; foreach ($invoiceItems as $invoiceItem) { $orderItem = $invoiceItem->getOrderItem(); if ($orderItem->isDummy() || !$orderItem->getIsVirtual()) { continue; } $itemSku = $this->getSkuFromOrderItem->execute($orderItem); $qty = $this->castQty($invoiceItem->getOrderItem(), $invoiceItem->getQty()); $selectionRequestItems[] = $this->itemRequestFactory->create([ 'sku' => $itemSku, 'qty' => $qty, ]); } return $selectionRequestItems; } /** * Cast qty value * * @param OrderItemInterface $item * @param string|int|float $qty * @return float */ private function castQty(OrderItemInterface $item, $qty): float { if ($item->getIsQtyDecimal()) { $qty = (float) $qty; } else { $qty = (int) $qty; } return $qty > 0 ? $qty : 0; } }