Magento – Magento sort using percentage discount

sorting

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

Best Answer

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.