filtering product collection on "is_salable"
Asked Answered
W

3

14

I would like to filter a product collection to show only items that are in stock. I thought this would be easy given that there's an attribute called 'is_salable' that is 1 (true) if it's in stock, 0 (false) if not. But no matter what I do, it doesn't work. Further, it seems to halt the execution of the query before it finishes.

Here's some sample code:

$this->_productCollection = Mage::getModel('catalog/product')->getCollection();
$this->_productCollection->addAttributeToSelect('*');
$this->_productCollection->addAttributeToFilter('my_attribute', true);
//So far, so good...filtering on 'my_attribute' works!
Mage::Log("select: " . $this->_productCollection->getSelect());
//Successfully outputs the SQL query
$this->_productCollection->addFieldToFilter('is_salable', '1');
Mage::Log("select: " . $this->_productCollection->getSelect());
//does NOT output any query...it's like it died trying

So what am I doing wrong? I've tried 'addFieldToFilter', 'addAttributeToFilter', and miscellaneous other queries, such as: addFieldToFilter('is_salable', array('eq' => true)), etc...

Anyone know how to do this? If 'is_salable' is not the answer, all I need to do is filter out products that are not in stock...so whatever works to do that would be fine :)

Thanks!

Weimaraner answered 14/3, 2011 at 17:4 Comment(3)
Quick tip: Sometimes a select object cannot be dumped correctly, at least not without running out of memory. Casting it to string is more reliable... (string)$this->getProductCollection()->getSelect()Prolactin
The __toString() method will automatically be called when concatenating with a string (since PHP 5.2, see the docs)Triglyceride
@jongosi actually the function name is isSalable as defined in Mage_Catalog_Model_Product so your comment is incorrect.Marek
I
45

There is no is_salable attribute in the product so it will rise an exception. If you want to display only products that are in stock, use this stock model addInStockFilterToCollection method:

Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($this->_productCollection);
Injure answered 14/3, 2011 at 18:25 Comment(4)
Thanks, @ivan-chepurnyi! That worked great! However, I'm still a bit confused. If I loop through the products in the collection and print out each one, the product contains an 'attribute' called 'is_salable'. Is that a generated element that can't be filtered on? Is that why it's different than other filterable attributes?Weimaraner
Checkout at the isSalable() funciton on Mage_Catalog_Model_Product. A lot of times regular ol' attributes don't have a specific method. In this case looks like it calls the isSalable() function on yet another class, Mage_Catalog_Model_Product_Type_Simple (or Mage_Catalog_Model_Product_Type_Grouped or Mage_Catalog_Model_Product_Type_Configurable depending on the product type)Swanhilda
@BrianVPS is_salable property in product list is an indexed value of possible isSalable method call. The result of isSalable method call can be different depends on product type and logic defined in Mage_CatalogInventory module observers. Also it may be different from the actual method call, if during the custom module development, the appropriate indexes wasn't customized as well.Injure
Thanks Ivan, I'm new to SO so don't know the protocol :) I appreciate all your help!Weimaraner
E
0

try this as well...

$stockCollection = Mage::getModel('cataloginventory/stock_item')->getCollection()->addFieldToFilter('qty', array('gteq' => 1))->addFieldToFilter('type_id', 'simple');

addFieldFilter ('qty',array('gteq' =>1))

get all products collection that have a stock of 1 or greater, you can put any number here according to your needs

addFieldToFilter('type_id', 'simple')

filter by simple products

Ethiopia answered 15/3, 2011 at 13:33 Comment(1)
This solution will not work in case that you're not managing your stock levels in Magento and use just in/out of stock flags as you dont need to specify the quantity to have the product visible on frontend.Apothem
B
0

I stumbled upon the problem that isSaleable() always returns false on my products, the problem was that I was getting the collection but didn't add the attribute price to the collection. In the isSaleable() function there is a check to make sure the price isn't 0, it needs the price attribute to check that so:

Changing:

$collection = Mage::getModel('catalog/product')->getCollection();
        $collection->addAttributeToSelect('name')
                ->addAttributeToSelect('image')
                ->addAttributeToSelect('url_path')
                ->addAttributeToSelect('status')
                ->addUrlRewrite();

To:

$collection = Mage::getModel('catalog/product')->getCollection();
        $collection->addAttributeToSelect('name')
                ->addAttributeToSelect('image')
                ->addAttributeToSelect('price')
                ->addAttributeToSelect('url_path')
                ->addAttributeToSelect('status')
                ->addUrlRewrite();

Did the trick :)

Bolme answered 26/5, 2014 at 8:53 Comment(1)
What about out of stock products? Their price is not zero, yet they are not saleable.Frock

© 2022 - 2024 — McMap. All rights reserved.