Add column to sales order view page
-
08-03-2021 - |
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.
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>';
}
NOTE: This will always display current qty source.