Magento – Magento 2 add data to custom column (sales order grid)

magento2

I've created a custom column in the sales order grid and now I want to load some data into it. I need to load a specific table from sales_order_address into the column.

This is what I have

registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_Modulename',
    __DIR__
);

di.xml (etc)

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Magento\Sales\Model\ResourceModel\Order\Grid"
                 type="Magento\Sales\Model\ResourceModel\Grid">
        <arguments>
            <argument name="columns" xsi:type="array">
                <item name="custom_field" xsi:type="string">sales_order.custom_field</item>
            </argument>
        </arguments>
    </virtualType>
</config>

module.xml (etc)

sales_order_grid.xml (view/adminhtml/ui_component)

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="sales_order_columns">
        <column name="custom_field">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Prefix</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

How can I load the data into the column?

Best Answer

I have added a tracking number(custom field) column in sales order grid.

The following steps I have implemented in the custom module.

Added the custom column into app/code/Vendor/Modulename/view/adminhtml/ui_component/sales_order_grid.xml

<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="sales_order_columns">
        <column name="track_number">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">                   
                    <item name="filter" xsi:type="string">text</item>                    
                    <item name="label" xsi:type="string" translate="true">Tracking Number
                    </item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

And override the sales_order_additional_columns function by plugin in app/code/Vendor/Modulename/etc/di.xml file

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">   
    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <plugin name="sales_order_additional_columns" type="Vendor\Modulename\Plugins\AddColumnsSalesOrderGridCollection" sortOrder="100" disabled="false" />
    </type>
</config>

Overrite the Collection of sales order grid file. app/code/Vendor/Modulename/Plugins/AddColumnsSalesOrderGridCollection.php

<?php 
namespace Vendor\Modulename\Plugins;

use Magento\Framework\Message\ManagerInterface as MessageManager;
use Magento\Sales\Model\ResourceModel\Order\Grid\Collection as SalesOrderGridCollection;

class AddColumnsSalesOrderGridCollection
{
    private $messageManager;
    private $collection;

    public function __construct(MessageManager $messageManager,
        SalesOrderGridCollection $collection
    ) {

        $this->messageManager = $messageManager;
        $this->collection = $collection;
    }

    public function aroundGetReport(
        \Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory $subject,
        \Closure $proceed,
        $requestName    
    ) {        
        $result = $proceed($requestName);
        if ($requestName == 'sales_order_grid_data_source') {
            if ($result instanceof $this->collection
            ) { 
                $select = $this->collection->getSelect();
                $select->join(
                    ["sst" => "sales_shipment_track"],
                    'main_table.entity_id = sst.entity_id',
                    'sst.track_number'
                )
                    ->distinct();                                   
            }

        }
        return $this->collection;
    }
}

finally flush your cache and refresh the sales order page. It is working fine now.

and see the output like below. enter image description here