2

I have added the special_price attribute to the catalog product grid using event observer with the following code.

Filtering works fine however sorting does not work, if anyone could help that'd be great.

NB: I'm using the core_layout_block_create_after event instead of the core_block_abstract_to_html_before event as often suggested on SE because I've got a massaction item that exports the grid to CSV. The fields added via my observer are not added to the CSV if I use core_block_abstract_to_html_before

config.xml:

<?xml version="1.0"?>
<config>
    <modules>
        <My_Module>
            <version>0.1.11</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>
                    <module_custom_register>
                        <type>singleton</type>
                        <class>module/observer</class>
                        <method>registerController</method>
                    </module_custom_register>
                </observers>
            </controller_action_predispatch_adminhtml>
            <!-- Called after creating a block -->
            <core_layout_block_create_after>
                <observers>
                    <module_custom_before_block>
                        <type>singleton</type>
                        <class>module/observer</class>
                        <method>blockCreateAfter</method>
                    </module_custom_before_block>
                </observers>
            </core_layout_block_create_after>
            <!-- Called before loading an EAV collection -->
            <eav_collection_abstract_load_before>
                <observers>
                    <module_custom_before_eav_load_collection>
                        <class>module/observer</class>
                        <method>beforeEavCollectionLoad</method>
                    </module_custom_before_eav_load_collection>
                </observers>
            </eav_collection_abstract_load_before>
        </events>
    </adminhtml>
</config>

Observer.php:

<?php
class My_Module_Model_Observer
{

    /**
     * @param Varien_Event_Observer $observer
     * @return $this
     */
    public function registerController(Varien_Event_Observer $observer)
    {
        $action = $observer->getControllerAction()->getFullActionName();
        switch ($action)
        {
            case 'adminhtml_catalog_product_grid':
            case 'adminhtml_catalog_product_index':
                Mage::register('adminhtml_catalog_product_grid', true);
                break;

        }

        return $this;
    }

/**
     * @param Varien_Event_Observer $observer
     */
    public function blockCreateAfter(Varien_Event_Observer $observer)
    {
        $block = $observer->getBlock();

        if($block instanceof Mage_Adminhtml_Block_Catalog_Product_Grid)
        {
            $store = Mage::app()->getStore((int) Mage::app()->getRequest()->getParam('store', 0));

            $block->addColumnAfter(
                'special_price',
                array(
                    'header'=> Mage::helper('catalog')->__('Sale Price'),
                    'type'  => 'price',
                    'currency_code' => $store->getBaseCurrency()->getCode(),
                    'index' => 'special_price'
                ),
                'price'
            );
        }
    }

    public function beforeEavCollectionLoad(Varien_Event_Observer $observer)
    {
        if (Mage::registry('adminhtml_catalog_product_grid'))
        {
            $collection = $observer->getCollection();
            if (!isset($collection)) {
                return;
            }

            if ($collection instanceof Mage_Catalog_Model_Resource_Product_Collection) {

                $store = Mage::app()->getStore((int) Mage::app()->getRequest()->getParam('store', 0));

                if ($store->getId())
                {
                    // Add the special price
                    $collection->joinAttribute('special_price', 'catalog_product/special_price', 'entity_id', null, 'left', $store->getId());
                }
                else {
                    // Add the special price
                    $collection->addAttributeToSelect('special_price');
                }
            }
        }
    }
}
2
  • Hi , can we do this using overwrite product grid block instead using event ?
    – Sourav
    Commented Jan 27, 2016 at 19:18
  • 1
    Yes but using observers is recommended because overwriting blocks can cause conflicts between modules Commented Jan 27, 2016 at 22:25

2 Answers 2

6

Answering my own question.

After a lot of debugging, I've found those interesting lines under the Mage_Catalog_Model_Resource_Product_Collection model:

    public function setOrder($attribute, $dir = 'desc')
    {
        if ($attribute == 'price') {
            $this->addAttributeToSort($attribute, $dir);
        } else {
            parent::setOrder($attribute, $dir);
        }
        return $this;
    }

It seems like Magento team hardcoded the way the price ordering is rendered, that's why I was getting such a different result when trying to sort by special price.

Well the only way to fix this was to override that module and change the function to this:

public function setOrder($attribute, $dir = 'desc')
{
    if ($attribute == 'price' || $attribute == "special_price") {
        $this->addAttributeToSort($attribute, $dir);
    } else {
        parent::setOrder($attribute, $dir);
    }
    return $this;
}
1
  • what if two products have same special price and price and position? In my case it doesn't sort by its entity_id then. Do you know how does it sort then?
    – Twinkal
    Commented Sep 17, 2016 at 6:46
-1

Only add this in product grid & use index sprice to display special price in your grid.

$collection->joinAttribute(
    'sprice',
    'catalog_product/special_price',
    'entity_id',
    null,
    'inner'
);
1
  • 1
    Definitely not, please re read my question I was able to add the special price I just couldn't sort it Commented Jan 27, 2016 at 22:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.