I want to add Company Name in Customer grid during order creation. Can any one help me how can we do that in magento2.We need to extened sales_order_create_customer_block.xml, but i can't able make it. Please help me.
Here are my code screenshtots with output
Magento – add Company name in Customer grid during order creation
magento2
Related Solutions
You need to define router for adminhtml in order to get it work with your custom module. You can define the same at app\code{{your_package}}{{your_module}}\etc\adminhtml\routes.xml as like below:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="orderdelete" frontName="orderdelete">
<module name="Krish_OrderDelete" />
</route>
</router>
</config>
You can define your own frontName for admin route. Now in your ui xml file, available at view\adminhtml\ui_component under custom mass action search the item name="url" and set path like "orderdelete/order/massDelete"
It should work if you will implement it correctly.
Please refer below module which I developed to add new MassDelete action in sales order grid (All the below files should be in your custom module i.e. package_module).
1. \etc\module.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Krish_OrderDelete" setup_version="1.0.0">
<sequence>
<module name="Magento_Sales"/>
</sequence>
</module>
</config>
2. \etc\adminhtml\routes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="orderdelete" frontName="orderdelete">
<module name="Krish_OrderDelete" />
</route>
</router>
</config>
3. \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">
<listingToolbar name="listing_top">
<massaction name="listing_massaction">
<action name="order_delete">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="type" xsi:type="string">order_delete</item>
<item name="label" xsi:type="string" translate="true">Delete</item>
<item name="url" xsi:type="url" path="orderdelete/order/massDelete"/>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Delete Order(s)</item>
<item name="message" xsi:type="string" translate="true">Are you sure you wan\'t to delete selected items?</item>
</item>
</item>
</argument>
</action>
</massaction>
</listingToolbar>
</listing>
**Note: If you will define your action under tag <listingToolbar>, than new mass action will be added as child mass action.**
4. \Controller\Adminhtml\Order\MassDelete.php
<?php
namespace Krish\OrderDelete\Controller\Adminhtml\Order;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory;
use Magento\Sales\Api\OrderManagementInterface;
/**
* Class MassDelete
*/
class MassDelete extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction
{
/**
* @var OrderManagementInterface
*/
protected $orderManagement;
/**
* @param Context $context
* @param Filter $filter
* @param CollectionFactory $collectionFactory
* @param OrderManagementInterface $orderManagement
*/
public function __construct(
Context $context,
Filter $filter,
CollectionFactory $collectionFactory,
OrderManagementInterface $orderManagement
) {
parent::__construct($context, $filter);
$this->collectionFactory = $collectionFactory;
$this->orderManagement = $orderManagement;
}
/**
* Hold selected orders
*
* @param AbstractCollection $collection
* @return \Magento\Backend\Model\View\Result\Redirect
*/
protected function massAction(AbstractCollection $collection)
{
$countDeleteOrder = 0;
$model = $this->_objectManager->create('Magento\Sales\Model\Order');
foreach ($collection->getItems() as $order) {
if (!$order->getEntityId()) {
continue;
}
$loadedOrder = $model->load($order->getEntityId());
$loadedOrder->delete();
$countDeleteOrder++;
}
$countNonDeleteOrder = $collection->count() - $countDeleteOrder;
if ($countNonDeleteOrder && $countDeleteOrder) {
$this->messageManager->addError(__('%1 order(s) were not deleted.', $countNonDeleteOrder));
} elseif ($countNonDeleteOrder) {
$this->messageManager->addError(__('No order(s) were deleted.'));
}
if ($countDeleteOrder) {
$this->messageManager->addSuccess(__('You have deleted %1 order(s).', $countDeleteOrder));
}
$resultRedirect = $this->resultRedirectFactory->create();
$resultRedirect->setPath($this->getComponentRefererUrl());
return $resultRedirect;
}
}
5. \composer.json
{
"name": "krish/magento2-order-delete",
"description": "extension for deleting orders in magento 2",
"type": "magento2-module",
"version": "1.0.0",
"license": [
"OSL-3.0",
"AFL-3.0"
],
"require": {
"php": "~5.5.0|~5.6.0|~7.0.0",
"magento/magento-composer-installer": "*"
},
"extra": {
"map": [
[
"*",
"Krish/OrderDelete"
]
]
}
}
6. \registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Krish_OrderDelete',
__DIR__
);
There are lots of answers about this question. But, almost articles deal with attribute mapped to any field of sales_order table. But, company name is not mapped on sales_order table directly so it 's some complex than others.
This is correct answer which we proved on our site. The detailed steps are as follow.
Adding column to sales_order_grid database table
Columns are added to database tables using UpgradeSchema script. To be consistent, this script should be updated in the same module, where company name table was added.
<?php
namespace [NameSpace]\[ModuleName]\Setup;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\DB\Adapter\AdapterInterface;
class UpgradeSchema implements UpgradeSchemaInterface
{
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
$installer->getConnection()->addColumn(
$installer->getTable('sales_order_grid'),
'company_name',
[
'type' => Table::TYPE_DATE,
'nullable' => true,
'comment' => 'Company Name',
]
);
$setup->endSetup();
}
}
Just add it to app/code///Setup/UpgradeSchema.php file.
DI configuration to populate the column is sales_order_grid table.
When order is placed (according to default configuration), data related to this order is selected from sales_order table joining several additional tables and inserted to sales_order_grid. This operation is initiated by \Magento\Sales\Model\ResourceModel\Grid::refresh function and the default select is declared in “/etc/di.xml” file. app/code/[Namespace]/[Module]/etc/adminhtml/di.xml file.
<virtualType name="Magento\Sales\Model\ResourceModel\Order\Grid" type="Magento\Sales\Model\ResourceModel\Grid">
<arguments>
<argument name="joins" xsi:type="array">
<item name="customer_grid_flat" xsi:type="array">
<item name="table" xsi:type="string">customer_grid_flat</item>
<item name="origin_column" xsi:type="string">customer_id</item>
<item name="target_column" xsi:type="string">entity_id</item>
</item>
</argument>
<argument name="columns" xsi:type="array">
<item name="company_name" xsi:type="string">customer_grid_flat.company_name</item>
</argument>
</arguments>
</virtualType>
After this step, our company_name column in sales_order_grid table is populated with value from customer_grid_flat table each time order is placed. Still, column will exist only in database, and will not be visible in admin panel.
Configure UI grid component to display the column
Finally, to reflect the column on admin panel grid, we have to extend sales_order_grid ui component by adding a ui configuration file in our module. It is possible to extend ui configuration fo sales order grid introducing app/code/[Namespace]/[Module]/view/adminhtml/ui_component/sales_order_grid.xml
<columns name="sales_order_columns">
<column name="company_name">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>
</item>
<item name="config" xsi:type="array">
<item name="visible" xsi:type="boolean">true</item>
<item name="dataType" xsi:type="string">select</item>
<item name="align" xsi:type="string">left</item>
<item name="filter" xsi:type="string">select</item>
<item name="label" xsi:type="string" translate="true">Company Name</item>
</item> -->
</argument>
</column>
</columns>
Populating created sales_order_grid column for existing order
To do this, we may create upgrade function as follow.
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if (version_compare($context->getVersion(), '1.0.1', '<')) {
$connection = $setup->getConnection();
$grid = $setup->getTable('sales_order_grid');
$source = $setup->getTable('customer_grid_flat');
$connection->query(
$connection->updateFromSelect(
$connection->select()
->join(
$source,
sprintf('%s.customer_id = %s.entity_id', $grid, $source),
'company_name'
),
$grid
)
);
}
$setup->endSetup();
}
Finally, be sure to refresh config cache after editing xml files.
The importance of this answer is just dealing with possibility of all kinds of tables, not just sales_order table records.
Hope this answer is useful for you. Please feel free to provide any feedback in comments.
Best Answer
Yes, you're right. We need to update this
sales_order_create_customer_block.xml
layout file for company attribute but alongside this we also need to extend the grid collection.Because the collection, which is being used to populate customer grid data doesn't include company attribute by default.
So after adding company attribute to the collection, we can add a new block instance for company column in grid columnSet.
Here are the steps to do so in your custom module.