Add Column to a grid (observer) - Column ‘store_id’ in where clause is ambiguous issue

Let's try this again with on other solution I mentioned before to you :-) , I have build the complete extension to show you how to add the field to the grid table. After that you only need a layout update file to add the column to you order grid page.

I called the extension Example_SalesGrid, but you can change it to your own needs.

Let's start by creating the module init xml in /app/etc/modules/Example_SalesGrid.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!--
 Module bootstrap file
-->
<config>
    <modules>
        <Example_SalesGrid>
            <active>true</active>
            <codePool>community</codePool>
            <depends>
                <Mage_Sales />
            </depends>
        </Example_SalesGrid>
    </modules>
</config>

Next we create our module config xml in /app/code/community/Example/SalesGrid/etc/config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Example_SalesGrid>
            <version>0.1.0</version> <!-- define version for sql upgrade -->
        </Example_SalesGrid>
    </modules>
    <global>
        <models>
            <example_salesgrid>
                <class>Example_SalesGrid_Model</class>
            </example_salesgrid>
        </models>
        <blocks>
            <example_salesgrid>
                <class>Example_SalesGrid_Block</class>
            </example_salesgrid>
        </blocks>
        <events>
            <!-- Add observer configuration -->
            <sales_order_resource_init_virtual_grid_columns>
                <observers>
                    <example_salesgrid>
                        <model>example_salesgrid/observer</model>
                        <method>addColumnToResource</method>
                    </example_salesgrid>
                </observers>
            </sales_order_resource_init_virtual_grid_columns>
        </events>
        <resources>
            <!-- initialize sql upgrade setup -->
            <example_salesgrid_setup>
                <setup>
                    <module>Example_SalesGrid</module>
                    <class>Mage_Sales_Model_Mysql4_Setup</class>
                </setup>
            </example_salesgrid_setup>
        </resources>
    </global>
    <adminhtml>
        <layout>
            <!-- layout upgrade configuration -->
            <updates>
                <example_salesgrid>
                    <file>example/salesgrid.xml</file>
                </example_salesgrid>
            </updates>
        </layout>
    </adminhtml>
</config>

Now we create the sql upgrade script in /app/code/community/Example/SalesGrid/sql/example_salesgrid_setup/install-0.1.0.php:

<?php
/**
 * Setup scripts, add new column and fulfills
 * its values to existing rows
 *
 */
$this->startSetup();
// Add column to grid table

$this->getConnection()->addColumn(
    $this->getTable('sales/order_grid'),
    'customer_group_id',
    'smallint(6) DEFAULT NULL'
);

// Add key to table for this field,
// it will improve the speed of searching & sorting by the field
$this->getConnection()->addKey(
    $this->getTable('sales/order_grid'),
    'customer_group_id',
    'customer_group_id'
);

// Now you need to fullfill existing rows with data from address table

$select = $this->getConnection()->select();
$select->join(
    array('order'=>$this->getTable('sales/order')),
    $this->getConnection()->quoteInto(
        'order.entity_id = order_grid.entity_id'
    ),
    array('customer_group_id' => 'customer_group_id')
);
$this->getConnection()->query(
    $select->crossUpdateFromSelect(
        array('order_grid' => $this->getTable('sales/order_grid'))
    )
);

$this->endSetup();

Next we create the layout update file in /app/design/adminhtml/default/default/layout/example/salesgrid.xml:

<?xml version="1.0"?>
<layout>
    <!-- main layout definition that adds the column -->
    <add_order_grid_column_handle>
        <reference name="sales_order.grid">
            <action method="addColumnAfter">
                <columnId>customer_group_id</columnId>
                <arguments module="sales" translate="header">
                    <header>Customer Group</header>
                    <index>customer_group_id</index>
                    <type>options</type>
                    <filter>Example_SalesGrid_Block_Widget_Grid_Column_Customer_Group</filter>
                    <renderer>Example_SalesGrid_Block_Widget_Grid_Column_Renderer_Customer_Group</renderer>
                    <width>200</width>
                </arguments>
                <after>grand_total</after>
            </action>
        </reference>
    </add_order_grid_column_handle>
    <!-- order grid action -->
    <adminhtml_sales_order_grid>
        <!-- apply the layout handle defined above -->
        <update handle="add_order_grid_column_handle" />
    </adminhtml_sales_order_grid>
    <!-- order grid view action -->
    <adminhtml_sales_order_index>
        <!-- apply the layout handle defined above -->
        <update handle="add_order_grid_column_handle" />
    </adminhtml_sales_order_index>
</layout>

Now we need two Block files, one to create the filter options, /app/code/community/Example/SalesGrid/Block/Widget/Grid/Column/Customer/Group.php:

<?php

class Example_SalesGrid_Block_Widget_Grid_Column_Customer_Group extends Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Select  {

    protected $_options = false;

    protected function _getOptions(){

        if(!$this->_options) {
            $methods = array();
            $methods[] = array(
                'value' =>  '',
                'label' =>  ''
            );
            $methods[] = array(
                'value' =>  '0',
                'label' =>  'Guest'
            );

            $groups = Mage::getResourceModel('customer/group_collection')
                ->addFieldToFilter('customer_group_id', array('gt' => 0))
                ->load()
                ->toOptionArray();

            $this->_options = array_merge($methods,$groups);
        }
        return $this->_options;
    }
}

And the second to translate the row values to the correct text that will be displayed, /app/code/community/Example/SalesGrid/Block/Widget/Grid/Column/Renderer/Customer/Group.php:

<?php

class Example_SalesGrid_Block_Widget_Grid_Column_Renderer_Customer_Group extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract   {

    protected $_options = false;

    protected function _getOptions(){

        if(!$this->_options) {
            $methods = array();
            $methods[0] = 'Guest';

            $groups = Mage::getResourceModel('customer/group_collection')
                ->addFieldToFilter('customer_group_id', array('gt' => 0))
                ->load()
                ->toOptionHash();
            $this->_options = array_merge($methods,$groups);
        }
        return $this->_options;
    }

    public function render(Varien_Object $row){
        $value = $this->_getValue($row);
        $options = $this->_getOptions();
        return isset($options[$value]) ? $options[$value] : $value;
    }
}

The last file needed is only needed if you create an extra column from a table other than sales/order (sales_flat_order). All fields in sales/order_grid matching the column name from sales/order is automatically updated in the sales/order_grid table. If you need to add the payment option for example you will need this observer to add the field to the query so the data can be copied to the correct table. The observer used for this is in /app/code/community/Example/SalesGrid/Model/Observer.php:

<?php
/**
 * Event observer model
 *
 *
 */
class Example_SalesGrid_Model_Observer {

    public function addColumnToResource(Varien_Event_Observer $observer) {
        // Only needed if you use a table other than sales/order (sales_flat_order)

        //$resource = $observer->getEvent()->getResource();
        //$resource->addVirtualGridColumn(
        //  'payment_method',
        //  'sales/order_payment',
        //  array('entity_id' => 'parent_id'),
        //  'method'
        //);
    }
}

This code is based on the example from http://www.ecomdev.org/2010/07/27/adding-order-attribute-to-orders-grid-in-magento-1-4-1.html

Hope the example above solves your problem.


Try to use these:

public function salesOrderGridCollectionLoadBefore($observer)
{
    /**
     * @var $select Varien_DB_Select
     */
    $collection = $observer->getOrderGridCollection();
    $collection->addFilterToMap('store_id', 'main_table.store_id');
    $select     = $collection->getSelect();
    $select->joinLeft(array('oe' => $collection->getTable('sales/order')), 'oe.entity_id=main_table.entity_id', array('oe.customer_group_id'));
    if ($where = $select->getPart('where')) {
        foreach ($where as $key=> $condition) {
            if (strpos($condition, 'store_id')) {
                $value       = explode('=', trim($condition, ')'));
                $value       = trim($value[1], "' ");
                $where[$key] = "(main_table.store_id = '$value')";
            }
        }
        $select->setPart('where', $where);
    }
}

Do you really need in your method salesOrderGridCollectionLoadBefore the following code $collection->addFilterToMap('store_id', 'main_table.store_id');? If not remove it and try the following:

protected function _addColumnToGrid($grid)
{
....... // here you code from your post above

    $storeIdColumn = $grid->getColumn('store_id');

    if($storeIdColumn) {
        $storeIdColumn->addData(array('filter_index' => 'main_table.store_id'));
    }
}