问题
I'm working on the display of the stock availability on the (individual) product page of my Magento theme, and there's something I don't completely understand about this.
I see two methods being used in the templates to check whether a product is available for sale:
Mage_Catalog_Model_Product::isAvailable()
Mage_Catalog_Model_Product::isSaleable()
My own findings:
I see that isSalable()
(which in turn is called by isSaleable()
) calls isAvailable()
but also dispatches two events (catalog_product_is_salable_before
and catalog_product_is_salable_after
).
On the fronted I've noticed that in Magento's base template isAvailable()
is used to decide whether to display the product as "in stock" or "out of stock"; isSaleable()
is used to decide something like whether to show an "Add to Cart" button.
On the backend I've noticed that when the stock quantity becomes zero and backorders are not allowed, the stock availability of a product goes to "out of stock". When the stock quantity becomes zero and backorders are allowed, the stock availability a of product remains unchanged.
Question:
The properties "stock availability" and "stock quantity" are obviously linked with each other and the mentioned PHP methods. I would like to know:
what the semantic difference between the PHP methods
isAvailable()
andisSaleable()
is and why I would use one over the other;what it is I appear not yet to know about their relation with these properties and Magento's behaviour.
Thank you.
EDIT:
I've tried every relevant combination of stock quantity (-1,0,1), stock availability (in/out of) and backorders (on/off) for a product, and this is the result:
St.Qu BckOrd St.Av isSalable() isSaleable() isAvailable() -1 0 0 0 0 0 -1 0 1 N/A N/A N/A -1 1 0 0 0 0 -1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 N/A N/A N/A 0 1 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1
Just for the sake of completeness:
St.Av 0 = out of stock St.Av 1 = in stock BckOrd 0 = no backorders allowed BckOrd 1 = backorders are allowed
It is the stock availability switch in Magento that controls the return value of all of the PHP methods, but when backorders are off and stock quantity drops below 1, the stock availability will automatically be reset to 'out of stock' (hence the N/A
rows).
回答1:
isSaleable()
While working with Magento templates you definitely stumbled upon isSalable() method applied to product object. The method physically exists but it only checks if product has enabled status and salable check should not be skipped. Then the is_salable
property of the product object is returned.
The obvious question is when this property is set. After product is loaded it is already set on model but it is not an attribute and is not a column in product flat table.
As usual, all the bizarre stuff in Magento is done by observers. Mage_Cataloginventory
is observing catalog_product_load_after event and there it comes down to Mage_CatalogInventory_Model_Resource_Stock_Status::getProductStatus
and the following query:
SELECT `cataloginventory_stock_status`.`product_id`,
`cataloginventory_stock_status`.`stock_status`
FROM `cataloginventory_stock_status`
WHERE product_id IN('241319')
AND stock_id=1
AND website_id=3;
It is clearly visible that the decision if product is salable or not is made during reindexing. And disregard stock_id which is sort of unfinished functionality which will also pop out later.
So we are ending up in a place no sane Magento developer will willingly go .. the indexer. Catalog inventory indexer in our case. After quick travel through the maze of Mage_CatalogInventory_Model_Indexer_Stock::_processEvent
, Mage_Index_Model_Indexer_Abstract::reindexAll
and Mage_CatalogInventory_Model_Resource_Indexer_Stock::reindexAll
we discover that each product type has it’s own stock indexer which resides in app/code/core/Mage/CatalogInventory/Model/Resource/Indexer/Stock
.
Each type has a _getStockStatusSelect
method where an SQL query finally decides if the product is in salable or not. Even though the query may seem massive the logic behind is not complicated.
The big part of code here is again this rudimentary stuff. Seems like core developers made a fine attempt to allow having different stock levels for different websites but for some reason this functionality was never finished.
So for instance the check of simple products stock availability only contains of verifying that product is enabled and quantity is positive spiced with a stock management flags. Queries for configurable and grouped products varies a bit due to product type specifics.
回答2:
I see those having semantic differences. An item that is not in stock can still be saleable if said item is set to allow backorders.
As far as I can tell, it looks like isAvailable
checks a product type instance to see if the product type could be for sale if it is indeed available.
So, to venture a guess at when you might choose one over the other:
If you are checking an individual product to see if said product is actually ready for sale, you should use isSalable()
, as it will call isAvailable()
.
To check if a product (whose type you don't know off hand) could be sold, and I suppose skipping the step of checking the product's type, you could call isAvailable()
on the product.
isAvailable()
checks if a product's type is salable.
isSalable()
checks if a product is salable.
isSaleable()
is an alias of isSalable()
.
回答3:
As far as my concern, isSaleable()
means you are checking the top most product that is ready for sale. While, isAvailable()
means you are checking the product from the lists that is available.
回答4:
isAvailable() is used to decide whether to display the product as in stock or out of stock, while isSaleable() is used to decide whether to show an Add to cart button or not.
来源:https://stackoverflow.com/questions/9038988/what-is-the-difference-between-issaleable-and-isavailable