1

I want to add a column to sales order invoice grid, that should be exported as it is shown in the grid.The column is a calculated column, based on the row data, so there is no explicit database entry for the column value.

Those questions already had similar issues: Magento 2 + Custom column added sku on grid not showing data in export file and Magento 2 Add Custom Sale Order Grid Column and Export in CSV.

But the answers to those question either suggest to alter ConvertToCsv.php and ConvertToXml.php or are based on a database entry that is joined.

Altering one of the ConvertToXXX.php files in IMHO not the right way, since the generation and calculation of the column data has nothing to do with either csv or xml. Nor do I have da database entry, so the answer does not hold.

Currently I got the following solution, which shows the data in the grid but does not get exported:

File {vendor}\{module}\view\adminhtml\ui_component\sales_order_invoice_grid.xml

with content:

<?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_invoice_columns">
        <column name="custom_column" class="{vendor}\{module}\Ui\Component\Listing\Column\CustomColumn">
            <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">Custom Column</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

and {vendor}\{module}\Ui\Component\Listing\Column\CustomColumn.php with content:

class CustomColumn extends Column
{
    protected $orderRepository;

    public function __construct(...)
    {
        ...
    }

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

            foreach ($dataSource['data']['items'] as & $item) {

                $order  = $this->orderRepository->get($item["order_id"]);
                // $value = calculate value based on order data
                $item[$this->getData('name')] = $value;
            }
        }

        return $dataSource;
    }
}

This is a perfectly fine and easy solution, it respects the Single Responsibility Principle and the Open Closed Principle. I can add multiple additional columns by just adding code, without modifying code. Drawback: The calculated value does not get exported.

In Magento core code in vendor/magento/module-sales/Ui/Component/DataProvider/Document.php they use a switch-case statement to alter some database values to export values. First, I don't know how to intercept/extend this behavior, and secondly, I don't like that switch-case statement, which does not quite adhere to the OCP.

So what is the recommended or best way to show data in the grid and get it exported (independent on which export format was chosen), in best case without doing it twice for grid and export separately.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.