Question

I'm currently working in the Magento 2.3.1 MSI. When I viewed in the product view page in the admin panel there is a quantity per source column with displaying quantities per source. Can I add this same feature into the sales order view page as well? If anyone knows please help me. Thanks in advance. You can take as reference to below image to view the product view page. enter image description here

Was it helpful?

Solution

Step1: Create column for sales order items app/code/Vendor/Test/view/adminhtml/layout/sales_order_view.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="order_items">
            <arguments>
                <argument name="columns" xsi:type="array">
                    <item name="qty_source" xsi:type="string" translate="true">Quantity per Source</item>
                </argument>
            </arguments>
            <referenceBlock name="default_order_items_renderer">
                <arguments>
                    <argument name="columns" xsi:type="array">
                        <item name="qty_source" xsi:type="string" translate="true">col-qtysource</item>
                    </argument>
                </arguments>
            </referenceBlock>

            <block class="Vendor\Test\Block\Adminhtml\QtySourceColumn"
                   name="column_qty_source"
                   template="Vendor_Test::qty_source.phtml" group="column" />
        </referenceBlock>
    </body>
</page>

Step2: Create adminblock to provide qty source with below code: app/code/Vendor/Test/Block/Adminhtml/QtySourceColumn.php

<?php

namespace Vendor\Test\Block\Adminhtml;

use Magento\InventoryCatalogApi\Model\IsSingleSourceModeInterface;
use Magento\InventoryApi\Api\SourceRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\InventoryApi\Api\SourceItemRepositoryInterface;
use Magento\InventoryApi\Api\Data\SourceItemInterface;
use Magento\InventoryApi\Api\Data\SourceInterface;

class QtySourceColumn extends \Magento\Sales\Block\Adminhtml\Items\Column\DefaultColumn
{

        /**
     * @var IsSingleSourceModeInterface
     */
    private $isSingleSourceMode;

    /**
     * @var SourceRepositoryInterface
     */
    private $sourceRepository;

    /**
     * @var SearchCriteriaBuilder
     */
    private $searchCriteriaBuilder;

    /**
     * @var SourceItemRepositoryInterface
     */
    private $sourceItemRepository;

    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
        \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration,
        \Magento\Framework\Registry $registry,
        \Magento\Catalog\Model\Product\OptionFactory $optionFactory,
        IsSingleSourceModeInterface $isSingleSourceMode,
        SourceRepositoryInterface $sourceRepository,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        SourceItemRepositoryInterface $sourceItemRepository,
        array $data = []
    ) {
        $this->_optionFactory = $optionFactory;
        $this->isSingleSourceMode = $isSingleSourceMode;
        $this->sourceRepository = $sourceRepository;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->sourceItemRepository = $sourceItemRepository;
        parent::__construct($context, $stockRegistry, $stockConfiguration, $registry, $optionFactory, $data);

    }

    public function getQtySource( $itemsBySkus )
    {
        $searchCriteria = $this->searchCriteriaBuilder
            ->addFilter(SourceItemInterface::SKU, $itemsBySkus)
            ->create();

        $sourceItems = $this->sourceItemRepository->getList($searchCriteria)->getItems();
        $sourcesBySourceCode = $this->getSourcesBySourceItems($sourceItems);
        $dataItems = [];
        foreach ($sourceItems as $sourceItem) {
            $sku = $sourceItem->getSku();

            if (isset($itemsBySkus)) {
                $source = $sourcesBySourceCode[$sourceItem->getSourceCode()];
                $qty = (float)$sourceItem->getQuantity();
                $dataItems[] = [
                    'source_name' => $source->getName(),
                    'qty' => $qty,
                ];
            }
        }
        return $dataItems;
    }

    private function getSourcesBySourceItems(array $sourceItems): array
    {
        $newSourceCodes = $sourcesBySourceCodes = [];

        foreach ($sourceItems as $sourceItem) {
            $newSourceCodes[$sourceItem->getSourceCode()] = $sourceItem->getSourceCode();
        }

        $searchCriteria = $this->searchCriteriaBuilder
            ->addFilter(SourceInterface::SOURCE_CODE, array_keys($newSourceCodes), 'in')
            ->create();
        $sources = $this->sourceRepository->getList($searchCriteria)->getItems();

        foreach ($sources as $source) {
            $sourcesBySourceCodes[$source->getSourceCode()] = $source;
        }

        return $sourcesBySourceCodes;
    }
}

Step3: Call getQtySource function with item sku in phtml file: app/code/Vendor/Test/view/adminhtml/templates/qty_source.phtml

<?php
$_item = $block->getItem();
$qtySource = $block->getQtySource($_item->getSku());
foreach ( $qtySource as $key => $value) {
    echo '<strong>'.$value['source_name'].' :</strong>';
    echo '<span>'.$value['qty'].'</span><br>';
}

Output:enter image description here

NOTE: This will always display current qty source.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top