0

In Magento, I want to apply a custom PHP function to the display of prices on the frontend without changing the actual numerical price on the backend / shopping cart.

To be specific, I want to remove decimals on the display price when there are no cents in the price. For example, $19.00 would display as $19 but $19.99 would display as $19.99.

I found a PHP function on PHP.net that will perform this change for me:

// formats money to a whole number or with 2 decimals; includes a dollar sign in front
    function formatMoney($number, $cents = 1) { // cents: 0=never, 1=if needed, 2=always
      if (is_numeric($number)) { // a number
        if (!$number) { // zero
          $money = ($cents == 2 ? '0.00' : '0'); // output zero
        } else { // value
          if (floor($number) == $number) { // whole number
            $money = number_format($number, ($cents == 2 ? 2 : 0)); // format
          } else { // cents
            $money = number_format(round($number, 2), ($cents == 0 ? 0 : 2)); // format
          } // integer or decimal
        } // value
        return $money;
      } // numeric
    } // formatMoney

I do not want to have to change Magento templates to apply this function, because the prices appear all over the place. It would be a nightmare to update all the templates.

I would like to know whether there is a place I can use this function to format the display of the price globally so it affects the display of all prices everywhere from one spot.

Already I have spent a few hours poking around various Magento files, including:

app/code/core/Mage/Directory/Model/Currency.php

public function format <-- This function changes the real price, not the display of the price.

app/code/core/Mage/Catalog/Model/Product.php:

public function getFormatedPrice <-- This function looked promising but didn't do anything for me.

I also looked at these files without anything jumping out as an obvious place:

app/code/core/Mage/Catalog/Block/Product.php

app/code/core/Mage/Catalog/Block/Product/Price.php

app/code/core/Mage/Catalog/Block/Product/View.php

Do you think it's possible to find one place in Magento that I can hack to apply my custom PHP function to the display of the price (and not the actual numerical price in the shopping cart)?

KingCrunch
  • 128,817
  • 21
  • 151
  • 173
Chrysippus
  • 119
  • 1
  • 11

2 Answers2

0

You could use an observer on catalog_product_get_final_price for that:

config.xml:

<config>
    <frontend>
        <events>
            <catalog_product_get_final_price>
                <observers>
                    <catalogrule>
                        <class>myextension/observer</class>
                        <method>processFrontFinalPrice</method>
                    </catalogrule>
                </observers>
            </catalog_product_get_final_price>
        </events>
    </frontend>
</config>

in your observer class:

<?php
public function processFrontFinalPrice($observer)
{
    $product    = $observer->getEvent()->getProduct();
    $finalPrice = 123.45;   //modify your price here
    return $this;
} 
?>
aeno
  • 560
  • 5
  • 24
  • I think Moldovan is right. This method no longer works in recent versions of Magento [catalog_product_get_final_price not dispached prop](http://www.magentocommerce.com/bug-tracking/issue?issue=10777) – Chrysippus Jan 19 '13 at 03:47
0

I'm not sure that catalog_product_get_final_price will work as you want, so another solution that i propose is to override formatTxt from Mage_Directory_Model_Currency

In that function you can check if price has decimals or not and set option $options['precision']=0; if you want that price to not have decimals (like xx.00).

Eg:

public function formatTxt($price, $options=array())
{
  if(is_numeric( $price ) && floor( $price ) == $price){
     $options['precision']=0;
  }
  return parent::formatTxt($price, $options);
}
Moldovan Daniel
  • 1,521
  • 14
  • 23
  • Wow, I got that to work beautifully by creating an extension and putting your function inside the extension's Model/Currency.php with: `class Myname_Myextension_Model_Currency extends Mage_Directory_Model_Currency { ... } `. Can you explain why this works? I have been studying PHP for a few months and don't fully understand overriding methods. Does this new formatTxt function completely replace the old one? And what does `parent::formatTxt` do exactly? Does it add the rest of the code in the original formatTxt function to the end of the new formatTxt function? – Chrysippus Jan 19 '13 at 03:54
  • Yes basically decide if price has this form eg 150.00 or 150.000 with that "if" statement and set option precision to zero and then call function from parent class, so all code from parent function will be executed, the only difference is that you control precision parameter that tell parent function with how decimals to format price. – Moldovan Daniel Jan 19 '13 at 11:16
  • Excellent. Thanks for this practical tutorial. Very helpful. – Chrysippus Jan 19 '13 at 16:01
  • I just noticed that it works everywhere except when you select a configurable product. For some reason, it still shows prices with .00 decimals when you select a configurable options (e.g. blue or red version of a product.) – Chrysippus Jan 19 '13 at 18:59
  • For that is i think is not a easy solution. You could override "getJsPriceFormat()" from "Mage_Core_Model_Locale" an set "requiredPrecision" to zero, but in this way all the time price will not have decimal even if are not '00'. Or you can modify/override "formatPrice" function from /js/varien/product.js and set "this.priceFormat.requiredPrecision =0;" when option price meet your condition. eg: "if(price % 1 == 0) { this.priceFormat.requiredPrecision =0; }" – Moldovan Daniel Jan 19 '13 at 20:02
  • 1
    Your second suggestion works perfectly when modifying the original in /js/varien/project.js file. I was then able to override this function using a custom JS file [with the help of some friends](http://stackoverflow.com/questions/14464492/how-do-i-override-a-js-function-in-js-varien-product-js). Thanks. – Chrysippus Jan 22 '13 at 20:48