Question

I have created order shipment programmatically with below code but I don't know how to select SourceCode when multiple sources available in Magento backend.

public function execute()
    {
        $orderId = $this->getRequest()->getParam('order_id');
        $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);

        // Check if order can be shipped or has already shipped
        if (!$order->canShip()) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('You can\'t create an shipment.')
            );
        }

        // Initialize the order shipment object
        $convertOrder = $this->_objectManager->create('Magento\Sales\Model\Convert\Order');
        $shipment = $convertOrder->toShipment($order);

        // Loop through order items
        foreach ($order->getAllItems() AS $orderItem) {
            // Check if order item has qty to ship or is virtual
            if (! $orderItem->getQtyToShip() || $orderItem->getIsVirtual()) {
                continue;
            }

            $qtyShipped = $orderItem->getQtyToShip();

            // Create shipment item with qty
            $shipmentItem = $convertOrder->itemToShipmentItem($orderItem)->setQty($qtyShipped);

            // Add shipment item to shipment
            $shipment->addItem($shipmentItem);
        }

        // Register shipment
        $shipment->register();

        $shipment->getOrder()->setIsInProcess(true);

        try {
            // Save created shipment and order
            $shipment->getExtensionAttributes()->setSourceCode('default');
            $shipment->save();

            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
            $order->setState('processing')
                ->setStatus('processing')
                ->save();

            // Send email
            //$this->_objectManager->create('Magento\Shipping\Model\ShipmentNotifier')->notify($shipment);
            //$shipment->save();

            $this->messageManager->addSuccess(__('Shipment has been created successfully.'));

            $pathParams = ['order_id' => $orderId];
            $path = 'sales/order/view';

            return $this->resultRedirectFactory->create()->setPath($path, $pathParams);
        } catch (\Exception $e) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __($e->getMessage())
            );
        }
    }

Here, I have put static code to select Source Code $shipment->getExtensionAttributes()->setSourceCode('default'); and its working fine.

I want to make it dynamic as per order.

How to get source code from order?

Était-ce utile?

La solution

This depends on your seller's logic for fairly simple logic where only 1 source is assigned to each website and no fallback is required

     try {
            $orderShipment->getExtensionAttributes()
                ->setSourceCode(
                    array_reduce(
                    /* @var \Magento\Inventory\Model\Source\Command\GetSourcesAssignedToStockOrderedByPriority*/
                        $this->sourceCommand->execute(
                            /* @var \Magento\InventorySales\Model\StockResolver */
                            $this->stockResolver
                                ->execute(
                                    'website',
                                    $order->getStore()
                                        ->getWebsite()
                                        ->getCode()
                                )
                                ->getStockId()
                        ),
                        function ($sourceCode, $source) {
                            return $sourceCode ?: $source->getSourceCode();
                        },
                        false
                    )
                );
        } catch (Exception $e) {
            //no source or stock assigned to website;
        }
Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top