Home > Magento, Programming > Hiding “Out of Stock” Items in Magento

Hiding “Out of Stock” Items in Magento

Updated 7/14/09

This module has been replaced with one that correctly updates the layered navigation counts. See the new version here.

Updated 7/3/09

The in-stock-only module now works properly when multiple websites are in use.

Updated 6/26/09

The in-stock-only module now works with configurable products.

 

Magento has several criteria for determining if an item should be visible in the store, but one of these is not whether or not the item is in stock. Magento can manage your stock and will set your stock status to “Out of Stock” for you, but what if you want these out of stock items to be hidden from the store.. automatically? Also, in my case I do not want to “disable” the item because the inventory management system will then ignore it. Turns out this was much more difficult to figure out than I expected it to be but the end solution was quite simple.

To hide all out of stock items from Magento’s storefront we are going to create a local module and call it “Lucky_InStockOnly”. This will be a very simple module, so get ready to copy and paste.

Every module needs a config file. Ours is very basic, here it is:

app/code/local/Lucky/InStockOnly/etc/config.xml

<?xml version="1.0"?>
<config>

<global>
  <models>
    <lucky_instockonly>
      <class>Lucky_InStockOnly_Model</class>
    </lucky_instockonly>
  </models>
</global>

<frontend>
  <events>
    <catalog_block_product_list_collection>
      <observers>
        <lucky_instockonly_list>
          <type>singleton</type>
          <class>lucky_instockonly/observer</class>
          <method>addInStockOnlyFilter</method>
        </lucky_instockonly_list>
      </observers>
    </catalog_block_product_list_collection>
  </events>
</frontend>

</config>

As you can see, we declare an event for the frontend that observes the “catalog_block_product_list_collection” event which is dispatched in Mage_Catalog_Block_Product_List in the _beforeToHtml() method. This _beforeToHtml method is called before the corresponding template code is loaded, and the next line after the dispatchEvent loads the collection at which point it is too late to add any further filters, so we’re just in time.

Next, we add the observer code:

app/code/local/Lucky/InStockOnly/Model/Observer.php

<?php

class Lucky_InStockOnly_Model_Observer {

  /**
   * Observes the catalog_block_product_list_collection event
   */
  public function addInStockOnlyFilter($observer){
    $observer->getEvent()->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(),
        ))
    ;
  }
}

That’s it! That’s it? Like all things Magento, easy for a veteran, not so easy for anyone else; hence, this blog post. All that is left is to enable our module and we’re off!

app/etc/modules/Lucky_InStockOnly.xml

<config>
  <modules>
    <Lucky_InStockOnly>
      <active>true</active>
      <codePool>local</codePool>
    </Lucky_InStockOnly>
  </modules>
</config>

Last thing, you need to refresh your configuration cache so Magento will notice the new module. In the admin backend you can do that under System > Cache Management.

Enjoy!

Magento, Programming ,

  • jcnh74

    Wow! How simple. The more I learn about Magento the more I love it. Thanks for the post. It really helped! http://dwskatesurf.com

  • mariatrier

    Great job! But what do I do if I want Magento automatically to hide a configurable product, when a product is out of stock? As you know a configurable product can be “in stock” while it is not actually saleable… It is precisely here the big problem with configurable products are … I hope you can help me on this matter as it really gives me grey hair :-)

  • http://colin.mollenhour.com colin

    Unfortunately I have no experience yet with configurable products. However, a little digging around reveals that catalog_product_super_link is the table that contains the parent_ids of products and catalog/product_type_configurable is the name of the resource model. Perhaps a join on that table with a group_by and another where clause would do the trick… For reference, here is the query generated on my site with the InStockOnly module. Are you wanting to hide a configurable product only when *all* options are out of stock? I have found that with these complex queries it is easiest to play with the SQL directly first, then convert it to proper Magento code once you get the query working.

  • mariatrier

    Hi there,
    Would you be able to take time to solve it? I would gladly pay you an amount, so that I can get this problem fixed. Take a look at http://www.trier.dk under “Nye varer 01”. Go to the bottom of the catalog on page 2. Here you see the problem. It hides out of stock single products very well, but not the configurable products, therefore you see that there – in a category with 30 items and 20 per page, a page with 5 sold out items will only display 15 items. You understand? I have no idea, where to make the changes to have only In-Stock and salable products shown in the product list.

  • http://colin.mollenhour.com colin

    The code has been updated to work correctly with configurable products.

  • http://colin.mollenhour.com colin

    The code has been updated again to work properly with multiple websites.

  • http://colin.mollenhour.com/2009/07/hiding-out-of-stock-items-in-layered-navigation/ Colin Mollenhour’s Technical Blog » Hiding “Out of Stock” items in Layered Navigation

    […] previous post about “Hiding Out of Stock Items in Magento” had one pretty major downfall, in that it did not handle the product counts in the layered […]

  • itosasia

    This is a great tip. But, i’m having a slight problem.

    In my search result this module implement hides the products out of stock but the total product count is still showing the full products.

  • http://colin.mollenhour.com colin

    @itosasia
    See the latest revision here.

  • http://www.gxjansen.com Guido Jansen

    Great, thanks for sharing!

  • http://www.2value.nl hans2103

    Although I prefer to see if an item is out of stock, this option should be in the core of Magento.

  • http://colin.mollenhour.com Colin Mollenhour

    Agreed, but actually, as of 1.4.1.1 it is in the core.

  • http://www.2value.nl hans2103

    How stupid of me… I should haven known that.

    Hide out of stock message is indeed a configurable item
    Admin >> System >> Configuration >> Catalog >> Inventory >> Stock Options
    Display Out of Stock product -> No

  • Arne

    works great, thanks!

  • Tanay Jha

    Thanks a lot! After wasting almost 5 hours here and there I found this and it helped to get what I was looking for. I wanted to display the no. of in Stock products in front of each category and subcategory menu items.

    Thanks again!

  • Gerdus Bronn

    I need items to show out of stock when they reach qty 0 and not show up on the frontend of my magento store but I need them to be still available for me to sell on the backend via a POS system in my physical store. I am struggling with this. Can you do some custom work for me Colin?