Create Custom Field On Sales Order Magento
Photo by William Iven
Create Custom Field On Sales Order Magento
We develop Magento Ecommerce that help our client build Ecommerce website also Order management. We have a lot of customization on admin page to make order management workflow more efficient.
This story begins when we have 2 call center companies that want to use the same Magento admin site to create order. We should recognize who was created order. So we decided that we create new custom field on sales order and show that information to the sales order grid.
Let's start:
Step 1
We should make new custom module. We create 2 new files app/code/Khoaln/Sales/registration.php
and app/code/Khoaln/Sales/etc/module.xml
Step 2
Add your custom column in Database using InstallSchema.php
, our column is call_center_id
.
1public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)2{3 $setup->startSetup();4 $this->addCallCenterIdToSalesOrder($setup);5 $setup->endSetup();6}78protected function addCallCenterIdToSalesOrder($setup)9{10 $connection = $setup->getConnection();11 $connection->addColumn(12 $setup->getTable('sales_order'),13 'call_center_id',14 [15 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,16 'nullable' => true,17 'comment' => 'Call Center ID',18 ]19 );20 $connection->addColumn(21 $setup->getTable('sales_order_grid'),22 'call_center_id',23 [24 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,25 'nullable' => true,26 'comment' => 'Call Center ID',27 ]28 );29}
After add lines of code, you can run install this module and see what is new in database.
I run the command bin/magento setup:upgrade
Step 3
At this stage, it would be good to understand how sales_order_grid
table populated.
When the order is placed, data related to this order is selected from sales_order
table joining several additional tables and inserted
to the sales_order_grid
. You can look at the \Magento\Sales\Model\ResourceModel\Grid::refresh
function and default select is declared in
<Magento Sales module>/etc/di.xml
1<virtualType name="Magento\Sales\Model\ResourceModel\Order\Grid" type="Magento\Sales\Model\ResourceModel\Grid">2 <arguments>3 <argument name="joins" xsi:type="array">4 <item name="sales_shipping_address" xsi:type="array">5 <item name="table" xsi:type="string">sales_order_address</item>6 <item name="origin_column" xsi:type="string">shipping_address_id</item>7 <item name="target_column" xsi:type="string">entity_id</item>8 </item>9 <item name="sales_billing_address" xsi:type="array">10 <item name="table" xsi:type="string">sales_order_address</item>11 <item name="origin_column" xsi:type="string">billing_address_id</item>12 <item name="target_column" xsi:type="string">entity_id</item>13 </item>14 <item name="sales_order_payment" xsi:type="array">15 <item name="table" xsi:type="string">sales_order_payment</item>16 <item name="origin_column" xsi:type="string">entity_id</item>17 <item name="target_column" xsi:type="string">parent_id</item>18 </item>19 </argument>20 </arguments>21</virtualType>
You only care about this when you want to join another table.
In this case, because our data already in the sales_order
table we just need to add new column in Order Grid
1<virtualType name="Magento\Sales\Model\ResourceModel\Order\Grid" type="Magento\Sales\Model\ResourceModel\Grid">2 <arguments>3 <argument name="columns" xsi:type="array">4 <item name="call_center_id" xsi:type="string">sales_order.call_center_id</item>5 </argument>6 </arguments>7</virtualType>
About how to assign call_center_id to sales_order
table base on the admin user. We will talk later in other post.
Step 4
Add your custom column in sales_order_grid by created file app/code/Khoaln/Sales/view/adminhtml/ui_component/sales_order_grid.xml
and extend the ales_order_grid
UI component
1<?xml version="1.0" encoding="UTF-8"?>2<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">3 <columns name="sales_order_columns">4 <column name="call_center_id">5 <argument name="data" xsi:type="array">6 <item name="config" xsi:type="array">7 <item name="filter" xsi:type="string">text</item>8 <item name="label" xsi:type="string" translate="true">Call Center</item>9 </item>10 </argument>11 </column>12 </columns>13</listing>
Just that, now refresh cache and see the result in admin page.
Maybe sometimes you will ask yourself, how can Magento handle it? Please look at this function in
vendor/magento/module-sales/Observer/GridSyncInsertObserver.php
1/**2 * Handles synchronous insertion of the new entity into3 * corresponding grid on certain events.4 *5 * Used in the next events:6 *7 * - sales_order_save_after8 * - sales_order_invoice_save_after9 * - sales_order_shipment_save_after10 * - sales_order_creditmemo_save_after11 *12 * Works only if asynchronous grid indexing is disabled13 * in global settings.14 *15 * @param \Magento\Framework\Event\Observer $observer16 * @return void17 */18 public function execute(\Magento\Framework\Event\Observer $observer)19 {20 if (!$this->globalConfig->getValue('dev/grid/async_indexing')) {21 $this->entityGrid->refresh($observer->getObject()->getId());22 }23 }
So the just call the function refresh
from Grid
class in sales_order_save_after
event and update back to the sales_order_grid
table.
Conclusion
I think this is the basic step when you want to be a magento developer. Hope this post can help you get more knowledge about magento. If you want to see all the code please check https://github.com/khoa-le/magento-sales-order-customize.