3

我一直在查看 Magento 的代码(1.6.2 社区版),OMG 是不是执行得非常糟糕,但我不会在这里咆哮

看这段代码:

// Delete error from item and its quote, if it was set due to qty lack
$this->_removeErrorsFromQuoteAndItem($quoteItem, Mage_CatalogInventory_Helper_Data::ERROR_QTY);

在 /app/code/core/Mage/CatalogInventory/Model/Observer.php 的Mage_CatalogInventory_Model_Observer中 行:489

这对我来说产生了一个特殊的错误,试试这个(确保在后端设置“无延期交货”):

  1. 将产品添加到购物车
  2. 将另一个产品添加到购物车。
  3. 进入管理员并更改第一个产品数量,以使购物车中请求的数量不够。
  4. 返回购物车页面。

结果
添加的第一个产品显示“requested item not available in this quantity”错误,但仍显示结帐方式!继续前进,最终给出了一个丑陋的 js 警报,说“并非所有项目都在请求的数量中可用”。

深入挖掘,我发现添加到报价(购物车)中的每个报价项目(购物车项目)似乎都会重置整个报价的错误状态。

这是故意的吗?我偶然发现了一个真正的错误吗?这个无用的评论是什么意思?提前致谢。

编辑:有关解决方法和解释,请参阅下面的答案。

4

2 回答 2

4

我必须发布一个跟进,我的核心黑客有一个不幸的副作用(另一个错误):

  1. 将一定数量的商品添加到购物车(确保有货)。
  2. 进入管理面板并减少库存,以便不再有剩余数量。
  3. 返回购物车页面并刷新,您会收到预期的错误。
  4. 尝试更新购物车并将请求的数量减少到实际可用的数量,您会注意到更新不起作用并且重新显示来自 #3 的错误。

因此,显然这种特殊逻辑对于这种情况是必要的。

实际的缺陷是报价错误信息集合不区分报价项目。因此 _removeErrorsFromQuoteAndItem 函数从购物车中删除所有与数量相关的错误,包括来自另一个报价项目的错误(仍然是错误的)。

我找到了一种无需任何核心技巧即可工作的解决方法,将此事件观察器附加到sales_quote_item_qty_set_after事件。

public function reinitQuoteErrorState(Varien_Event_Observer $observer)
{
    $item = $observer->getEvent()->getItem();
    /** @var $item Mage_Sales_Model_Quote_Item */

    $quote = $item->getQuote();
    /** @var $quote Mage_Sales_Model_Quote */

    // Quote not loaded, do nothing since our changes are transient
    if (!$quote) return;

    // Quote already has error state, nothing to do.
    if ($quote->getHasError()) return;

    foreach ($quote->getAllItems() as $quoteItem)
    {
        if ($errorItems = $quoteItem->getErrorInfos())
        {
            foreach ($errorItems as $errorItem)
            {
                if ($errorItem['code'] == Mage_CatalogInventory_Helper_Data::ERROR_QTY)
                {
                    $quote->addErrorInfo(
                        'error',
                        'cataloginventory',
                        Mage_CatalogInventory_Helper_Data::ERROR_QTY,
                        Mage::helper('cataloginventory')->__('Not all products are available in the requested quantity')
                    );

                    return;
                }
            }
        }
    }
}

注意:具有此事件处理程序的模块必须添加到 /app/etc/modules/ 中的模块 XML 文件的标记(例如:/app/etc/modules/MyCompany_MyModule.xml),以确保在Mage_CatalogInventory_Model_Observer之后调用此处理程序::checkQuoteItemQty有错误。

真正的解决方案是修复报价错误信息系统以维护报价项目身份,但这种解决方法无需任何核心黑客攻击即可。

<?xml version="1.0" encoding="utf-8"?>
<config>
    <modules>
        <MyCompany_MyModule>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_CatalogInventory />
            </depends>
        </MyCompany_MyModule>
    </modules>
</config>
于 2012-05-12T12:49:40.393 回答
1

我们最近也注意到了这个问题,并写了一个类似的解释。我们还根据 Raif 提供的大纲整理了一个模块来解决此问题 - http://www.brand3.com/b3labs/magento-core-bug-multiple-basket-items-stock/ - 对于任何不确定的人如何把它变成一个模块。

于 2012-07-23T08:10:07.050 回答