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.
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
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With