Magento 2

How to Change Order Buttons in Magento 2

In the article I am going to answer how to add, remove and modify buttons on the Order view page in Magento 2

 

Order view page in the Magento administration panel allows you to perform certain actions for a specific Order. Sometimes these actions have to be adjusted based on Merchant's needs and business expectations. In this article we will modify existing Order Buttons at the Order View page.

Our Goal

For this article let's imagine we have the following expectations from a Merchant:

  • We expect to use Invoice button as our next step in order processing flow.
  • We aren't going to use Hold button since our Orders are imported into ERP system.
  • Our integration with Email Marketing platform allows to Send Email notification automatically once an Order has been placed.

Looks clear. Our development skills will help Merchant to achieve his/her expectations.

Where Should We Start?

First of all we have to navigate to the Magento Admin -> Sales -> Orders page and click to one of existing Orders from the Orders grid.

If there are no orders, you might want to create it. URL of Order View page is:

http://magento2.dev/admin/sales/order/view/order_id/1/

From the above URL we may assume that:

  • The admin/sales/order/view page is managed by the Magento\Sales module.
  • The sales/order/view URI part has to have a corresponding layout file where blocks are defined.

Let's see. In the Magento\Sales\view\adminhtml\layout directory there is a sales_order_view.xml file. There is a content container used in the file to assign Magento\Sales\Block\Adminhtml\Order\View class:

<referenceContainer name="content">
    <block class="Magento\Sales\Block\Adminhtml\Order\View" name="sales_order_edit"/>
</referenceContainer>

The Magento\Sales\Block\Adminhtml\Order\View class prepares Information Tab content for the Order View page. This class also prepares buttons which we are going to change:

  • Edit order. Primary page button.
  • Cancel order.
  • Send Email.
  • Creditmemo. The button will be shown once an Invoice is created.
  • Void payment. Depends on Payment Gateway settings.
  • Hold order.
  • Unhold order.
  • Accept Payment. Shows in case Order Status is in "payment_review".
  • Deny Payment. Same as 8.
  • Get Payment Update.
  • Invoice or Invoice and Ship.
  • Ship.
  • Reorder.

These buttons provide full control for an Order: Magento 2 Order Form Buttons Before

All these buttons are hard-coded in the Magento\Sales\Block\Adminhtml\Order\View class. There is no container or array of buttons defined in the di.xml configuration file. It means we have to find alternative way of changing order buttons. The Magento\Sales\Block\Adminhtml\Order\View class adds buttons into buttonList protected variable which is Magento\Backend\Block\Widget\Button\ButtonList class. In the Magento\Backend\Block\Widget\Container class (this is parent class for the Magento\Sales\Block\Adminhtml\Order\View class) we may see that the buttonList has been passed into pushButtons() method:

protected function _prepareLayout()
{
    $this->toolbar->pushButtons($this, $this->buttonList);
    return parent::_prepareLayout();
}

We are going to inject our changes right before buttons will be pushed into Forms Toolbar.

This is a good place to extend logic by adding a Plugin for the Toolbar class. The Magento\Sales\Block\Adminhtml\Order\View class does not provide enough methods with public visibility that is why we have to look deeper into the implementation.

Development

Once we know where to start it is a time to create our new module.

The following actions are must have for our module:

  • Create new etc/module.xml configuration file with module name and setup version.
  • Create registration.php file in order to include module into composer autoload workflow.
  • Add Pronko_Magento2OrderButtons module into the app/etc/config.php file.
  • Run bin/magento setup:upgrade command

In order to add a Plugin which will inject pushButtons() method call and provide control over to our Plugin class we have to declare it first. This di.xml configuration file should be placed into the etc\adminhtml directory:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Backend\Block\Widget\Button\Toolbar">
        <plugin name="orderFormToolbarButtons" type="Pronko\Magento2OrderButtons\Plugin\Block\Widget\Button\Toolbar" />
    </type>
</config>

The plugin node allows to add an Interceptor class for the Magento\Backend\Block\Widget\Button\Toolbar class. The code has to be regenerated before the configuration will take affect. Content of the <magento_root>/var/generation directory should be removed.

The Pronko\Magento2OrderButtons\Plugin\Block\Widget\Button\Toolbar class might look like the following:

<?php

namespace Pronko\Magento2OrderButtons\Plugin\Block\Widget\Button;

use Magento\Backend\Block\Widget\Button\Toolbar as ToolbarContext;
use Magento\Framework\View\Element\AbstractBlock;
use Magento\Backend\Block\Widget\Button\ButtonList;

class Toolbar
{
    /**
     * @param ToolbarContext $toolbar
     * @param AbstractBlock $context
     * @param ButtonList $buttonList
     * @return array
     */
    public function beforePushButtons(
        ToolbarContext $toolbar,
        \Magento\Framework\View\Element\AbstractBlock $context,
        \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
    ) {
        if (!$context instanceof \Magento\Sales\Block\Adminhtml\Order\View) {
            return [$context, $buttonList];
        }
        $buttonList->update('order_edit', 'class', 'edit');
        $buttonList->update('order_invoice', 'class', 'invoice primary');
        $buttonList->update('order_invoice', 'sort_order', (count($buttonList->getItems()) + 1) * 10);

        $buttonList->add('order_review',
            [
                'label' => __('Review'),
                'onclick' => 'setLocation('' . $context->getUrl('sales/*/review') . '')',
                'class' => 'review'
            ]
        );

        $buttonList->remove('order_hold');
        $buttonList->remove('send_notification');

        return [$context, $buttonList];
    }
}

The beforePushButtons() method listens for the Toolbar::pushButtons() call and triggered before original Toolbar::pushButtons() method call. Once we are in the method the $context argument has to be checked first. It allows to modify buttonList only when execution is in context of the Magento\Sales\Block\Adminhtml\Order\View class:

if (!$context instanceof \Magento\Sales\Block\Adminhtml\Order\View) {
    return [$context, $buttonList];
}

Once this is checked we have some control over buttonList object prepared in the Magento\Sales\Block\Adminhtml\Order\View::_construct() method. Changing class of Primary Edit button to become secondary button:

$buttonList->update('order_edit', 'class', 'edit');

Updating Invoice button to become Primary Button:

$buttonList->update('order_invoice', 'class', 'invoice primary');

Since Invoice became Primary Button it has to be moved right side to be consistent with other pages:

$buttonList->update('order_invoice', 'sort_order', (count($buttonList->getItems()) + 1) * 10);

Adding new Review button:

$buttonList->add('order_review',
    [
        'label' => __('Review'),
        'onclick' => 'setLocation('' . $context->getUrl('sales/*/review') . '')',
        'class' => 'review'
    ]
);

And finally, removing Hold and Send Email buttons from the page:

$buttonList->remove('order_hold');
$buttonList->remove('send_notification');

As a result of adding new Plugin we have changed order form button toolbar:

Magento 2 Order Form Buttons After

0 Bình luận

Trở về
  • Magento plug-ins
  • Magento plug-ins

    Magento2 gave very good concept called Plugin   we can do what ever after and before core function and also we have...

  • HOW TO CREATE MENU IN MAGENTO 2 ADMIN
  • HOW TO CREATE MENU IN MAGENTO 2 ADMIN

    magento-2-admin- menu My previous tutorial show you how to create a simple module in Magento 2, learn more here: http://www.venustheme.com/how-to-create-magento-2-module/....