3

I've got a problem when programatically saving a product.

While loading the product with help of the product collection or the model (by attribute), setting some value and then saving it, I'm losing the tier and group prices.

$productList = Mage::getModel ( 'catalog/product' )->getCollection ()
  ->addFieldToFilter('color', $color)
  ->load();
foreach($productList as  $product) {
    $product->setColor($newColor);
    $product->save();
}

One can do a workaround by doing one of these:

1.Reload each product:

$productList = Mage::getModel ( 'catalog/product' )->getCollection ()
  ->addFieldToFilter('color', $color)
  ->load();
foreach($productList as  $product) {
    $product = Mage::helper('catalog/product')->getProduct($product->getId());
    $product->setColor($newColor);
    $product->save();
}

2.Load tier and group price (source):

$productList = Mage::getModel ( 'catalog/product' )->getCollection ()
  ->addFieldToFilter('color', $color)
  ->load();
foreach($productList as  $product) {
    $product->getTierPrice(); 
    $product->getGroupPrice();
    $product->setColor($newColor);
    $product->save();
}

minimal variant of reloading (for example) the tier price attribute (extracted from Mage_Catalog_Model_Product_Type_Price::getTierPrice():

$attribute = $product->getResource()->getAttribute('tier_price');
if($attribute){
    $attribute->getBackend()->afterLoad($product);
}

3.Add dummy values (source):

$productList = Mage::getModel ( 'catalog/product' )->getCollection ()
  ->addFieldToFilter('color', $color)
  ->load();
foreach($productList as  $product) {
    $product->setTierPrice ( array (
        'website_id' => 0,
        'cust_group' => 2,
        'price_qty' => 3,
        'price' => 10 
    ) );
    $product->setGroupPrice ( array (
        'website_id' => 0,
        'cust_group' => 2,
        'price' => 10 
    ) );
    $product->setColor($newColor);
    $product->save();
}

All these workarounds have one problem: more database calls. When often running scripts that update a lot of products, it is bad to have even more database calls only for not to lose the tier and group prices.

One can add the tier prices while building up the collection:

$productList = Mage::getModel ( 'catalog/product' )->getCollection ()
  ->addFieldToFilter('color', $color)
  ->addTierPriceData()
  ->load();
foreach($productList as  $product) {
    $product->setColor($newColor);
    $product->save();
}

But by doing so, on save one will get a constraint violation error. It seems in this case Magento tries to save the exact same tier prices again.

Does anyone know a solution which loads the tier and group prices in the same query that is used by the product collection and does not trigger constraint violations on save?

I have also posted this question in the StackOverflow part of StackExchange: https://stackoverflow.com/questions/27900130/saving-product-deletes-tier-price-and-group-price

1

you should never call save without calling load first on a product instance.
A save without a load (on a product from a collection for example) will lead to loss of data.
If you only want to update a single attribute value for a product do this:

Mage::getSingleton('catalog/product_action')->updateAttributes(
    array($attributeId),
    array('attribute_code' => 'attribute_value'),
    $storeId
);

$storeId is the storeview for which you want to update the value. For default values use 0.

  • Unfortunately I am not able to test this right now, as the Project is on ice. I'll see to it, that I can reproduce the problem and to check out your solution. – Akerus Nov 17 '15 at 8:21
  • Hello @Marius , can you give me syntax for "tier_price" attribute for Mage::getSingleton('catalog/product_action') ? – Chirag Rajput Jan 8 '18 at 9:54
0

Try this

$product->setTierPrice ( array(array (
        'website_id' => 0,
        'cust_group' => 2,
        'price_qty' => 3,
        'price' => 10 
    )) );

Its should be array of arrays

  • This looks like the workaround no. 3 (which worked without an array of arrays). What I am looking for is a way to make an update to the product without touching it's tier and group prices. – Akerus May 28 '15 at 8:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.