سؤال

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?

هل كانت مفيدة؟

المحلول

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;
        }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى magento.stackexchange
scroll top