Ever needed to add one additional hold status in Magento?

For example:

Let’s say that we have some order processing logic integrated with third-party shipping provider. We make API call and it fails.

If we put an order on regular onHold status, it will mix up with orders that are put onHold by the site administrator and we will not be able to filter them later if we want to re-try processing etc.

I suppose that most convenient way would be to use “holded” state and create additional status, for example: “order_processing_error”.

This can be (of course) done through Magento admin, but to keep it modular with our code, let’s add upgrade script to our module:

<?php
 
$installer = $this;
 
// Required tables
$statusTable = $installer->getTable('sales/order_status');
$statusStateTable = $installer->getTable('sales/order_status_state');
 
// Insert statuses
$installer->getConnection()->insertArray(
    $statusTable,
    array(
        'status',
        'label'
    ),
    array(
        array('status' => 'order_processing_error', 'label' => 'Order Processing Error'),
    )
);
 
// Insert states and mapping of statuses to states
$installer->getConnection()->insertArray(
    $statusStateTable,
    array(
        'status',
        'state',
        'is_default'
    ),
    array(
        array(
            'status' => 'order_processing_error',
            'state' => 'holded',
            'is_default' => 0
        ),
    )
);
 
$installer->endSetup();

Of course, don’t forget to increase module version in “config.xml” file in order this upgrade script to execute.

Next, we can put our orders to new “Order Processing Error” status which has “holded” state and like regular holded orders will need to be un-holded before any additional changes on it.

<?php
//...
 
try {
            //...Some operation that will possible cause exception ...
        } Catch (Exception $e) {
             
            Mage::logException($e);
 
            if ($order->canHold()) {
                $order->setHoldBeforeState($order->getState());
                $order->setHoldBeforeStatus($order->getStatus());
                $order->setState(Mage_Sales_Model_Order::STATE_HOLDED, 'order_processing_error', $errMsg);
                $order->save();
            }
        }
 
//...

And that is it 🙂 If you find this article helpful, please don’t forget to share it 🙂 Cheers!

Categories: Magento