Cách tạo một admin grid từ một table thì các bạn đã biết rồi phải không nào. Nếu bạn nào chưa biết có thể xem lại bài viết tạo grid của admin tại đây. Trong bài viết này mình sẽ hướng dẫn các bạn tạo một grid chứa dữ liệu của nhiều table trong Magento 2.
Tạo Ui Component
[Vendor]/[Module]/view/adminhtml/ui_component/your_grid.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
<?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”>
<argument name=“data” xsi:type=“array”>
<item name=“js_config” xsi:type=“array”>
<item name=“provider” xsi:type=“string”>your_grid.your_grid_data_source</item>
</item>
</argument>
<settings>
<spinner>your_grid_columns</spinner>
<deps>
<dep>your_grid.your_grid_data_source</dep>
</deps>
</settings>
<dataSource name=“your_grid_data_source” component=“Magento_Ui/js/grid/provider”>
<settings>
<updateUrl path=“mui/index/render”/>
<storageConfig>
<param name=“indexField” xsi:type=“string”>item_id</param>
</storageConfig>
</settings>
<aclResource>Magento_Reports::salesroot_sales</aclResource>
<dataProvider class=“MagentoFrameworkViewElementUiComponentDataProviderDataProvider” name=“your_grid_data_source”>
<settings>
<requestFieldName>item_id</requestFieldName>
<primaryFieldName>item_id</primaryFieldName>
</settings>
</dataProvider>
</dataSource>
<listingToolbar name=“listing_top”>
<settings>
<sticky>true</sticky>
</settings>
<bookmark name=“bookmarks”/>
<columnsControls name=“columns_controls”/>
<exportButton name=“export_button”/>
<filters name=“listing_filters”>
<argument name=“data” xsi:type=“array”>
<item name=“config” xsi:type=“array”>
<item name=“templates” xsi:type=“array”>
<item name=“filters” xsi:type=“array”>
<item name=“select” xsi:type=“array”>
<item name=“component” xsi:type=“string”>Magento_Ui/js/form/element/ui–select</item>
<item name=“template” xsi:type=“string”>ui/grid/filters/elements/ui–select</item>
</item>
</item>
</item>
</item>
</argument>
</filters>
<paging name=“listing_paging”/>
<massaction name=“listing_massaction” />
</listingToolbar>
<columns name=“your_grid_columns”>
<selectionsColumn name=“ids”>
<settings>
<indexField>item_id</indexField>
</settings>
</selectionsColumn>
<column name=“item_id”>
<settings>
<label translate=“true”>Item ID</label>
<filter>text</filter>
</settings>
</column>
<column name=“product_sku”>
<settings>
<label translate=“true”>SKU</label>
<filter>text</filter>
</settings>
</column>
<column name=“product_name”>
<settings>
<filter>text</filter>
<label translate=“true”>Product Name</label>
</settings>
</column>
<column name=“main_order”>
<settings>
<filter>text</filter>
<label translate=“true”>Main Order</label>
</settings>
</column>
<column name=“order_date” class=“MagentoUiComponentListingColumnsDate” component=“Magento_Ui/js/grid/columns/date”>
<settings>
<label translate=“true”>Order Date</label>
<filter>dateRange</filter>
<dataType>date</dataType>
</settings>
</column>
<column name=“status_main_order”>
<settings>
<label translate=“true”>Status of Main order</label>
<filter>false</filter>
</settings>
</column>
<column name=“qty_ordered”>
<settings>
<label translate=“true”>Quantity Ordered</label>
<filter>false</filter>
</settings>
</column>
<column name=“original_price” class=“MagentoSalesUiComponentListingColumnPrice”>
<settings>
<filter>false</filter>
<label translate=“true”>Original Price</label>
</settings>
</column>
</columns>
</listing>
|
Tạo di.xml
[Vendor]/[Module]/etc/di.xml
1
2
3
4
5
6
7
8
9
10
|
<?xml version=“1.0” encoding=“UTF-8”?>
<config xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=“urn:magento:framework:ObjectManager/etc/config.xsd”>
<type name=“MagentoFrameworkViewElementUiComponentDataProviderCollectionFactory”>
<arguments>
<argument name=“collections” xsi:type=“array”>
<item name=“your_grid_data_source” xsi:type=“string”>[Vendor]/[Module]ModelResourceModelProcessingGridCollection</item>
</argument>
</arguments>
</type>
</config>
|
Tạo Collection
[Vendor]/[Module]ModelResourceModelProcessingGridCollection.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
<?php
namespace [Vendor]/[Module]ModelResourceModelViMagentoGrid;
use MagentoCatalogModelProduct;
use MagentoFrameworkDataCollectionDbFetchStrategyInterface as FetchStrategy;
use MagentoFrameworkDataCollectionEntityFactoryInterface as EntityFactory;
use MagentoFrameworkEventManagerInterface as EventManager;
use PsrLogLoggerInterface as Logger;
use MagentoSalesModelResourceModelOrderItem;
use MagentoEavModelResourceModelEntityAttribute;
use MagentoSalesModelOrder;
use MagentoSalesModelOrderItem as ItemOrder;
class Collection extends MagentoFrameworkViewElementUiComponentDataProviderSearchResult
{
private $eavAttribute;
protected $itemOrder;
/**
* @var MagentoUiDataProviderAddFilterToCollectionInterface[]
*/
protected $addFilterStrategies;
public function __construct(
Attribute $eavAttribute,
ItemOrder $itemOrder,
EntityFactory $entityFactory,
Logger $logger,
FetchStrategy $fetchStrategy,
EventManager $eventManager,
array $addFilterStrategies = [],
$mainTable = ‘sales_order_item’,
$resourceModel = Item::class,
$identifierName = null,
$connectionName = null
)
{
$this->addFilterStrategies = $addFilterStrategies;
$this->itemOrder = $itemOrder;
$this->eavAttribute = $eavAttribute;
parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel, $identifierName, $connectionName);
}
protected function _initSelect()
{
parent::_initSelect();
$this->getSelect()
->joinLeft(
[‘so’ => $this->getTable(‘sales_order’)],
‘main_table.order_id = so.entity_id’,
[‘main_order’ => ‘so.increment_id’, ‘order_date’ => ‘so.created_at’, ‘status_main_order’ => ‘so.status’]
)->joinLeft(
[‘cpe’ => $this->getTable(‘catalog_product_entity’)],
‘main_table.product_id = cpe.entity_id’,
[‘product_sku’ => ‘cpe.sku’]
)->joinLeft(
[‘cpev’ => $this->getTable(‘catalog_product_entity_varchar’)],
“cpe.row_id = cpev.row_id AND cpev.attribute_id = {$this->getProductNameAttributeId()}”,
[‘product_name’ => ‘cpev.value’]
)
->where(‘so.state = ?’, Order::STATE_COMPLETE)
->group(‘main_table.item_id’);
return $this;
}
private function getProductNameAttributeId()
{
return $this->getProductAttribute(‘name’);
}
private function getProductAttribute($code)
{
return $this->eavAttribute->getIdByCode(Product::ENTITY, $code);
}
}
|

Làm đến đây các bạn sẽ có được 1 grid với dữ liệu như mong muốn. Nhưng chưa dừng lại ở đây. Chúng ta phải làm thêm vài bước nữa để hoàn thiện grid của mình. Nếu bạn filter sẽ gặp lỗi này:

Để khắc phục lỗi này bạn cần thêm một biến protected $_map và thêm các field cần filter vào trong file Collection.php ở trên.
1
2
3
4
5
6
7
8
9
|
protected $_map = [
‘fields’ => [
‘main_order’ => ‘so.increment_id’,
‘order_date’ => ‘so.created_at’,
‘status_main_order’ => ‘so.status’,
‘product_sku’ => ‘cpe.sku’,
‘product_name’ => ‘cpev.value’
]
];
|
Hoặc bạn cũng có thể sử dụng function addFilterToMap để thực hiện công việc tương tự:
1
2
|
$this->addFilterToMap( ‘so.increment_id’, ‘main_order’);
return $this;
|
Còn nếu dữ liệu export ra bị sai, ví dụ ngày giờ bị sai do không lấy đúng time zone thì các bạn có thể thêm đoạn code này vào file di.xml. Đoạn code này sẽ chuyển ngày giờ về đúng time zone cho bạn.
[Vendor]/[Module]/etc/adminhtml/di.xml
1
2
3
4
5
6
7
8
9
10
11
12
|
<?xml version=“1.0” encoding=“UTF-8”?>
<config xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=“urn:magento:framework:ObjectManager/etc/config.xsd”>
<type name=“MagentoUiModelExportMetadataProvider”>
<arguments>
<argument name=“data” xsi:type=“array”>
<item name=“your_grid” xsi:type=“array”>
<item name=“order_date” xsi:type=“string”>order_date</item>
</item>
</argument>
</arguments>
</type>
</config>
|
Còn nếu bạn muốn chỉnh sửa dữ liệu khi export thì các bạn có thể plugin vào function getRowData của class MagentoUiModelExportMetadataProvider.
Kết luận
Hy vọng bài viết này sẽ có ích đối với các bạn. Thanks.