Email Template Parser Not Parsing Currency

Hey All, I’m trying to troubleshoot a problem where the email template parser is not parsing the currency properly. It has like 6 decimal places (see screen shot below). Hoping someone may have tackled this before. I’m trying to compare what the PDF parser does with currency vs. email template parser.

I’ve found this public function in EmailTemplate.php and looked at the function for currency_format_number() and that all looks ok.

 public function _convertToType($type, $value)
    {
        switch ($type) {
            case 'currency':
                return currency_format_number($value);
            default:
                return $value;
        }
    }

Anyone looked at this before?

email template currency issue

I should also note that “yes” my currency format in locale is set to two (2) decimal places.

If I go further down, I found this…

  $repl_arr["contact_user_" . $fieldName] = self::_convertToType($field_def['type'], $user->$fieldName);

The function currency_format_number() must be OK because it works other places (like PDF template).

function currency_format_number($amount, $params = array())
{
    global $locale;
    if (isset($params['round']) && is_int($params['round'])) {
        $real_round = $params['round'];
    } else {
        $real_round = $locale->getPrecedentPreference('default_currency_significant_digits');
    }
    if (isset($params['decimals']) && is_int($params['decimals'])) {
        $real_decimals = $params['decimals'];
    } else {
        $real_decimals = $locale->getPrecedentPreference('default_currency_significant_digits');
    }
    $real_round = $real_round == '' ? 0 : $real_round;
    $real_decimals = $real_decimals == '' ? 0 : $real_decimals;

    $showCurrencySymbol = $locale->getPrecedentPreference('default_currency_symbol') != '' ? true : false;
    if ($showCurrencySymbol && !isset($params['currency_symbol'])) {
        $params["currency_symbol"] = true;
    }
    return format_number($amount, $real_round, $real_decimals, $params);
}

I just remember this old issue, which got fixed back in 2018

But this is not likely to be related to your case…

Thanks @pgr I did look into a bunch of past threads about the PDF parser. I’ve tested the PDF parser it it works fine with currency, it’s only email templates. I’ve never really delved into the email template code before, but it’s unrelated to the PDF template parser right?

It’s really messy, there are 2 or 3 different bits of code doing variable replacement.

It’s not even just a matter of distinguishing the uses with Email/PDF. Even just for Email it can go through different routes (e.g. in Campaigns versus single email in Compose window)

I’ve spent hours going through the email parser and email template. Just can’t seem to get to the bottom of it. Looks like it has provisions for currency, Just can’t seem to follow how it’s implemented in order to troubleshoot. Think I’m going to try and “cheat” and just change the DB table to have two decimal places and see if that can output it correctly. Hoping that doesn’t change every time I repair and rebuild.

In your tests, where is it being called from? Which UI action are you doing to trigger the parsing etc?

That’s kind of my problem, I’ve been putting a write to log line pretty much everywhere I can think of in the email template file and I can’t see where it’s running the currency parser at all. I’m going to give it one more look today.

OK, so I’m close, after hours and hours, I finally found where it’s subbing in the values. Strangely for system email templates, seems to work fine and executes _convertToType() function in EmailTemplate.php

However, when it’s just a regular on demand email template using the email compose, it does not use _convertToType() function.

So I narrowed it down to (around line 460ish, I’ve got so many comments in, it might be +/-)

$value= $focus->{$field_name};

outputs the value of the variable.

$focus is an array of all the Account Fields.

So, I’m close, I just need to grab the “type” of the field and so I can use the function _converttoType() and then an if statement, if type is currency.

Multi-Dimensional arrays are really pushing the limits of my PHP knowledge.

How do I get the Account ($focus)->Field_Name($field_name)…-> [type]? Anyone help with the syntax to get the type?

Look under $focus->field_defs sub-array

Finally!! Ok fixed it.

in …/modules/EmailTemplates/EmailTemplate.php

after line 458 ( $value = $focus->{$field_name}; )

//add this line to get the type of field
					$type = $focus->field_defs[$matches[0][$i][2]]['type'];
// convert type function to convert to currency
						$value =  self::_convertToType($type, $value);

PS - I don’t think you need an if statement, the function looks like it’s designed to work for all fields and then just format the currency type.

Line 450 reads

$field_name = $matches[0][$i][2];

So I think you can simplify that expression of yours to just

$type = $focus->field_defs[$field_name]['type'];

That also works!!! Thanks so much @pgr for your coaching on this one. I was ready to give up so many times, but your hint to me about testing led me to output to the log like everywhere until I could zero in on exactly where the values were being generated.

I’ll add it on github too, hopefully it makes it into an update.

That was good detective work! :clap:

How about taking the next step and running an IDE like PHPStorm and stepping through the code in the debugger? That’s when your productivity really increases, and you learn much faster.