Adding Mass Actions to Magento Orders

By | December 27, 2014

I recently needed to add the ability to perform mass actions to Magento’s order screen.  I’m far from being a Magneto expert, but I was able to find several examples online that got me part of the way there.  After some experimentation and learning, I finally succeeded in adding the most crucial feature we were lacking, which was the ability to invoice multiple orders at once.  For the sake of anyone else in need of this information, I’ll include all of the steps I took in this post.   I created a module for Magento 1.6, though I suspect this will work in later versions as well.

 

Screen Shot 2014-12-22 at 7.35.57 PM

First, add the XML file that describes your module to the modules directory.  In my case this was, /app/etc/modules/MiscWS_MassActions.xml.  Notice that I am putting my code in the “local” directory.

<?xml version="1.0"?>
<config>
    <modules>
        <MiscWS_MassActions>
            <active>true</active>
            <codePool>local</codePool>
        </MiscWS_MassActions>
    </modules>
</config>

Next, set up the directories in /app/code/local to contain your module if they do not already exist.  In my case, I created “MiscWS”, where I may eventually add multiple modules.  Inside of that, I added another directory, “MassActions”, to contain this module.  In other words, create /app/code/local/MiscWS/MassActions or similar to match your requirements.

Add a config.xml file to your directory at /app/code/local/MiscWS/MassActions/etc/config.xml to describe your module.  Lines 2-6 describe the module itself.  Lines 7-17 set up the URL at which your module’s controller will be accessible.  Lines 18-30 set up an observer that will be called as the order screen is built, allowing you to add your option(s) to the mass actions drop-down list.

<config>
    <modules>
        <MiscWS_MassActions>
            <version>0.1.0</version>
        </MiscWS_MassActions>
    </modules>
    <admin>
          <routers>
             <MiscWS_MassActions>
                <use>admin</use>
                <args>
                   <module>MiscWS_MassActions</module>
                   <frontName>miscwsmassactions</frontName>
                </args>
             </MiscWS_MassActions>
          </routers>
    </admin>
    <adminhtml>
        <events>
            <core_block_abstract_prepare_layout_before>
                <observers>
                    <MiscWS_MassActions_Model_Observer>
                        <type>singleton</type>
                        <class>MiscWS_MassActions_Model_Observer</class>
                        <method>addMassAction</method>
                    </MiscWS_MassActions_Model_Observer>
                </observers>
            </core_block_abstract_prepare_layout_before>
        </events>
    </adminhtml>
</config>

Add an observer that will add your option to the dropdown list by creating the following file:  /app/code/local/MiscWS/MassActions/Model/Observer.php.  I will eventually add more actions, but this was the most crucial at present.

<?php
class MiscWS_MassActions_Model_Observer
{
    public function addMassAction($observer)
    {
        $block = $observer->getEvent()->getBlock();
        if(get_class($block) =='Mage_Adminhtml_Block_Widget_Grid_Massaction'
            && $block->getRequest()->getControllerName() == 'sales_order')
        {
            $block->addItem('miscwsmassactions', array(
                'label' => 'Invoice - Capture Online',
                'url' => Mage::app()->getStore()->getUrl('miscwsmassactions/adminhtml_massActions/massInvoiceCaptureOnline')
            ));
        }
    }
}

Finally, add the code to perform the action: /app/code/local/MiscWS/MassActions/controllers/Adminhtml/MassActionsController.php.  Notice that “adminhtml_massActions” on line 12 in the code above corresponds to the class name minus the word “Controller” and with the first word in lowercase.  By the same token, the action, “massInvoiceCaptureOnline”, refers to the method name minus the word “Action”.  This caused me some confusion, not being intimately with familiar with Magento controllers.

<?php

class MiscWS_MassActions_Adminhtml_MassActionsController extends Mage_Adminhtml_Controller_Action
{
  public function massInvoiceCaptureOnlineAction()
    {
        $orderIds = $this->getRequest()->getPost('order_ids', array());
        $countInvoicedOrder = 0;
        $countNonInvoicedOrder = 0;

        foreach ($orderIds as $orderId) {
            $order = Mage::getModel('sales/order')->load($orderId);
            if ($order->canInvoice()) {
                $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
                if( $invoice->getTotalQty() ) {
                    $invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
                    $invoice->register();
                    $transactionSave = Mage::getModel('core/resource_transaction')
                        ->addObject($invoice)
                        ->addObject($invoice->getOrder());
                    $transactionSave->save();                    
                    $countInvoicedOrder++;
                } else {
                    $countNonInvoicedOrder++;
                }
                         
            } else {
                $countNonInvoicedOrder++;
            }
        }
        if ($countNonInvoicedOrder) {
            if ($countInvoicedOrder) {
                $this->_getSession()->addError($this->__('%s order(s) were not invoiced.', $countNonInvoicedOrder));
            } else {
                $this->_getSession()->addError($this->__('No order(s) were invoiced.'));
            }
        }
        if ($countInvoicedOrder) {
            $this->_getSession()->addSuccess($this->__('%s order(s) have been invoiced.', $countInvoicedOrder));
        }
        $this->_redirect('adminhtml/sales_order/');
    }
}

There are some relatively inexpensive plugins available that offer a variety of mass actions, and I may end up going that direction at some point.  For now, however, this solves the immediate need, and I learned a little something in the process.

 

References:

Magento Controller Dispatch – Describes how Magento dispatches requests to controllers.

Adding a New Mass Action in Magento – This is where I got some of the best information.  It is lacking the controller piece, however.

One thought on “Adding Mass Actions to Magento Orders

  1. Abdul Ghaffar

    I have add mass action by following you. I need to pass selected order ids “$orderIds” to a js function. Is is possible?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *