#731596: Add a currency list function and settings form specifies the core currency listing function. It will only include a limited number of currencies for testing purposes, but we want it to include as many as possible. Ideally, every country's currency would be represented. When that issue is resolved, observe its pattern for defining currencies and post a patch that includes all the others. : )

Resources would be Wikipedia and other open source projects like Magento.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Damien Tournoud’s picture

At the very minimum, we need all the currencies defined in ISO 4217.

rszrama’s picture

I knew there was an ISO standard with some number on it...

http://www.iso.org/iso/currency_codes_list-1
http://en.wikipedia.org/wiki/ISO_4217

Would be nice to see a list with the symbol for each currency. Also, I suppose we might need to update the other issue to include the numeric code?

onyxnz’s picture

List of Currency Symbols:
http://www.xe.com/symbols.php

XE is good as a real world (traded-currency) example.
Also their list of the ISO4217 (shortened to traded currencies):

http://www.xe.com/iso4217.php

onyxnz’s picture

Also, we may need to specify a suggested font in order to enable the viewing of such symbols outside of our Western Latin idiom?

Have a look at here:

http://www.unifont.org/fontguide/

Interesting reading if you are going to make truly multi-currency sites. OTOH the headache-inducing strain of getting different fonts to work across multiple OSes and browsers (yes IE, I'm looking at you!) will most likely mean that everyone edges closer to the fabled one-world currency (or USD).

(apologies if this posts twice, D.O seems to be disagreeing with my Save button!)

redben’s picture

FileSize
25.62 KB

I thought i posted this a while ago but realized i didn't ! Attached is a return array of currencies in the following structure

array (
  'USD' => array ( 
    'numeric_code'  =>	840	, 
    'code' => 'USD', 
    'name' => t('United States dollar'), 
    'symbol' => '$', 
    'fraction_name' => t('Cent'), 
    'decimals' => 2 
  ),
  ...
);
dmakal’s picture

Assigned: Unassigned » dmakal

I'll get this into the module.

splash112’s picture

CCK money field does a very good job at showing currencies (type, amount and sign)
Currency API and units could also be very helpfull...

mertskeli’s picture

While checking base_price_price noticed 5-digit decimals (i.e. 100$ stored as 100.00000. Is it necessary? Even the strongest Kuwaiti currency can not occupy more than 3 decimals compared to $.
As for max value, 1,000,000,000,000.00 looks a bit optimistic...

rszrama’s picture

hehe Yeah, that's a temporary column definition. The reason you store more decimals than are necessary is for tax purposes - storing a value with greater precision allows you to add / round appropriately later on when totally the value of an order.

Mac_Weber’s picture

Another way we could do it is instead of programming every single currency, just let the user to give the parameters to include a new currency. Even in case of programming each currency, I think this feature would also be important, for example in some countries that have weak currencies (I remember Brazil about 20 years ago), where it changes relatively frequent.

This customization would also allow other changes like the personal preference how negative numbers would appear (-R$300,00 R$-300,00; using automatic color or red for negative; maybe even different colors for different currencies, which makes it easier on spreadsheets to not get lost)

neokrish’s picture

@rszrama do you propose to add all the currencies of the world in the module code as in commerce.module like below?

    $currencies = array(
      'EUR' => array(
        'numeric_code' => 978,
        'code' => 'EUR',
        'name' => t('Euro'),
        'symbol' => '€',
        'fraction_name' => t('Cent'),
        'decimal_separator' => ',',
        'thousands_separator' => ' ',
        'symbol_placement' => 'after',
      ),
      'USD' => array (
        'numeric_code' => 840,
        'code' => 'USD',
        'name' => t('United States Dollars'),
        'symbol' => '$',
        'fraction_name' => t('Cent'),
        'symbol_placement' => 'before',
      ),
    );

This is another low-hanging that I could do. However, I am little doubtful if in the longrun, is it not better to have it on database via some import script that loads the latest currency list?

das-peter’s picture

What about to define stuff like this in drupal/includes/iso.inc? Language and country codes are already defined there.
The question is, if the formatting rules also should be defined there.
My first idea was to fetch the currency-codes from a function in iso.inc and add the formatting rules by fetching them with something php-internal like this:

$current_locale = setlocale(LC_ALL, 0);
setlocale(LC_MONETARY, 'USD');
$currency_format = localeconv();
setlocale(LC_ALL, $current_locale);

Unfortunately, setlocale() seems to be to limited to work like this. Especially the fact that the keys, it works with, differ from platform to platform.
But I'm not 100% sure there's no way to do the trick.

Maybe it's even better to add the formatting rules to the iso.inc too - to ensure system wide consistency .

rszrama’s picture

Hmm, I hadn't looked in iso.inc before. Will do that today. : D

das-peter’s picture

@Ryan: Since I have to start working with currencies now, I added the ones needed for my project.
Could we add them, even if it's not the final solution?

Attached patch is git-style - hope that works too. Otherwise I could send you a pull request on github.

rszrama’s picture

Added those. I should take care of these currency issues as part of the pricing stuff...

das-peter’s picture

Yay - It's done.
I've created a list with every currency ever needed. ;)
One patch contains even deprecated currencies - but I don't know if we have usage for this.

I worked as clean as possible, but there's no guarantee for the completeness and correctness of the data.
Formatting is a special issue - thus symbol_placement and code_placement are always defined as before.
What I could do, is to remove all array key/values which are equal to the ones defined in $defaults - but I'm not sure what's better for performance.

dj1999’s picture

FileSize
6.26 KB

Hi,

I was made something to currencies, please check it.

Joe

recidive’s picture

Status: Active » Needs review

In the patch in #14, 'code' and 'symbol' properties are messed up, sometimes code contains symbol values and vice versa. That seems fixed in the patches in #16.

Here are some suggestions for the patches in #16:

1. It's time to put this data on a separate file, and include it only on required pages or better include it only on admin/commerce/config/currency page
2. Cache the enabled currencies to avoid including the currencies include file often
3. Add constants for 'before' and 'after' values
4. Make some conventions, adding default values to properties, e.g. default symbol and code placement to 'before', to reduce currencies array size

Also, why there's a 'code' property when you have this as the array key, are there cases where those values are different?

rszrama’s picture

Awesome patch in #17 and feedback from recidive. I hadn't even thought about using a cache instead of just loading the include every time. : )

I'll start with getting the active currency list into the code and then see where we go from there. Adding sensible defaults will be easy enough (though I was already doing that, whoops). The code is part of the array because the load function returns a single currency object, and if that needs to be passed as a parameter to other functions or something it's helpful to have the code baked into the object instead of having to pass the code, too.

rszrama’s picture

Actually, I can't get the patch in #16 to apply because I corrected the bugs in #14 when I committed. ; )

das-peter, is there any way you can re-roll against HEAD w/ the patch in #14 in?

das-peter’s picture

rszrama: Sure here's a rerolled patch. But I'm not sure if this one works - I'm still a git trainee.
If you really want to integrate deprecated currencies - let me know ;)

rszrama’s picture

I did forget to respond to dj1999 - thanks for posting up the concept of currency storage in the database. I'm thinking it's best to keep this sort of data out of the database and in module files where it's easier to manage alterations but especially translations. Strings stored in the database aren't as straightforward to translate into other languages as those in module files wrapped in the t() function (and a few other related functions).

Peter, will give that patch a go here in a bit. Thanks for re-rolling it. : )

rszrama’s picture

Status: Needs review » Needs work

Ok, I just committed das-peter's patch from #21 then followed it up by moving the currency definition code into an include file, loading it via a hook (so new currencies can be defined properly instead of just altered in), and removing any 'decimals' => 2 strings from the currency arrays (that was already defaulted).

I'd like to remove more from the currency definition array with some sensible defaults, so I'll need some follow-up help. My thinking on currency definition is we should define how the currency would natively be formatted in your country. This means a EUR definition would look like this:

    'EUR' => array(
      'code' => 'EUR',
      'numeric_code' => 978,
      'symbol' => '€',
      'name' => t('Euro'),
      'minor_unit' => t('Cent'),
      'major_unit' => t('Euro'),
      'thousands_separator' => ' ',
      'decimal_separator' => ',',
      'symbol_placement' => 'after',
    ),

Because prices in France would appear like so: 15,99 €

The definitions from das-peter's patch all have the format [CODE] [SYMBOL] xx.xx. That might be sufficient for administrative displays, but I'd prefer us to use the country's display. I think perhaps we can setup a default that doesn't display the symbol and only displays the code after the number for starters. Then as people start using this, they can tell us "Hey, my prices actually look like _____."

Obviously we'll then need some sort of display formatter setting or something that allows multi-currency stores to differentiate between $10.00 USD and $10.00 CAD.

Also, I'm not sure what the 'rounding' property is... can you let us know? I think that might be from a patch you had elsewhere to address differences in rounding, but I can't remember where it was. : )

I think we might also need to convert all 'numeric_code' properties to strings. I believe the standard calls for leading 0's for numbers < 100, and we don't want to have mixed data types with some being strings to preserve the leading 0 and others being integers.

Be sure to pull the changes / update from CVS HEAD before posting additional patches. : )

das-peter’s picture

Since the currencies are cached now, I fully agree with reduce the size of the currency array in the code. Without the cache, I was not sure about the performance impact of processing defaults.
But now let's define defaults - but how far? We could even use t('Cent') for minor_unit as default since it's the most appearing minor_unit. :)

Problem with the symbol / code placement is, that there seems no consensus about how to format.
I spent some time looking for proper definitions but couldn't find any.
A good example is the Euro, it seems that each country has it's own display format and not even within a country there's a official format as far as I know (Wiki Article).
Thus defining a default and provide a hook to alter the format seems the best solution at the moment.

To generate the currency array I used information from the ZendFramework (Zend_Currency) and extendet them manually.
Maybe there are other good approaches how to deal with country/currency/format.

#958944: Add currency specific rounding
The rounding property defines the rounding steps to use. E.g. Swiss Francs are rounded using 0.05 steps - there's no price like 11.93, it's converted to 11.95.

The numeric_code values prefixed with a 0 are defined as string. This is a sideeffect of my code generator I used to create the array. Valid integers are keept as integers, but values starting with a 0 are handled as string.

Pulled & merged changes from github ;)

rszrama’s picture

So, I'm thinking since some numeric codes need to be strings we should convert them all to strings, esp. since we'll never need to use these numbers in arithmetic (if at all). Also, how does [amount] [currency_code] sound as a default format for currencies? We could then provide currency specific formats for the currencies we know about or people patch, i.e. $10.00 or 45,00 €. Also, I notice some symbols have abbreviations in them, particularly currencies besides USD that use the $ as their symbol. I think we should only include the abbreviations if those letters are actually used in the currency's home country (for currencies that have a "home country").

das-peter’s picture

Sounds fine to me. And the formatting will be easy to understand :)
The attached patch defines all numeric_codes as string. I've also reviewed an issue with special chars - they were lost, especially currency symbols were replaced by questionmarks. I've inserted the correct symbols again - please keep an eye on them while merging. Maybe git doesn't like them :|

rszrama’s picture

Committed... not sure what happened to those currency codes. : ?

What do you think about defaulting the currencies to all have code_placement => after and symbol_placement just left off unless we know of a specific "regular" format?

das-peter’s picture

Absolutely fine with me. If nobody has a reason to reject this format, just apply the patch :)

dj1999’s picture

FileSize
34.87 KB
596 bytes

This is just change of HUF because we don't use in Hungary minor_unit and default is 'after' of symbol.

I think it is disturbing if code and symbol together using.

rszrama’s picture

Assigned: dmakal » Unassigned
Status: Needs work » Fixed

Excellent! Got both patches in. : )

I also made some changes based on mikl's fork in GitHub - many thanks to all of you. Now I'm going to make an FAQ section for reporting missing / incorrect currency formats. : D

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

BenK’s picture

Keeping track of this thread