Magento 2 Orders Grid – How to Add a New Column

magento-2.1magento2order-grid

I've added a new column to the table sales_order called export_status, now I want to add new order grid column with the data from the new sales_order column.

I've managed to add column to the sales_order_grid table.

$installer->getConnection()->addColumn($installer->getTable("sales_order_grid"), "xml_exported", [
     'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
     'comment' => 'XML Exported'
]);

How can I now make it actually show in the orders grid with the value from the sales_order export_status column?

Best Answer

After lots of digging into Magento's core code, I found a solution to my question. Instead of adding a column to the grid via the database, I created a UI component sales_order_grid.xml under [COMPANY]/[MODULE]/view/adminhtml/ui_component/sales_order_grid.xml

<?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="export_status" class="[COMPANY]\[MODULE]\Ui\Component\Listing\Column\Status">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="label" xsi:type="string" translate="true">XML Exported</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

Then created the UI class under [COMPANY]/[MODULE]/Ui/Component/Listing/Column/Status.php

<?php
namespace [COMPANY]\[MODULE]\Ui\Component\Listing\Column;

use \Magento\Sales\Api\OrderRepositoryInterface;
use \Magento\Framework\View\Element\UiComponent\ContextInterface;
use \Magento\Framework\View\Element\UiComponentFactory;
use \Magento\Ui\Component\Listing\Columns\Column;
use \Magento\Framework\Api\SearchCriteriaBuilder;

class Status extends Column
{
    protected $_orderRepository;
    protected $_searchCriteria;

    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        OrderRepositoryInterface $orderRepository,
        SearchCriteriaBuilder $criteria,
        array $components = [],
        array $data = []
    ) {
        $this->_orderRepository = $orderRepository;
        $this->_searchCriteria  = $criteria;
        parent::__construct($context, $uiComponentFactory, $components, $data);
    }

    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item) {

                $order  = $this->_orderRepository->get($item["entity_id"]);
                $status = $order->getData("export_status");

                switch ($status) {
                    case "0":
                        $export_status = "No";
                        break;
                    case "1";
                        $export_status = "Yes";
                        break;
                    default:
                        $export_status = "Failed";
                        break;

                }

                // $this->getData('name') returns the name of the column so in this case it would return export_status
                $item[$this->getData('name')] = $export_status;
            }
        }

        return $dataSource;
    }
}