Magento 2 Plugin – Set Attribute Value on Backend Order Creation

adminhtmlmagento-2.1magento2ordersplugin

I am attempting to set a custom attribute require_verification on a newly created order from the Magento backend using a plugin in Magento 2.

Many suggestions I have found recommend using events, which I was able to successfully implement. But I am specifically looking for information about how this can be done using a plugin. This is because the use of plugins is preferred over events in Magento 2.

I am attempting to run my plugin after the \Magento\Sales\Controller\Adminhtml\Order\Create\Save execute() method.

Save.php

namespace Training\RequireVerification\Controller\Adminhtml\Order\Create;

class Save
{ 
    public function afterExecute(\Magento\Sales\Controller\Adminhtml\Order\Create\Save $controller, $result) 
    {

        $order = $controller->getOrder(); // DOES NOT WORK
        $order->setRequireVerification(0);
        return $result;
    }
}
?>

di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Sales\Controller\Adminhtml\Order\Create\Save">
        <plugin name="training-order-create-after-controller-plugin" type="Training\RequireVerification\Controller\Adminhtml\Order\Create\Save" sortOrder="10"/>
    </type> 
</config>

The plugin is firing, so I know it is setup properly, I just need help understanding how to get access to the newly created order in the afterExecute method.

Best Answer

This is because the controller object does not contain the order and you are trying to call getOrder() on it. Magento dispatches an observer for this purpose, sales_order_place_after, and you can grab the order there. There are a variety of plugins that could be created for this purpose but the observer mentioned above is easiest.

If you only want this to occur for orders placed through the admin panel, you could implement a plugin for Magento\Sales\Model\AdminOrder\Create with the method afterCreateOrder($subject,$result). The $result variable will contain the actual order.