Posting in the Magento forums has been disabled pending the implementation of a new and improved forum solution which should better serve the community.

For new questions please post at magento.stackexchange.com, the community-run support site for the Magento community. We will be providing updates on the new forum solution soon. For questions or concerns please email community@magento.com.

Magento Forum

Page 1 of 3
How to sort “Out of Stock” products to always appear at the end of categories pages? 
 
PauloON
Jr. Member
 
Total Posts:  21
Joined:  2009-06-16
 

Hello everyone!

I need yout help, in case you have a clue on how to do this:

Challenge: Make “out of stock” products always show up at the end of every categories page.

Googling a little, I was able to hide the “out of stock” by adding this code to the file:
/public_html/app/code/core/Mage/Catalog/Block/Product/List/Toolbar.php

$this->getCollection()->joinField('stock_status','cataloginventory/stock_status','stock_status''product_id=entity_id',
array(
'stock_status' => Mage_CatalogInventory_Model_Stock_Status::STATUS_IN_STOCK'website_id' => Mage::app()->getWebsite()->getWebsiteId(), ));

But this is not exactly what I want.

Any clues?

Best regards!
Paulo.

 
Magento Community Magento Community
Magento Community
Magento Community
 
eschamann
Member
 
Total Posts:  33
Joined:  2009-11-17
São Paulo - Brazil
 

Paulo, I need the same info.

Cheers, Quique

 
Magento Community Magento Community
Magento Community
Magento Community
 
tzyganu
Mentor
 
Avatar
Total Posts:  2205
Joined:  2009-11-18
Bucharest, Romania
 

Here is what I did:
I added this code:

$this->getSelect()->joinLeft(
                array(
'_inventory_table'=>$this->getTable('cataloginventory/stock_item')),
                
"_inventory_table.product_id = e.entity_id",
                array(
'is_in_stock''manage_stock')
            );
            
$this->addExpressionAttributeToSelect('on_top',
            
'(CASE WHEN (((_inventory_table.use_config_manage_stock = 1) AND (_inventory_table.is_in_stock = 1)) OR  ((_inventory_table.use_config_manage_stock = 0) AND (1 - _inventory_table.manage_stock + _inventory_table.is_in_stock >= 1))) THEN 1 ELSE 0 END)',
             array());
            
$this->getSelect()->order('on_top DESC');
in Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection class setOrder method right before
if ($attribute == 'price' && $storeId != 0{

I don’t know how it acts with configurable products (I don’t have any in my website). And I’m using Magento 1.1.6. I tested it on 1.3.x and it does not give an error but I’m not sure if it works properly. If someone tries it please post here the result.

PS. I already posted this solution a few months ago but the admins of this forum decided to delete my account “by mistake”. Bad, bad admins.

 
Magento Community Magento Community
Magento Community
Magento Community
 
tzyganu
Mentor
 
Avatar
Total Posts:  2205
Joined:  2009-11-18
Bucharest, Romania
 

I just realized something.
It doesn’t work for bundle products with mandatory bundle items, when all the bundle items are out of stock and the main bundle product is in stock.
If someone finds a solution for this please post it here.

 
Magento Community Magento Community
Magento Community
Magento Community
 
The Sunday Paper
Sr. Member
 
Total Posts:  202
Joined:  2008-08-06
 

Won’t this modification be overwritten in any future Magento updates, though?

 
Magento Community Magento Community
Magento Community
Magento Community
 
tzyganu
Mentor
 
Avatar
Total Posts:  2205
Joined:  2009-11-18
Bucharest, Romania
 

Not if you properly overwrite the Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection model (I think : ) )

 
Magento Community Magento Community
Magento Community
Magento Community
 
PauloON
Jr. Member
 
Total Posts:  21
Joined:  2009-06-16
 

That’s great, thanks! Worked perfectly for me.

tzyganu - 15 February 2010 04:25 AM

I just realized something.
It doesn’t work for bundle products with mandatory bundle items, when all the bundle items are out of stock and the main bundle product is in stock.
If someone finds a solution for this please post it here.

I also get this same behaviour with configurable products.
I would appreciate if someone could give us a clue for a solution.

Best regards,
Paulo.

 
Magento Community Magento Community
Magento Community
Magento Community
 
The Sunday Paper
Sr. Member
 
Total Posts:  202
Joined:  2008-08-06
 

tzyganu, when you say “properly overwrite\” the file — and forgive me for asking you to spell this out — do you literally mean overwriting the file with the changes and uploading the changed file to the server? Or does this need to go somewhere in app/local?

Thanks for your help. The change definitely works, and I’m hoping I can protect it from updates and push it live!

 
Magento Community Magento Community
Magento Community
Magento Community
 
tzyganu
Mentor
 
Avatar
Total Posts:  2205
Joined:  2009-11-18
Bucharest, Romania
 

It means that the model/helper/block goes into the app/local.
As shown here http://magedev.com/2009/06/03/magento-overriding-model-block-or-helper/

 
Magento Community Magento Community
Magento Community
Magento Community
 
PauloON
Jr. Member
 
Total Posts:  21
Joined:  2009-06-16
 

Hello “Sunday”,

I’m not sure about that (Tzyganu maybe can confirm), but I’ll give it a try.

Inside “/app” directory there are 3 folders: “community”, “core” and “local”.
If you make changes to files inside “core”, it’s possible that they get overwritten on a upgrade.
In order for that NOT to happen, you have to replicate the same directory structure from “core” to the “local” folder, and put a copy of your modified file there.
Magento reads the file from this folder instead, and it is not touched on an possible upgrade.

I actually don’t do that, but that’s the information I have.
If I’m wrong, someone please correct me.

Best regards,
Paulo.

 
Magento Community Magento Community
Magento Community
Magento Community
 
The Sunday Paper
Sr. Member
 
Total Posts:  202
Joined:  2008-08-06
 

I see that I have to set up a bunch of files to tell Magento to look in the local folder for a custom version of Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection. But I don’t see where the actual changed code is supposed to go.

 
Magento Community Magento Community
Magento Community
Magento Community
 
PauloON
Jr. Member
 
Total Posts:  21
Joined:  2009-06-16
 

It’s not just the “changed code” that’s supposed to be saved there, it’s the whole copy of the modified “collection.php” file.

So, instead of:
App_Code_CORE_Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection.php

It will stay at:
App_Code_LOCAL_Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection.php

Regards!
Paulo.

 
Magento Community Magento Community
Magento Community
Magento Community
 
tzyganu
Mentor
 
Avatar
Total Posts:  2205
Joined:  2009-11-18
Bucharest, Romania
 

Inside the model you create in your local folder.
The model you create extends the ‘core’ model, so all the methods in the core model are available in your newly created model (OOP principle) and you just overwrite the method you need.

 
Magento Community Magento Community
Magento Community
Magento Community
 
factorymediaweb
Jr. Member
 
Total Posts:  15
Joined:  2008-11-10
 

Hello, yesterday i did this modification at “local” folder (not in core folder) and refreshed cache and all the things seemed to go ok.
But today my main store shows:

You cannot define a correlation name '_inventory_table' more than once
Trace
:
#0 /var/www/vhosts/xxx/httpdocs/lib/Zend/Db/Select.php(315): Zend_Db_Select->_join('left join', Array, '_inventory_tabl...', Array, NULL)
#1 /var/www/vhosts/xxx/httpdocs/app/code/local/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php(1137): Zend_Db_Select->joinLeft(Array, '_inventory_tabl...', Array)

Can anybody help?
In the meanwhile i’m going to deactivate the “local” Collection.php so my main store is ok again.
Thanks to all

 
Magento Community Magento Community
Magento Community
Magento Community
 
PauloON
Jr. Member
 
Total Posts:  21
Joined:  2009-06-16
 

Factory,

I’m not an expert, but in my case I’ve put the suggested code inside the followin “if”, and it worked:

if ( ( $attribute == ‘name’ || $attribute == ‘price’ || $attribute == ‘random’ || $attribute == ‘creation_date’ || $attribute == ‘position’ )) {

....

}

The “name”, “price”, “random”, “creation_date” and “position” are the names of my sorting attributes.

So, the final code is:

if ( ( $attribute == 'name' || $attribute == 'price' || $attribute == 'random' || $attribute == 'creation_date' || $attribute == 'position' )) {

           $this
->getSelect()->joinLeft(
                array(
'_inventory_table'=>$this->getTable('cataloginventory/stock_item')),
                
"_inventory_table.product_id = e.entity_id",
                array(
'is_in_stock''manage_stock')
            );

            
$this->addExpressionAttributeToSelect('on_top',
            
'(CASE WHEN (((_inventory_table.use_config_manage_stock = 1) AND (_inventory_table.is_in_stock = 1)) OR  ((_inventory_table.use_config_manage_stock = 0) AND (1 - _inventory_table.manage_stock + _inventory_table.is_in_stock >= 1))) THEN 1 ELSE 0 END)',
             array());

            
$this->getSelect()->order('on_top DESC');
}

Hope it helps.

Best regards,
Paulo.

 
Magento Community Magento Community
Magento Community
Magento Community
 
pighead
Jr. Member
 
Total Posts:  9
Joined:  2009-05-05
 

I tried the code, and I am sure the code has overwritten the class exactly. However, I still see ‘Out of Stock’ product listed in front of the category page. Doesn’t work for me.  I am using 1.3.2.3, any ideas?

 
Magento Community Magento Community
Magento Community
Magento Community
Magento Community
Magento Community
Back to top
Page 1 of 3