isSaleable()和isAvailable()有什么区别?

时间:2012-01-27 19:33:39

标签: magento product stock

我正在Magento主题的(个人)产品页面上显示库存可用性,而且我对此并不完全了解。

我看到模板中使用了两种方法来检查产品是否可供销售:

Mage_Catalog_Model_Product::isAvailable()
Mage_Catalog_Model_Product::isSaleable()

我自己的发现:
我看到isSalable()isSaleable()调用)调用isAvailable(),但也会调度两个事件(catalog_product_is_salable_beforecatalog_product_is_salable_after)。

在前面我注意到在Magento的基础模板isAvailable()用于决定是否将产品显示为“库存”或“缺货”; isSaleable()用于决定是否显示“添加到购物车”按钮。

在后端,我注意到当库存数量变为零并且缺货时,产品的库存可用性变为“缺货”。 当库存数量变为零且允许延迟交货 时,产品的库存可用性保持不变。

问题:
“库存可用性”和“库存数量”属性显然是相互关联的,并且提到了PHP方法。我想知道:

  • PHP方法isAvailable()和之间的语义区别是什么 isSaleable()是我为什么要使用其中一个;

  • 我似乎还不知道他们与这些属性的关系以及Magento的行为。

谢谢。

修改
我已经尝试了产品的库存数量(-1,0,1),库存可用性(进/出)和缺货(开/关)的每个相关组合,结果如下:

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

为了完整起见:

St.Av 0  = out of stock
St.Av 1  = in stock
BckOrd 0 = no backorders allowed
BckOrd 1 = backorders are allowed

Magento中的库存可用性开关控制所有PHP方法的返回值,但是当缺货停止且库存数量低于1时,库存可用性将自动重置为“缺货”(因此N/A行。

5 个答案:

答案 0 :(得分:3)

isSaleable() 在使用Magento模板时,你肯定偶然发现了应用于产品对象的isSalable()方法。该方法实际存在,但它仅检查产品是否已启用状态,并且不应跳过可销售检查。然后返回产品对象的is_salable属性。

显而易见的问题是何时设置此属性。加载产品后,它已在模型上设置,但它不是属性,也不是产品平台中的列。

像往常一样,Magento中所有奇怪的东西都是由观察者完成的。 Mage_Cataloginventory正在观察catalog_product_load_after事件,然后归结为Mage_CatalogInventory_Model_Resource_Stock_Status::getProductStatus以及以下查询:

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;

很明显,在重新索引期间,决定产品是否可销售。而忽略了stock_id,这是一种未完成的功能,也会在以后出现。

所以我们最终会在一个没有理智的地方结束Magento的开发人员愿意去...索引器。我们的目录库存索引器。快速浏览Mage_CatalogInventory_Model_Indexer_Stock::_processEventMage_Index_Model_Indexer_Abstract::reindexAllMage_CatalogInventory_Model_Resource_Indexer_Stock::reindexAll迷宫后,我们发现每种产品类型都有自己的股票索引器,位于app/code/core/Mage/CatalogInventory/Model/Resource/Indexer/Stock

每种类型都有_getStockStatusSelect方法,其中SQL查询最终决定产品是否可销售。即使查询看起来很大,但背后的逻辑并不复杂。

这里代码的重要部分又是这个基本的东西。似乎核心开发人员做了很好的尝试,允许不同的网站有不同的库存水平,但由于某种原因,这个功能从未完成。

因此,例如,对简单产品库存可用性的检查仅包含验证产品是否已启用且数量是否为库存管理标记的正数。可配置和分组产品的查询因产品类型细节而有所不同。

答案 1 :(得分:1)

如果我没记错的话,这些支票的区别与所下订单产品的保留有关。当客户将产品添加到订单中时,这些产品仍将在您的库存中,因此它们仍然可用。不过,由于其他客户已经订购了它们,因此它们无法出售。

所以语义上的区别是:

  • 可售方式:有现货,尚未被其他客户订购
  • 可用表示:有现货,但由另一位客户订购,因此可用,但不可出售。

您可以尝试通过订购产品来验证这一点。并执行与您已经执行的相同的检查。这将导致可用产品数量与可销售产品数量之间的差异。

编辑: 这里有更多信息:

https://blog.magestore.com/magento-multi-source-inventory-msi/#a3

答案 2 :(得分:0)

class _MyWidgetState extends State<MyWidget> { @override Widget build(BuildContext context) { return ClipPath( clipper: TriangleClipper(), child: Container( padding: EdgeInsets.fromLTRB(20, 30, 20, 20), //extra 10 for top padding because triangle's height = 10 decoration: BoxDecoration( color: Colors.green, borderRadius: BorderRadius.circular(10), ), child: Text('My parent is a fancy container'), ), ); } } class TriangleClipper extends CustomClipper<Path> { double radius = 10, tw = 20, th = 10; //tw & th = triangle width & height @override Path getClip(Size size) { final path = Path(); path.lineTo(0, size.height); path.lineTo(size.width, size.height); path.lineTo(size.width, th + radius); path.arcToPoint(Offset(size.width - radius, th), radius: Radius.circular(radius), clockwise: false); path.lineTo(radius + 10 + tw, th); path.lineTo(radius + 10 + tw/2, 0); //in these lines, the 10 is to have a space of 10 between the top-left corner curve and the triangle path.lineTo(radius + 10, th); path.lineTo(radius, th); path.arcToPoint(Offset(0, th + radius), radius: Radius.circular(radius), clockwise: false); return path; } @override bool shouldReclip(TriangleClipper oldClipper) => false; } 似乎正在检查它是否达到0

isSeable()似乎在计数

答案 3 :(得分:-1)

我看到那些有语义差异的人。如果所述项目设置为允许延期交货,则无库存的商品仍可销售。

据我所知,看起来isAvailable检查产品类型实例,看看产品类型是否可以出售,如果它确实可用。

所以,想一想你何时可以选择其中一个:

如果您要检查某个产品以查看该产品是否已准备好销售,则应使用isSalable(),因为它会调用isAvailable()

要检查是否可以销售产品(您手边不知道的类型),并且我想跳过检查产品类型的步骤,您可以在产品上调用isAvailable()

isAvailable()检查产品的类型是否可销售。

isSalable()检查产品是否可销售。

isSaleable()isSalable()的别名。

答案 4 :(得分:-4)

就我而言,isSaleable()意味着您正在检查可以出售的最顶级产品。虽然,isAvailable()表示您正在从可用的列表中检查产品。