我们都知道,Magento以一种直接的方式处理产品库存。数据库中只有一个“warehouse”,一个库存,一个“number”负责最终决定权 - 库存的数量。其他大部分功能依赖于全局库存。如果我们从产品管理中检查“Advanced inventory”配置,我们会注意到所有选项都是全局的:Out of stock threshold, Minimum and maximum qty allowed in Shopping Cart, backorders, notifications等。
虽然这是完全正常的——具有全局库存,需要大多数功能与其相关,也需要全局设置,但可能会出现这样的情况,即我们需要一些功能来处理不同的范围(例如网站或商店视图范围)。这样的例子就是延期交货,一个简单的功能,来允许客户购买没有库存的产品。 这会使数量进一步减少为负值,例如-5。
我们是否可以将此功能扩展到全球范围之外,并将其用于网站级别?事实证明我们可以,而且变化不大。
为了研究这一点,我们需要将更多的商品添加到购物车中。通过这样做,我们最终(省略了几个简短的步骤)vendor/magento/module-catalog-inventory/Model/StockStateProvider.php
/**
* Check quantity
*
* @param StockItemInterface $stockItem
* @param int|float $qty
* @exception \Magento\Framework\Exception\LocalizedException
* @return bool
*/
public function checkQty(StockItemInterface $stockItem, $qty)
{
if (!$this->qtyCheckApplicable) {
return true;
}
if (!$stockItem->getManageStock()) {
return true;
}
if ($stockItem->getQty() - $stockItem->getMinQty() - $qty < 0) {
switch ($stockItem->getBackorders()) {
case \Magento\CatalogInventory\Model\Stock::BACKORDERS_YES_NONOTIFY:
case \Magento\CatalogInventory\Model\Stock::BACKORDERS_YES_NOTIFY:
break;
default:
return false;
}
}
return true;
}
这样做是检查qty
我们是否想要购买。如果不是,它会对延期交货功能进行检查,从而进一步引导我们vendor/magento/module-catalog-inventory/Model/Configuration.php
,用于从数据库(core_config_data
)中检索延期交货信息。
/**
* Retrieve backorders status
*
* @param null|string|bool|int|\Magento\Store\Model\Store $store
* @return int
*/
public function getBackorders($store = null)
{
return (int) $this->scopeConfig->getValue(
self::XML_PATH_BACKORDERS,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE,
$store
);
}
要注意的有趣的事情是在获取配置细节时传递的$Stand变量。因此,Magento正在寻找数据库中延期交货设置的范围值,但由于没有,因此返回全局范围的值。如果我们将此配置的范围从全局更改为网站会怎么样?我们试试吧。
- 制作一个简单的Magento 2模块
- 创建一个文件 app\code\Your_Vendor\Your_Module\etc\adminhtml\system.xml
内容如下:
<?xml version="1.0"?>
<!--
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="cataloginventory" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<group id="item_options" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<field id="backorders" translate="label" type="select" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
<label>Backorders</label>
<source_model>Magento\CatalogInventory\Model\Source\Backorders</source_model>
<backend_model>Magento\CatalogInventory\Model\Config\Backend\Backorders</backend_model>
<comment>Changing can take some time due to processing whole catalog.</comment>
</field>
</group>
</section>
</system>
</config>
我们刚刚复制了位于ven./magento/module-catalog-./etc/adminhtml/system.xml的核心配置,并将showInWebsite从0更新为1。现在我们有一个网站上的备份订单的配置。
我们刚刚复制位于vendor/magento/module-catalog-inventory/etc/adminhtml/system.xml的核心配置,并将showInWebsite
从0更新为1,现在我们有一个网站级别的延期交货配置。
这里的更改产生了一些影响:
- 显然,我们可以在网站级别设置后台功能
- 由于仍然只有1个库存,我们需要确保打开缺省的订单范围,因为cataloginventory_stockstatus indexer使用该范围来正确设置状态
- 如果启用了默认配置(如第2点所示),则所有产品在前端都是“可用”,这并非我们所希望的(“Add to cart”按钮将随处可见)
值得庆幸的是,Magento提供了一些方便的事件,我们可以监听以“修复”那些没有启用bacorder的库存状态。
vendor/magento/module-catalog/Model/Product.php中
有isSalable()
方法,从前端调用(在决定是否应显示“add-to-cart”按钮时)。据调度catalog_product_is_salable_before
和catalog_product_is_salable_after
,我们可以使用,和显示产品为“不实用”,如果他们。
我们可以使用catalog_product_is_salable_before和catalog_product_is_salable_after事件,将未启用延期交货的功能的店铺里的产品显示为“不可销售的”
/**
* Check is product available for sale
*
* @return bool
*/
public function isSalable()
{
// ...
<strong>$this->_eventManager->dispatch('catalog_product_is_salable_before', ['product' => $this]);</strong>
$salable = $this->isAvailable();
$object = new \Magento\Framework\DataObject(['product' => $this, 'is_salable' => $salable]);
<strong>$this->_eventManager->dispatch(
'catalog_product_is_salable_after',
['product' => $this, 'salable' => $object]
);</strong>
// ...
}
我们可以创建一个自定义观察器,该观察器将监听这些事件之一,并在qty <= 0或者店铺未启用延期交货时将product设置为不可销售($product->setIsSalable(false))
就是这样 - 在配置上的一个小更改,以及一个自定义的观察器,就能确保所有数据都正确显示,使我们能够在网站范围内拥有延期交货功能。