0

I want to add a new column to the "Catalog Products" grid in Magento's admin area.

The new column will be called Currently Discounted? or Sale Item? and will display "Yes" when a product's price is more than its special_price (i.e. the product is in a sale).

So far I've been able to add the special_price column to the grid, via the code below:

$collection->joinAttribute('special_price', 'catalog_product/special_price', 'entity_id', null, 'left', $store->getId());

$this->addColumn('special_price',
        array(
            'header'=> Mage::helper('catalog')->__('Special Price'),
            'type'  => 'price',
            'currency_code' => $store->getBaseCurrency()->getCode(),
            'index' => 'special_price',
    ));

But what I really need is another column which actually performs some kind of logic to compare the special_price and print "Yes" if it's discounted and "No" if it's not.

I've added the column but for now, obviously, it's empty because its index doesn't correspond to any real source of data:

$this->addColumn('is_sale_item',
    array(
        'header'=> Mage::helper('catalog')->__('Sale Item?'),
        'type'  => 'options',
        'index' => 'is_sale_item', // <--- HOW DO I POPULATE THIS INDEX?
        'options' => array( 0 => 'No', 1 => 'Yes')
));

How would I achieve this? Where would I put the logic for the "is_sale_item" calculation and make it a "real" index?

2 Answers 2

2

I managed to implement this but in a slightly hacky way. If anyone knows a better way please comment.

1. Add the custom column to the column list, with a custom renderer and a filter callback

$this->addColumn('is_sale_item',
            array(
                'header'=> Mage::helper('catalog')->__('Sale Item?'),
                'type'  => 'options',
                'index' => 'is_sale_item',
                'options' => array( "no" => 'No', "yes" => 'Yes'),
                'renderer'  => 'Mage_Adminhtml_Catalog_Product_Renderer_Sale',
                'filter_condition_callback' => array($this, '_filterIsSaleItem'),
        ));

2. Create custom renderer for the new custom attribute

I used a custom renderer to perform the logic to test whether the item has been reduced or not. Again, probably not the right way to do this. In the folder with Grid.php, create Renderer/Sale.php:

<?php
class Mage_Adminhtml_Catalog_Product_Renderer_Sale extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
    public function render(Varien_Object $row)
    {
        $_price        = $row->getData("price");
        $_specialPrice = $row->getData("special_price");
        if ($_specialPrice && $_price > $_specialPrice) {
            return "Yes";
        } else {
            return "No";
        }
    }
}
?>

3. Add the filter callback which will apply the logic when the filter is used

Back in Grid.php:

protected function _filterIsSaleItem($collection, $column)
    {   
        $value = $column->getFilter()->getValue();

        if (!$value) {
            return $this;
        }

        $store = $this->_getStore();
        $this->getCollection()->joinAttribute('price', 'catalog_product/price', 'entity_id', null, 'left', $store->getId());
        $this->getCollection()->joinAttribute('special_price', 'catalog_product/special_price', 'entity_id', null, 'left', $store->getId());

        if ($value == "yes") {
            $this->getCollection()->getSelect()->where("_table_price.value >  _table_special_price.value");
        } else {
            $this->getCollection()->getSelect()->where("_table_price.value <= _table_special_price.value OR _table_special_price.value IS NULL");
        }

        return $this;

    }
Sign up to request clarification or add additional context in comments.

Comments

2

This should help:

$this->addColumn('special_price', array(
    'header'    => Mage::helper('catalog')->__('Special Price'),
    'type'      => 'options',
    'index'     => 'special_price',
    'options' => Mage::getSingleton('eav/entity_attribute_source_boolean')->getOptionArray(),
));

@WackGet I hope you find this useful :).

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.