3

当我尝试从具有分级定价的 Magento Enterprise 1.8 脚本中保存产品模型时,我发现了一些奇怪的行为。

以这段代码为例:

// This product has a tier price
$product = Mage::getModel('catalog/product')->load(194760);
$product->setName('Changed Product Title');
$product->save();

保存时获取异常(详情如下)。但是,如果我不更改模型中的任何内容,则不会出现异常。我有一种感觉,这是因为我没有更新任何东西,所以 Magento 没有做太多的工作。

// Same product, but I changed nothing and it works 
$product = Mage::getModel('catalog/product')->load(194760);
$product->save();

奇怪的是,如果我正在设置或修改等级价格信息,我能够成功保存产品(等待我不创建任何重复的东西)

// This works pending the tier price does not already exist
$mud_array = array();
$mud_array[] = array(
    'website_id' => 0,
    'cust_group' => 32000,
    'price_qty' => 5,
    'price' => 6
);
$product = Mage::getModel('catalog/product')->load(194760);
$product->setTierPrice($mud_array);
$product->save();

我看到的异常如下:

致命错误:未捕获的异常“Mage_Eav_Model_Entity_Attribute_Exception”和消息“SQLSTATE [23000]:完整性约束违规:1062 /path/to/magento/app/ 中键“UNQ_CATALOG_PRODUCT_TIER_PRICE”的重复条目“194760-1-0-5.0000-0”代码/核心/法师/Eav/模型/实体/Abstract.php:61

因此,当产品中存在等级价格时,如果您尝试更改模型中的任何内容,它将尝试重新插入所有等级价格信息。

有没有人见过这个?有没有办法解决这个问题?感谢您的任何帮助,您可以提供。

4

2 回答 2

5

我在使用 EE 1.12 时遇到了同样的问题,但使用了“group_price”属性。只是通过在我的脚本的乞求中添加来修复错误

法师::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

于 2012-07-04T09:59:31.697 回答
1

好的,所以我为此创建了一个似乎可行的修复程序。

在 /app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Attribute/Backend/Tierprice.php 中有一个名为 savePriceData 的函数。据我所知,这个函数负责确定我们是否需要更新或插入等级价格。

有一个 if 块根据来自传递给函数的 $priceObject 的信息做出更新或插入的决定。

如果您从管理面板更新等级价格,priceObject 有两个值 value_id 和 value。这些字段都指向 catalog_product_entity_tier_price 表中的列。这就是 if 块的第一部分发生的情况

如果您从管理面板创建新的层价格,priceObject 具有 catalog_product_entity_tier_price 表中的所有列(entity_id、all_groups、customer_group_id、qty、value 和 website_id)。Magento 然后获取此信息并将其插入到 catalog_product_entity_tier_price 表中。

实际的问题是,当您从脚本(也就是管理面板之外)保存产品时,您总是会得到一个包含所有插入信息的 priceObject。所以它总是会尝试插入到表中,如果它已经存在会导致违反完整性约束。

所以我为此做的修复非常简单。在 if 块的第二部分,我正在检查表中是否已经存在等级价格,如果是,我根本不进行插入。这是代码:

... first part of if statement
// somehow we need to have this not happen if it already exists
$reader = $this->_getReadAdapter();
$sql = "SELECT * FROM catalog_product_entity_tier_price WHERE ";
foreach($data as $index => $value) {
$sql .= $index . ' = ' . $value . ' AND ';
}
$sql = substr($sql, 0, -4);
$search = $reader->fetchAll($sql);
if(count($search) > 0) {
// It already exists, don't do anything
} else {
$adapter->insert($this->getMainTable(), $data);
}

显然,您确实应该确保在进行此更改之前将此文件复制到本地(或者更好的是,在模块中重写它)。这可能不是做到这一点的最 100% 正确的“Magento 方式”,但我真的需要尽快找到解决方案。

我愿意接受比这更好的解决方案,但我想分享我的发现

(注意:由于我使用的是 Magento 企业版,因此​​我不想再分享不必要的源代码,因为这可能违反我们的许可协议)

于 2012-04-16T17:40:23.093 回答