Magento 1.9 – Best Approach to Change Product Prices on the Fly

collection;event-observermagento-1.9priceproduct

So I have this requirement where I need to round product prices based on several criteria for one specific currency.

So when watching the catalog (category view / product view whatever) the prices need to be updated on the fly.

I managed to get it right by using the following observer:

<frontend>
    <events>
        <catalog_product_get_final_price>
            <observers>
                <update_price_on_the_fly>
                    <type>singleton</type>
                    <class>Vendor_Module_Model_Observer</class>
                    <method>roundPrice</method>
                </update_price_on_the_fly>
            </observers>
        </catalog_product_get_final_price>
    </events>
</frontend>

Then in my observer I did:

public function roundPrice(Varien_Event_Observer $observer) {

    // check if are using NZD conversion
    if (!preg_match("/NZD/i", $code = Mage::app()->getStore()->getCurrentCurrencyCode())) {
        return;
    }

    $newPrice = $this->_getPriceLogic($observer->getProduct());
    $observer->getProduct()->setFinalPrice($newPrice);
}

That works fine for the product view page but does not work on the category page. It seems like catalog_product_get_final_price event is not dispatched on the category page.

I tried to observer catalog_product_collection_load_after event and use the following code but it does not seem to work entirely.

Instead of displaying my rounded price is displays:

rounded price as low as original price

public function roundPriceCollection($observer) {

    // check if are using NZD conversion
    if (!preg_match("/NZD/i", $code = Mage::app()->getStore()->getCurrentCurrencyCode())) {
        return;
    }

    $event = $observer->getEvent();
    $products = $observer->getCollection();
    foreach( $products as $product ) {
        $product->setFinalPrice($this->_getPriceLogic($product));
    }
    return $this;
}

Thus I'm wondering what is the best approach to implement such feature.

Best Answer

Thanks to @Marius, @Vinai and @AndreasVonStudnitz here's how I managed to get it right.

So the catalog_product_get_final_price is only for display purpose on the product view page and the final price from the category and checkout pages come from the price index database table.

Thus I was right using catalog_product_collection_load_after

However, to fix the As Low As display issue I had to add the following code to my observer code:

$product->setPrice($this->_getPriceLogic($product));
$product->setMinimalPrice($this->_getPriceLogic($product));

Of course, as this was for a simple product not on sale it was an easy case and I'll probably have some adjustements to make in order to get it working for every case but I got the idea now.

Related Topic