Recalculating a Product’s Price with Catalog Price Rules in Magento 1.8

catalog-price-rulesindexingmagento-1.8price

I have a module that directly changes a product's price in the database. I would like for the catalog price rules, the various discounts on our site, to get applied to the product's price after I update the base price.

Saving the item, either in admin area or with a ->save() call sets the prices, but it takes far too long to save all the items we need. I want to just recalculate the discount prices without doing anything else.

I've tried various 're-indexing' methods, but I don't know if this is the issue. Nothing I've done seems to affect the product's price. Below is a overview of the attempts I've made that haven't born fruit:

Mage::getResourceModel('catalog/product_indexer_price')->reindexProductIds($productId);

This runs without error but doesn't seem to actually update the discounted prices on the front end.

Mage::getSingleton('index/indexer')->processEntityAction(
        $product, 'catalog_product', Mage_Index_Model_Event::TYPE_SAVE
    );

Again, this will run without error, but it won't change the price. I've tried changing catalog_product to catalog_product_price and TYPE_SAVE to TYPE_REINDEX all without success.

Mage::getModel('catalog/product_indexer_price')->reindexAll();
$event = Mage::getSingleton('index/indexer')->logEvent(
    $product,
    $product->getResource()->getType(),
    Mage_Index_Model_Event::TYPE_SAVE,
    false
);
Mage::getSingleton('index/indexer')
    ->getProcessByCode('catalog_product_price')
    ->setMode(Mage_Index_Model_Process::MODE_REAL_TIME)
    ->processEvent($event);

Once again, no errors, but also no price updates.

To be clear, the base price will show up immediately. It is only the actual price that is calculated with all of the catalog price rules that isn't updating.

Caching is disabled on my development system.

Best Answer

It seems I've stumble upon the answer. To recalculate the 'final' price that gets calculated by applying all of the catalog price rules you need to run this:

Mage::getModel('catalogrule/rule')->applyAllRulesToProduct($product);

One thing that gave me problems is that in messing around trying to figure this out I set a special price with the following:

$product->setSpecialPrice(20.00);
$product->save();

Apparently a special price is higher priority than the price calculated by the price rules. As long as my special price was manually set I could not see that applyAllRulesToProduct was recalculating my prices correctly. I had to first:

$product->setSpecialPrice(null);
$product->save();

And then I could adjust the price in the database, and run:

Mage::getModel('catalogrule/rule')->applyAllRulesToProduct($product);

All of my sales prices for diferent stores and customer groups would get calculated. There is no need to reindex, the applyAllRulesToProduct function reindexes what is necessary.

Unfortunately, with the number of price rules in our store, that function is still slow. However, it is much faster than saving the whole item.