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