2

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.

4
  • 2
    I posted the same problem on the old forum a million years ago, but that does not work anymore: magentocommerce.com/bug-tracking/issue?issue=10777. All I remember is that the catalog_product_get_final_price method is not dispatched for collections. The recommendation from the core team was to use catalog_product_collection_load_after as you tried and it involved changing the attribute price in the base currency so the conversion ends up at a rounded value.
    – Marius
    May 31, 2016 at 7:42
  • @Marius see my edit. Basically using catalog_product_collection_load_after displays rounded price as low as original price May 31, 2016 at 7:44
  • 1
    That's why you need to change price and final_price and other prices, so it will look like the original price is the rounded value.
    – Marius
    May 31, 2016 at 7:47
  • @Marius Imma make some tests ;) May 31, 2016 at 7:47

3 Answers 3

3

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.

2
  • Did you find lot of troubles with this, making that custom price prevail during the whole checkout process? I need to do something like that Jul 26, 2016 at 12:45
  • @RaulSanchez not really apart from the issue I faced in my question and solved by my answer I didn't face any issue Jul 26, 2016 at 13:03
2

A wild idea.
You say that it works for the product details page because the event catalog_product_get_final_price is triggered.
How about making it trigger in the list page?
The event is not triggered in the event page because the getFinalPrice method looks like this:

public function getFinalPrice($qty=null)
{
    $price = $this->_getData('final_price');
    if ($price !== null) {
        return $price;
    }
    return $this->getPriceModel()->getFinalPrice($qty, $this);
}

The event is dispatched in the method Mage_Catalog_Model_Product_Type_Price::getFinalPrice.
You can try to rewrite the method it means the getFinalPrice from the product model and skip the verification for $price = $this->_getData('final_price'); when the currency is NZD.
Or change it to something like

public function getFinalPrice($qty=null)
{
    $price = $this->_getData('my_final_price'); //change the attributehere
    if ($price !== null) {
        return $price;
    }
    return $this->getPriceModel()->getFinalPrice($qty, $this);
}

then rewrite the getFinalPrice method from Mage_Catalog_Model_Product_Type_Price and make sure it sets the value for my_custom_price also.
And in order to make sure you don't get in the list something like regular price / promo price apply your price logic to the price minimal_price and special_price and all other prices that might be involved in the price.phtml file.
I didn't test this, but it looks like it's worth a try.

1
0

For update pricing or any product attribute like name, description, you can use the event catalog_product_collection_load_after and php observer function would be like below.

public function priceupdate(Varien_Event_Observer $observer){ $products = $observer->getCollection(); foreach( $products as $product ) { $product->setMinimalPrice($priceincfriegt); $product->setPrice($priceincfriegt); } return $this; }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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