13 replies [Last post]
alliax@drupal.org's picture
Offline
Joined: 01/20/2008
Juice: 22
Was this information Helpful?

Hello, I've searched the forum after I couldn't find the settings.
I made the default country France, and the page add product asks for a price with a dot to separate the decimals.
But after that, the price is displayed with a comma, which is the way people in France are used to.

At the moment when I add a product price with a comma, it says error and ask for a dot. Since most install of ubercart are probably developed for clients, it would be fair to expect the UI to follow the default country's currency/number settings.

Is there an option I've missed in the settings panel?

Cheers,
James

TR
TR's picture
Offline
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3424
Re: In some countries the separator for decimal is a comma, can

admin/store/settings/store/edit/format

<tr>.
alliax@drupal.org's picture
Offline
Joined: 01/20/2008
Juice: 22
Re: Re: In some countries the separator for decimal is a comma,

OK I wasn't clear once again, trying to give too much details, I'll say it simply :

I KNOW I CAN CHANGE THE COUNTRY SETTINGS, I PUT A COMMA TO SEPARATE DECIMALS

But in the input box of a new product, the system ASKS for a dot, when I enter a dot, it's fine, if not, the product is never created, error message ASKING for a dot.

When the product is accepted, the DISPLAY is fine, with a comma.

But can I have the system ACCEPTS a comma when adding products prices ?

That I haven't found.

TR
TR's picture
Offline
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3424
Re: Re: Re: In some countries the separator for decimal is a com

I see now. It appears that uc_product_form_validate() (in uc_product.module) is not written to properly accept the store's currency format. Shouldn't be a big deal to fix - submit it as a bug in Issue Tracker.

<tr>.
Ryan's picture
Offline
Joined: 08/07/2007
Juice: 15438
Re: Re: Re: Re: In some countries the separator for decimal is a

Regarding putting numbers in using commas instead of periods for decimals... PHP and MySQL expect decimals to be periods in several places that would make adding support for commas here be extremely difficult. For now, I'm going to have to suggest this isn't possible until proven wrong by another source, although it might do to put below the box the format for numbers the form requires.

alliax@drupal.org's picture
Offline
Joined: 01/20/2008
Juice: 22
Re: Re: Re: Re: Re: In some countries the separator for decimal

Thank you. I'm submitting a bug report in issue tracker

In fact I don't think there are a lot of other signs to separate decimals, it's either a dot or a comma I believe.
What you could do is accept the input as per the country settings, but add it in the database as a dot separated decimal number. You only have to do the str_replace('.', ',', $submit_price) when displaying the price to the store owner in the product edit form.

But anyway, I understand now that I didn't miss a settings somewhere, ubercart just doesn't support that yet, ok I'll write the format the price number requires. But you know it's not so convenient to change people's habits when all your life you're used to put a comma. Thanksfully for us web developpers from non-english countries we've learned to be flexible with our habits, but that's not the case for our clients.

TR
TR's picture
Offline
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3424
Re: Re: Re: Re: Re: Re: In some countries the separator for deci

The following modification to uc_product_form_validate() will allow localized money formats to be used in the price fields of the product edit form.

Replace this:

<?php
  $pattern
= '/^\d*(\.\d*)?$/';
 
$price_error = t('Price must be in a valid number format. No commas and only one decimal point.');

  if (!empty(

$form_values['list_price']) && !is_numeric($form_values['list_price']) && !preg_match($pattern, $form_values['list_price'])){
   
form_set_error('list_price', $price_error);
  }
  if (!empty(
$form_values['cost']) && !is_numeric($form_values['cost']) && !preg_match($pattern, $form_values['cost'])){
   
form_set_error('cost', $price_error);
  }
  if (!
is_numeric($form_values['sell_price']) && !preg_match($pattern, $form_values['sell_price'])){
   
form_set_error('sell_price', $price_error);
  }
?>

By this:

<?php
  $price_error
= t('Price must be in a valid currency format. No "' .variable_get('uc_currency_thou', ',').  '" and only one "'. variable_get('uc_currency_dec', '.') .'".');

  foreach (array(

'list_price', 'cost', 'sell_price') as $price_type) {
   
$price  = $form_values[$price_type];
    if (!
uc_currency_is_currency($price)) {
     
form_set_error($price_type, $price_error);
    }
   
// Strip thousands marker
   
$price  = str_replace(variable_get('uc_currency_thou', ','), '', $price);
   
// Rewrite price to use "." as decimal marker
   
$price  = str_replace(variable_get('uc_currency_dec', '.'), '.', $price);
   
// Store canonical price format back into the form
   
form_set_value(array('#parents' => array($price_type)), $price);
  }
?>

There are also three other lines that need to be modified higher up in the code, to re-format the prices back to the localized version before displaying in the form textfield:

This: '#default_value' => $node->list_price;
Becomes this:'#default_value' => uc_currency_format($node->list_price, false),
This: '#default_value' => $node->cost;
Becomes this:'#default_value' => uc_currency_format($node->cost, false),
And this: '#default_value' => $node->sell_price;
Becomes this:'#default_value' => uc_currency_format($node->sell_price, false),

I've introduced (but not fully checked!) a new function uc_currency_is_currency() for the uc_store() module. It returns a boolean true if the argument is a valid currency string in the localized format. This new function could be used where ever a currency value is input, like in the shipping modules (Flatrate) etc:

<?php
function uc_currency_is_currency($price) {
  return
preg_match('/^[0-9]*(' .variable_get('uc_currency_thou', ',') .'[0-9][0-9][0-9])*(['. variable_get('uc_currency_dec', '.') .'][0-9]*)?$/', $price);
}
?>

The regexp could use a little thinking about to make sure it works in all cases.

<tr>.
Lyle's picture
Offline
AdministratoreLiTe!
Joined: 08/07/2007
Juice: 6846
Re: Re: Re: Re: Re: Re: Re: In some countries the separator for

I like it. The only thing I might change is to use preg_quote() on the thousands and decimal markers in uc_currency_is_currency(). This would be more to prevent things from being broken by malicious users than because someone really needs to use special characters in their currency format.

Lyle's picture
Offline
AdministratoreLiTe!
Joined: 08/07/2007
Juice: 6846
Re: Re: Re: Re: Re: Re: Re: Re: In some countries the separator

Hmm...second thoughts: Are we going to do the same thing with the weight field? What about all the other forms in Übercart that deal with numeric data? Attributes, quotes, taxes, and payments should all act the same way if we're going to start changing things.

TR
TR's picture
Offline
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3424
Re: Re: Re: Re: Re: Re: Re: Re: Re: In some countries the separa

Well yeah, that's the problem - this isn't the only module where this situation occurs.

I think a much more elegant solution would be to handle localization at a much lower level. It SHOULD be built into PHP (i.e., numbers should be stored in a machine-independent binary format, and the implicit type conversion should correctly parse or output numerical strings based on the locale setting), but I suppose that's asking too much...

Next best is to subclass textfield to handle localized numbers. Call it numberfield or something like that, in analogy with the password component which is a specialized textfield for passwords. Then it would be a simple change to any module which uses textfields to display numbers. I don't have time to figure out how to do that or to delve into what is going on with Drupal in regards to internationalization, so I just implemented it for this one case.

<tr>.
kidrobot's picture
Offline
Joined: 02/09/2009
Juice: 17
Any update on uc_currency_is_currency?

Thought this thread might be useful for altering the price validation in the Direct Deposit module, which flags an error on prices with commas.

Using the above uc_currency_is_currency() function, prices like 1,000.50 return false. Is there an updated version of this function kicking about somewhere or do I need to get down and dirty with regex?

chegga's picture
Offline
Joined: 07/20/2010
Juice: 16
Re: Any update on uc_currency_is_currency?

It's really bad usability for people that don't use a point as decimal seperator. Unfortunately there is no solution for ubercart.
Here is another prospal. Ubercart core need a function to replace prices into 000.00 (default format). The replace pattern is using drupal price format settings.

For example replace from "10,50" into "10.50".

Every uc module that has a price field in a form can use this function to replace prices on validation and/or submit functions. The output would be correct without changes because it's still integrated in uc.

Please give feedback.
Chris

ferrum's picture
Offline
Joined: 04/11/2010
Juice: 20
does not work for Drupal 6

This solution does not work for Drupal 6 as the function form_set_value now requests a third parameter $form_state which is not available in hook_validate / uc_product_validate. Does anyone has a solution for Drupal 6 to use decimal comma in price setting?

webmaker's picture
Offline
Joined: 04/22/2009
Juice: 76
Re: In some countries the separator for decimal is a comma, can

Would like to stress that this is also an issue for me and several projects. I create shops for German customers and again and again they claim that it is very unhandy to type in the prices with a dot instead of comma. Would be great if there would be found a sollution!