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」属性で問題が発生しました。スクリプトの最初の段階で追加することで、エラーを修正することができました

Mage :: 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 という関数があります。私が収集できることから、この関数は、ティア価格を更新または挿入する必要があるかどうかを判断する役割を果たします。

関数に渡される $priceObject からの情報に基づいて、この更新または挿入の決定を行う if ブロックがあります。

管理パネルから階層価格を更新する場合、priceObject には value_id と value の 2 つの値があります。これらのフィールドは両方とも、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 ブロックの 2 番目の部分では、層の価格が既にテーブルにあるかどうかを確認します。ある場合は、単に挿入を行いません。コードは次のとおりです。

... 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 の Enterprise Edition を使用しているため、ライセンス契約に違反する可能性があるため、必要以上にソースを共有したくありませんでした)

于 2012-04-16T17:40:23.093 に答える