Magento 1 – Adding Custom Attribute to Sales Order Grid

adminhtmlattributesgridmagento-1sales-order

I have created a custom attribute which is the customer account reference and we set this in the back end through the customer page. However we need to add this to the Sales order grid as well. I created my Attribute using this:
http://codemagento.blogspot.co.uk/

This is my sql file:

<?php

$installer = $this;

$installer->startSetup();

$this->addAttribute('customer', 'accref', array(
    'type' => 'varchar',
    'input' => 'text',
    'label' => 'Account Reference',
    'global' => 1,
    'visible' => 1,
    'required' => 1,
    'user_defined' => 1,
    'default' => null,
    'visible_on_front' => 1
));


if (version_compare(Mage::getVersion(), '1.6.0', '<=')) {
    $customer = Mage::getModel('customer/customer');
    $attrSetId = $customer->getResource()->getEntityType()->getDefaultAttributeSetId();
    $this->addAttributeToSet('customer', $attrSetId, 'General', 'accref');
}

if (version_compare(Mage::getVersion(), '1.4.2', '>=')) {
    Mage::getSingleton('eav/config')
            ->getAttribute('customer', 'accref')
            ->setData('used_in_forms', array('adminhtml_customer', 'customer_account_create', 'customer_account_edit', 'checkout_register'))
            ->save();
}

$installer->endSetup(); 

i have tried many things for example adding

$this->addColumn('accref', array(
            'header' => Mage::helper('sales')->__('Account Reference'),
            'index' => 'accref',
        ));

to a copied version of code/core/Mage/Adminhtml/Block/Sales/Order/Grid.php in the _prepareColumns()function.

But nothing is displaying in the sale order grid.

Best Answer

I reckon you need to create a custom module:

app/code/local/My/Module/etc/config.xml:

<?xml version="1.0"?>
<config>
    <modules>
        <My_Module>
            <version>0.0.1</version>
        </My_Module>
    </modules>

    <global>
        <models>
            <module>
                <class>My_Module_Model</class>
            </module>
        </models>
    </global>

    <adminhtml>
        <events>
            <!-- To register the controller action -->
            <controller_action_predispatch_adminhtml>
                <observers>
                    <my_module_custom_register>
                        <type>singleton</type>
                        <class>module/observer</class>
                        <method>registerController</method>
                    </my_module_custom_register>
                </observers>
            </controller_action_predispatch_adminhtml>
            <!-- Called after creating a block -->
            <core_layout_block_create_after>
                <observers>
                    <my_module_custom_before_block>
                        <type>singleton</type>
                        <class>module/observer</class>
                        <method>blockCreateAfter</method>
                    </my_module_custom_before_block>
                </observers>
            </core_layout_block_create_after>
            <!-- Called before loading a non EAV collection -->
            <core_collection_abstract_load_before>
                <observers>
                    <my_module_custom_before_core_load_collection>
                        <class>module/observer</class>
                        <method>beforeCoreCollectionLoad</method>
                    </factoryx_custom_before_core_load_collection>
                </observers>
            </core_collection_abstract_load_before>
        </events>
    </adminhtml>
</config>

app/code/local/My/Module/Model/Observer.php:

<?php

class My_Module_Model_Observer
{
    public function registerController(Varien_Event_Observer $observer)
    {
        $action = $observer->getControllerAction()->getFullActionName();
        switch ($action)
        {
            case 'adminhtml_sales_order_index':
            case 'adminhtml_sales_order_grid':
            case 'adminhtml_sales_order_exportCsv':
            case 'adminhtml_sales_order_exportExcel':
                Mage::register('adminhtml_sales_order_grid', true);
                break;
        }

        return $this;
    }

    public function blockCreateAfter(Varien_Event_Observer $observer)
    {
        $block = $observer->getBlock();

        if($block instanceof Mage_Adminhtml_Block_Sales_Order_Grid)
        {
            $block->addColumnAfter(
                'accref',
                array(
                    'header' => Mage::helper('sales')->__('Account Reference'),
                    'index' => 'accref',
                    'filter_index' => 'cust.value',
                ),
                'created_at'
            );
        }
    }

    public function beforeCoreCollectionLoad(Varien_Event_Observer $observer)
    {

        if (Mage::registry('adminhtml_sales_order_grid')) {

            $collection = $observer->getCollection();
            if (!isset($collection)) {
                return;
            }

            if ($collection instanceof Mage_Sales_Model_Resource_Order_Collection) {
                // Get the attribute id for the accref attribute
                $eavAttribute = Mage::getModel('eav/entity_attribute');
                $accrefId = $eavAttribute->getIdByCode('customer', 'accref');
                $collection->getSelect()->joinLeft(
                    array('cust' => Mage::getSingleton("core/resource")->getTableName('customer_entity_varchar')),
                    'main_table.customer_id = cust.entity_id AND cust.attribute_id = '.$accrefId,
                    array(
                        'cust.value'
                    )
                );
}

And obviously:

app/etc/modules/My_Module.xml:

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