Default order grid in Magento provides only basic columns. Usually, the information provided by the columns is very poor and store-owners need some custom columns to be added for better convenience. Based on this, we decided to show some code snippets that should help newbie Magento developers add new custom columns to orders grid.

1. Configure your extension to observe event 'core_layout_block_create_after'.

The best way to add a new column to the orders grid is to use event observers. In our case, we are going to use event 'core_layout_block_create_after'. To add an observer for this event we need to edit file /etc/config.xml of your custom module.

app/code/community/MyCompany/MyModule/etc/config.xml

<config>
    ...
    <adminhtml>
        <events>
            <core_layout_block_create_after>
                <observers>
                    <magestyapps_ordergrid_add_columns>
                        <class>MyCompany_MyModule_Model_Observer</class>
                        <method>addColumnsToGrid</method>
                    </magestyapps_ordergrid_add_columns>
                </observers>
            </core_layout_block_create_after>
        </events>
    </adminhtml>
    ...
</config>


2. Create an observer for the event

The next step is to create the observer class with the observing method in it:

app/code/community/MyCompany/MyModule/Model/Observer.php

<?php

class MyCompany_MyModule_Model_Observer
{
    /** 
     * Add new column to orders grid
     *
     * @param Varien_Event_Observer $observer
     * @return $this
     */
    public function addColumnsToGrid(Varien_Event_Observer $observer)
    {
        $block = $observer->getEvent()->getBlock();
        
        // Check whether the loaded block is the orders grid block
        if (!($block instanceof Mage_Adminhtml_Block_Sales_Order_Grid)
            || $block->getNameInLayout() != 'sales_order.grid'
        ) {
            return $this;
        }

        // Add a new column rigth after the "Ship to Name" column
        $block->addColumnAfter('coupon_rule_name', [
            'header' => $block->__('Coupon Rule Name'),
            'index' => 'coupon_rule_name',
        ], 'shipping_name');

        return $this;
    }
}

After doing that you can go to Sales > Orders in your Magento admin panel. Now you should see a new column called "Coupon Rule Name" there. But as you see, the column is empty, there is no data in it.

3. Join necessary data to orders collection

The newly added column is empty because Magento takes data from 'sales_flat_order_grid' table while the data we need is stored in 'sales_flat_order' table. So we need to join data from the table to the original collection. To do that we need to create an observer for the event called 'sales_order_grid_collection_load_before'.

app/code/community/MyCompany/MyModule/etc/config.xml

<config>
    ...
    <adminhtml>
        <events>
            ...
            <sales_order_grid_collection_load_before>
                <observers>
                    <magestyapps_ordergrid_prepare_collection>
                        <class>magestyapps_ordergrid/observer</class>
                        <method>prepareOrderGridCollection</method>
                    </magestyapps_ordergrid_prepare_collection>
                </observers>
            </sales_order_grid_collection_load_before>
        </events>
    </adminhtml>
    ...
</config>


app/code/community/MyCompany/MyModule/Model/Observer.php

...

/**
 * @param Varien_Event_Observer $observer
 * @return $this
 */
public function prepareOrderGridCollection(Varien_Event_Observer $observer)
{
    $collection = $observer->getEvent()->getOrderGridCollection();

    $orderCollection = Mage::getResourceModel('sales/order_collection');
    $orderCollection->getSelect()
        ->reset(Zend_Db_Select::COLUMNS)
        ->columns(['order_id' => 'entity_id', 'coupon_rule_name']);

    $collection->getSelect()
        ->joinLeft(['order' => $orderCollection->getSelect()],
            'order.order_id = main_table.entity_id',
            ['coupon_rule_name']);

    return $this;
}

...

P.S. Parts of the code have been taken from Custom Order Grid extension