Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento 2 : How to customise admin sales order grid collection?

Tags:

magento2

I am trying to customise the admin sale order grid collection. I have created an custom sale_order attribute store_manager. These store managers are the admin users eg: 'manager1', 'manager2'.

1) Orders are manually assigned to 'manager1' or 'manager2' -- this part is done

2) Now I am trying to set filter on sale order grid collection, so when manager logged in to there system they can only see there orders.

In Magento 1 we have sales_order_grid_collection_load_before, sales_order_grid_collection_load_after for this requirement .

Is tried to such event for Magento 2 but didn't get any success.

My Queries :

Is there any such event like (sales_order_grid_collection_load_after) in magento 1 which full fill my requirement?

Is there any other way where I can set filter to sale order grid collection?

Note : I already search for this on google but didn't get any perfect solution.

like image 212
Deepak Mankotia Avatar asked May 16 '17 12:05

Deepak Mankotia


2 Answers

I was searching for the events sales_order_grid_collection_load_after and sales_order_grid_collection_load_before to customise the sales order grid.

My findings are, there are no such events in Magento 2. A general event core_collection_abstract_load_after or core_collection_abstract_load_before dispatch to render all of the grids in Magento 2 Admin.

We can override _renderFiltersBefore() function to add a column in sales order grid or to join table with sales_order_grid. Here are the steps:

Step 1: Specify class for sales order grid data source in app/code/Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<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">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="sales_order_grid_data_source" xsi:type="string">Vendor\Module\Model\ResourceModel\Order\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
</config>

Step 2: Add a Collection class in app/code/Vendor/Module/Model/ResourceModel/Order/Grid.php to override _renderFiltersBefore()

<?php

namespace Vendor\Module\Model\ResourceModel\Order\Grid;

use Magento\Sales\Model\ResourceModel\Order\Grid\Collection as OriginalCollection;
use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as FetchStrategy;
use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
use Magento\Framework\Event\ManagerInterface as EventManager;
use Psr\Log\LoggerInterface as Logger;

class Collection extends OriginalCollection
{
    protected $_authSession;

    public function __construct(
       EntityFactory $entityFactory,
       Logger $logger,
       FetchStrategy $fetchStrategy,
       EventManager $eventManager,
       \Magento\Backend\Model\Auth\Session $authSession
    ) {        
       $this->_authSession = $authSession;
       parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager);
    }

    protected function _renderFiltersBefore() 
    {
        $user = $this->_authSession->getUser();
        $joinTable = $this->getTable('your_table');
        $this->getSelect()->joinLeft($joinTable, 'main_table.entity_id = your_table.order_id', ['user_id']);
        parent::_renderFiltersBefore();
    }
}

Step 3 - Optional: To show a new column of user id in Sales order grid, modify standard grid component in app/code/Vendor/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="user_id">
            <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">User ID</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

A reference is here

like image 115
Zulqarnain Abdul Jabbar Avatar answered Nov 15 '22 07:11

Zulqarnain Abdul Jabbar


For our customized Grid, we’ll change the default data source with our own. Its parent is the standard class of the grid collection, which will let the third-party extensions effortlessly process modifications (if needed) using observers and plugins.

To implement that, in the di.xml file of our module, specify that another class should be used for the sales_order_grid data source.

app/code/Vendor/ExtendGrid/etc/di.xml

<?xml version="1.0"?>
<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">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="sales_order_grid_data_source" xsi:type="string">Vendor\ExtendGrid\Model\ResourceModel\Order\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
</config>

As you can see, we’ll need an extension class for the collection. Let’s create it here:

app/code/Vendor/ExtendGrid/Model/ResourceModel/Order/Grid/Collection.php

<?php

namespace Vendor\ExtendGrid\Model\ResourceModel\Order\Grid;

use Magento\Sales\Model\ResourceModel\Order\Grid\Collection as OriginalCollection;
use Vendor\ExtendGrid\Helper\Data as Helper;

/**
* Order grid extended collection
*/
class Collection extends OriginalCollection
{
}

We modify the method _renderFiltersBefore so that it could connect to our table and select the necessary column there.

To do that,

<?php

namespace Vendor\ExtendGrid\Model\ResourceModel\Order\Grid;

use Magento\Sales\Model\ResourceModel\Order\Grid\Collection as OriginalCollection;
use Vendor\ExtendGrid\Helper\Data as Helper;

/**
* Order grid extended collection
*/
class Collection extends OriginalCollection
{
    protected function _renderFiltersBefore()
    {
        $joinTable = $this->getTable('sales_order');
        $this->getSelect()->joinLeft($joinTable, 'main_table.entity_id = sales_order.entity_id', ['coupon_code']);
        //or filter in sale_order_grid collection then use like that
        $this->getSelect()->where("main_table.your_attribute is NULL");
        parent::_renderFiltersBefore();
    }
}
like image 2
Dhrumin Avatar answered Nov 15 '22 07:11

Dhrumin