4

We have to display all In stock products in starting position even if we sort by name or any other criteria, we have to display out of stock product in last position.

How can we do this in all type of listing pages?

2
4

The following solution works for ce version 1.6+. For versions before that refer to http://stackoverflow.com/a/24239602/2047249 (but the solution in the link may not work for composite products).

You need to rewrite the Mage_Catalog_Model_Resource_Product_Collection class.
For this create a new module. Let's call it Easylife_Sorting.
You will need the following 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 where we declare the class rewrite

<?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 - the rewrite of the product collection class

<?php
class Easylife_Sorting_Model_Resource_Product_Collection
    extends Mage_Catalog_Model_Resource_Product_Collection 
{
    public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC)
    {
        //if on the admin side, use the default behavior.
        //we don't to screw up the admin sorting
        if (Mage::app()->getStore()->getId() == Mage_Core_Model_App::ADMIN_STORE_ID){
            return parent::addAttributeToSort($attribute, $dir);
        }
        //add the stock status to the collection
        Mage::getModel('cataloginventory/stock_status')->addStockStatusToSelect($this->getSelect(), Mage::app()->getWebsite());
        //sort by the stock status descending
        $this->getSelect()->order('salable DESC');
        //sort by the requested attribute
        return parent::addAttributeToSort($attribute, $dir);
    }
}

Clear the cache and poof. You have the out of stock products at the end of the list.
In order for this to work you need to have the stock index up to date.

Improvement: You can even add a config setting to show out of stock products last and wrap the custom code in an if statement. This way you can disable it easily.

Side note: The decision to ALWAYS show the out of stock products last is a bad one at least for the user experience. When I sort a list by price I want to see it by price even if the product is out of stock. If I really want that out of stock product I will subscribe to the stock alert or I will bug you with emails to get it back in stock.
But if you show it last in the list I may not see it at all and go do my shopping somewhere else.
It makes sense to show out of stock products last when sorting by position in category or by relevance in the search.

If my advice makes sense, then you need to modify the class above to look like this:

<?php
class Easylife_Sorting_Model_Resource_Product_Collection
    extends Mage_Catalog_Model_Resource_Product_Collection 
{
    public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC)
    {
        //if one admin use the default behavior.
        //we don't to screw up the admin sorting
        if (Mage::app()->getStore()->getId() == Mage_Core_Model_App::ADMIN_STORE_ID){
            return parent::addAttributeToSort($attribute, $dir);
        }
        if ($attribute == 'position') {
            //add the stock status to the collection
            Mage::getModel('cataloginventory/stock_status')->addStockStatusToSelect($this->getSelect(), Mage::app()->getWebsite());
            //sort by the stock status descending
            $this->getSelect()->order('salable DESC');
        }
        //sort by the requested attribute
        return parent::addAttributeToSort($attribute, $dir);
    }
} 
0

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.