0

I am new to magento, please tell me How can I add a sorting option to my product listing page which will automatically calculate percentage discount using Special Price and Original Price and will sort according to the discount percentage

5

First add a dummy attribute called 'discount_percent' and make it "used for sorting" (just as Giuseppe said in the other answer).
It's not important what type it is or what values it has.
it's easier that way. If you don't want to add the attribute you have to rewrite the method Mage_Catalog_Model_Config::getAttributeUsedForSortByArray to include your attribute. I would rather avoid rewrites as much as possible. Now you need to tell magento to take a special action when the sorting is done by that attribute.
For this you have to rewrite (I don't know other way) the method Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSort()
You will need a new module for that. let's call it Easylife_Sorting.
Here are the files.

app/etc/module/Easylife_Sorting.xml - the declaration file

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Sorting>
            <codePool>local</codePool>
            <active>true</active>
            <depends>
                <Mage_Catalog />
            </depends>
        </Easylife_Sorting>
    </modules>
</config>

app/code/local/Easylife/Sorting/etc/config.xml - the configuration file

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Sorting>
            <version>1.0.0</version>
        </Easylife_Sorting>
    </modules>
    <global>
        <models>
            <catalog_resource>
                <rewrite>
                    <product_collection>Easylife_Sorting_Model_Resource_Product_Collection</product_collection>
                </rewrite>
            </catalog_resource>
        </models>
    </global>
</config>

app/code/local/Easylife/Sorting/Model/Resource/Product/Collection.php - your class override. Here is where the magic happens.

class Easylife_Sorting_Model_Resource_Product_Collection
    extends Mage_Catalog_Model_Resource_Product_Collection {
    public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC){
        //don't screw up the admin sorting
        if (Mage::app()->getStore()->getId() == Mage_Core_Model_App::ADMIN_STORE_ID){
            return parent::addAttributeToSort($attribute, $dir);
        }
        if ($attribute == 'discount_percent') {
            //determine the discount percent value
            $this->addExpressionAttributeToSelect('discount_percent_value', '(({{price}} - final_price) / {{price}})', array('price'));
            //sort by the discount percent value
            $sortDir = $dir;
            //in case you need to reverse the order so when you sort ascending you will see the most discounts first do this:
            //if not then remove the if-else statement below.
            if ($sortDir == self::SORT_ORDER_ASC) {
                $sortDir = self::SORT_ORDER_DESC;
            }
            else {
                $sortDir = self::SORT_ORDER_ASC;
            }
            $this->getSelect()->order(array('discount_percent_value '.$sortDir));
            return $this;
        }
        //otherwise do nothing special
        return parent::addAttributeToSort($attribute, $dir);
    }
}

This works for sure for simple/virtual/downloadable products. I have no idea what effect has on configurable/bundle and grouped products.

1
  • I'm guessing for configurable products it'll just use the default price. Not sure about bundle
    – Alex M
    Jul 27 '17 at 8:53
1

it is not an easy task if you are new to magento !

You should add an attribute "discount_percent" and let it be usable for sorting.

Then you have two option. 1) when you change price manually calculate and set the discount_percent value

2) write a module that listen to the "product_before_save" event and calculate and update the discount_percent value.

0

Here my solution for SORT products collection by BEST DISCOUNT

$today = date('Y-m-d',time());
        $collection = Mage::getModel('catalog/product')->getCollection();
        $collection->addAttributeToSelect('*')
            ->addAttributeToFilter('special_price',array('is' => new Zend_Db_Expr('not null')))
            ->addAttributeToFilter('special_from_date', array('or'=> array(
                0 => array('date' => true, 'to' => $today),
                1 => array('is' => new Zend_Db_Expr('null')))
            ), 'left')
            ->addAttributeToFilter('special_to_date', array('or'=> array(
                0 => array('date' => true, 'from' => $today),
                1 => array('is' => new Zend_Db_Expr('null')))
            ), 'left')
            ->addAttributeToFilter(
                array(
                    array('attribute' => 'special_from_date', 'is'=>new Zend_Db_Expr('not null')),
                    array('attribute' => 'special_to_date', 'is'=>new Zend_Db_Expr('not null'))
                )
            )
            ->addMinimalPrice()
            ->addTaxPercents()
            ->addStoreFilter();


        $collection->addAttributeToFilter('status', 1);
        $collection->addAttributeToSelect('*');

and add ORDER by discount

$collection->getSelect()->columns(array('discount_different'=>'(`e`.`price` - `e`.`special_price`)'))->order(array('discount_different DESC'))->group('e.entity_id');

Also can try this

$collection->addExpressionAttributeToSelect(
                    'discount_value',
                    '({{price}} - price_index.final_price)',
                    array('price'));
0

Here is my solution that worked for simple and grouped products

if ($attribute == 'discount_percent') {
        $sortDir = $dir;
        /*if ($sortDir == self::SORT_ORDER_ASC) {
            $sortDir = self::SORT_ORDER_DESC;
        }
        else {
            $sortDir = self::SORT_ORDER_ASC;
        }*/

        $this->getSelect()->joinLeft(
            array('related' => 'catalog_product_relation'),
            'related.parent_id = e.entity_id',
            array()
        )
        ->joinLeft(
            array('status' => 'catalog_product_entity_int'),
            'status.entity_id = related.child_id and status.attribute_id = 96 and status.store_id = 0 ',
            array()
        )
        ->joinLeft(
            array('related_price' => 'catalog_product_index_price'),
            'related.child_id = related_price.entity_id and price_index.website_id = related_price.website_id '
                . 'AND price_index.customer_group_id = related_price.customer_group_id ',
            array()
        )
        ->where('status.value = '.Mage_Catalog_Model_Product_Status::STATUS_ENABLED.' or status.value is null')
        ->columns(array(
            'discount_percent_value' => new Zend_Db_Expr('GREATEST(COALESCE(((price_index.price - price_index.final_price) / price_index.price),0), COALESCE(((related_price.price - related_price.final_price) / related_price.price), 0))'),
        ))
        ->order(array('discount_percent_value '.$sortDir))
        ->group(array(
            'e.entity_id'
        ));

        return $this;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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