multiple currency (price) support... l10n Country + Price

Issue #437 new
Former user created an issue

Satchmo needs support for more than one currency at a time. Pricing versatility is important.

First, we need to add a currency code field (ISO 4217 3 character currency code) for each country in the l10n app's Country model. I've done this below. Next, changes to the Price model need to be made to support multiple currencies. (There should be automated exchange rate updating support and support for custom set prices in different currencies, right?)

I am making the assumption that every country has a national currency, and that there is a 1 to 1 relationship between countries and currencies. Therefore, we can include the currency code in the Country model, rather than making a separate Currency model that has a many-to-one relationship with Country...

{{{
Index: satchmo/l10n/models.py
===================================================================
--- satchmo/l10n/models.py (revision 1298)
+++ satchmo/l10n/models.py (working copy)
@@ -58,6 +58,9 @@
active = models.BooleanField(('Country is active'), default=True)
continent = models.CharField(
('Continent'), choices=CONTINENTS, max_length=2)
admin_area = models.CharField(('Administrative Area'), choices=AREAS, max_length=2, null=True, blank=True)
+ # ISO 4217 currency code.
+ # These are not unique: for example, EUR (Euros) are multiple countries' currency...
+ iso4217_currency = models.CharField(
('ISO Currency'), max_length=3)

 class Meta:
     verbose_name = _('Country')

}}}

I searched but couldn't find a ticket for multiple currency support. If there's one already, please let me know so I can contribute there instead of starting from scratch...

Reported by ido

Comments (24)

  1. Former user Account Deleted

    No further progress due to time constraints on my part. If anyone else would like to take this over, feel free, otherwise I'll get back to this in late November/early December.

  2. mk

    Any progress and/or additional comments here? What's the plan? I'm developing a new shop using Satchmo that will run in only one currency in the beginning but will soon have to be extended to support several (at least two). I have collected some experience with another multi-currency shop that I've implemented with Satchmo, but the code and especially the database schema are far too ugly to be integrated into mainline let alone be published.

  3. Former user Account Deleted

    Since the above diff does not change any preexisting models, you may apply it to trunk whenever you want. I'll continue assuming that the above code is locked.

    My next update will change how prices/money is handled, so it will be more substantial. I'll try to post as I go along to avoid code bombs.

  4. Former user Account Deleted

    Great. Thanks!

    ISO 4217 does have a country name (though some currencies, such as gold/XAU, do not have one associated with them). Therefore, I wanted currency as an optional (nullable) field in Country. ISO4217 actually defines a default country / entity to which a currency is related (usually a country's central bank / monetary policy setter), so I've removed the default currency in Country and added an entity field in Currency so it matches the ISO4217 list more closely...

    I also agree that the currencies should be explicitly set and not implied by the localized country. Ideally, prices will be set and (simultaneously) displayed in multiple currencies.

    Index: satchmo/l10n/models.py
    ===================================================================
    --- satchmo/l10n/models.py	(revision 1298)
    +++ satchmo/l10n/models.py	(working copy)
    @@ -74,6 +74,30 @@
             return self.printable_name
     
     
    +class Currency(models.Model):
    +    """
    +    International Organization for Standardization (ISO) 4127 Currency list
    +    """
    +    # http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/
    +    # http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=41270
    +    # http://www.iso.org/iso/iso_catalogue/catalogue_ics/catalogue_detail_ics.htm?csnumber=46121
    +    #
    +    # entity is just the default currency for the entity/country as per ISO4217.
    +    entity = models.ForeignKey(Country, null=True)
    +    name = models.CharField(_('Currency name'), max_length=128, unique=True)
    +    iso3_code = models.CharField(_('ISO alpha-3'), max_length=3, unique=True)
    +    num_code = models.PositiveSmallIntegerField(_('ISO numeric'), null=True, blank=True, unique=True)
    +
    +    class Meta:
    +        verbose_name = _('Currency')
    +        verbose_name_plural = _('Currencies')
    +        ordering = ('iso3_code',)
    +
    +    class Admin:
    +        list_display = ('name','iso3_code')
    +        search_fields = ('name', 'iso3_code')
    +
    +
     class AdminArea(models.Model):
         """
         Administrative Area level 1 for a country.  For the US, this would be the states
    
  5. Former user Account Deleted

    Your last model looks good. Two suggestions:

    • Rename numcode to num_code.
    • Country's relation to Currency is inaccurate, since there are in fact countries where multiple currencies are used.
    • Store owners should explicitly select which Currencies they want to sell in, and not just the Countries. The only use that I can see for relating Country to Currency is to be able to suggest currencies that the store admin may want to use. If that is the case, then I would hold off relating Country and Currency until there is implemented code that requires it.
  6. Former user Account Deleted

    I don't want to throw code bombs, so I'll wait until I get some feedback or a go-ahead before submitting any more code.

  7. Former user Account Deleted

    Okay, this one doesn't break the current fixtures and can be thrown into trunk right away probably... I'll modify the l10n fixtures when I get a chance to add currencies into them from the ISO4127 list.

    Index: satchmo/l10n/models.py
    ===================================================================
    --- satchmo/l10n/models.py	(revision 1298)
    +++ satchmo/l10n/models.py	(working copy)
    @@ -46,6 +46,26 @@
     
     
     
    +class Currency(models.Model):
    +    """
    +    International Organization for Standardization (ISO) 4127 Currency list
    +    """
    +    # http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/
    +    # http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=41270
    +    # http://www.iso.org/iso/iso_catalogue/catalogue_ics/catalogue_detail_ics.htm?csnumber=46121
    +    name = models.CharField(_('Currency name'), max_length=128, unique=True)
    +    iso3_code = models.CharField(_('ISO alpha-3'), max_length=3, unique=True)
    +    numcode = models.PositiveSmallIntegerField(_('ISO numeric'), null=True, blank=True, unique=True)
    +
    +    class Meta:
    +        verbose_name = _('Currency')
    +        verbose_name_plural = _('Currencies')
    +        ordering = ('iso3_code',)
    +
    +    class Admin:
    +        list_display = ('name','iso3_code')
    +        search_fields = ('name', 'iso3_code')
    +
     class Country(models.Model):
         """
         International Organization for Standardization (ISO) 3166-1 Country list
    @@ -58,6 +78,7 @@
         active = models.BooleanField(_('Country is active'), default=True)
         continent = models.CharField(_('Continent'), choices=CONTINENTS, max_length=2)
         admin_area = models.CharField(_('Administrative Area'), choices=AREAS, max_length=2, null=True, blank=True)
    +    currency = models.ForeignKey(Currency, null=True)
     
         class Meta:
             verbose_name = _('Country')
    @@ -73,7 +94,6 @@
         def __unicode__(self):
             return self.printable_name
     
    -
     class AdminArea(models.Model):
         """
         Administrative Area level 1 for a country.  For the US, this would be the states
    
  8. Former user Account Deleted
    Index: satchmo/l10n/models.py
    ===================================================================
    --- satchmo/l10n/models.py	(revision 1298)
    +++ satchmo/l10n/models.py	(working copy)
    @@ -46,6 +46,26 @@
     
     
     
    +class Currency(models.Model):
    +    """
    +    International Organization for Standardization (ISO) 4127 Currency list
    +    """
    +    # http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/
    +    # http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=41270
    +    # http://www.iso.org/iso/iso_catalogue/catalogue_ics/catalogue_detail_ics.htm?csnumber=46121
    +    name = models.CharField(_('Currency name'), max_length=128, unique=True)
    +    iso3_code = models.CharField(_('ISO alpha-3'), max_length=3, unique=True)
    +    numcode = models.PositiveSmallIntegerField(_('ISO numeric'), null=True, blank=True, unique=True)
    +
    +    class Meta:
    +        verbose_name = _('Currency')
    +        verbose_name_plural = _('Currencies')
    +        ordering = ('iso3_code')
    +
    +    class Admin:
    +        list_display = ('name','iso3_code')
    +        search_fields = ('name', 'iso3_code')
    +
     class Country(models.Model):
         """
         International Organization for Standardization (ISO) 3166-1 Country list
    @@ -58,6 +78,7 @@
         active = models.BooleanField(_('Country is active'), default=True)
         continent = models.CharField(_('Continent'), choices=CONTINENTS, max_length=2)
         admin_area = models.CharField(_('Administrative Area'), choices=AREAS, max_length=2, null=True, blank=True)
    +    currency = models.ForeignKey(Currency)
     
         class Meta:
             verbose_name = _('Country')
    @@ -73,7 +94,6 @@
         def __unicode__(self):
             return self.printable_name
     
    -
     class AdminArea(models.Model):
         """
         Administrative Area level 1 for a country.  For the US, this would be the states
    
  9. Former user Account Deleted
    Index: models.py
    ===================================================================
    --- models.py	(revision 1298)
    +++ models.py	(working copy)
    @@ -58,6 +58,7 @@
         active = models.BooleanField(_('Country is active'), default=True)
         continent = models.CharField(_('Continent'), choices=CONTINENTS, max_length=2)
         admin_area = models.CharField(_('Administrative Area'), choices=AREAS, max_length=2, null=True, blank=True)
    +    currency = models.ForeignKey(Currency)
     
         class Meta:
             verbose_name = _('Country')
    @@ -73,7 +74,26 @@
         def __unicode__(self):
             return self.printable_name
     
    +class Currency(models.Model):
    +    """
    +    International Organization for Standardization (ISO) 4127 Currency list
    +    """
    +    # http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/
    +    # http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=41270
    +    # http://www.iso.org/iso/iso_catalogue/catalogue_ics/catalogue_detail_ics.htm?csnumber=46121
    +    name = models.CharField(_('Currency name'), max_length=128, unique=True)
    +    iso3_code = models.CharField(_('ISO alpha-3'), max_length=3, unique=True)
    +    numcode = models.PositiveSmallIntegerField(_('ISO numeric'), null=True, blank=True, unique=True)
     
    +    class Meta:
    +        verbose_name = _('Currency')
    +        verbose_name_plural = _('Currencies')
    +        ordering = ('iso3_code')
    +
    +    class Admin:
    +        list_display = ('name','iso3_code')
    +        search_fields = ('name', 'iso3_code')
    +
     class AdminArea(models.Model):
         """
         Administrative Area level 1 for a country.  For the US, this would be the states
    
  10. Former user Account Deleted

    Is this being looked at all? I noticed the original Trac ticket was from about 12 months ago and last updated pre-xmas?

    I'm looking at deploying Satchmo for a client who is absolutely running multiple currencies right from the outset. If there hasn't been a solution provided perhaps an update of where this is and we'll look at implementing it as we're definitely going Satchmo but HAVE to have multi-currency option as it's an international store (min AUD, NZD, SGD, USD, GBP and YEN)

    Any info would be very appreciated.

    @Andrew Fisher

  11. Chris Moffitt repo owner

    To answer your question, there's no active work going on right now. My suggestion would be to setup a fork on bitbucket to integrate these ideas and get them working, tested and documented. Then, we can look at pulling back into Satchmo.

  12. Former user Account Deleted

    Hi Chris,

    Thanks for the update on that. We'll definitely need it for what we are going to do with this client and it looks like they aren't the only one in our current pipeline (most Aussie companies trade in New Zealand and Singapore as well you see) so I this we'll take a crack at this and flick it back.

    For where you're at given the movement that has been made since this item was opened, is there any further direction you'd want to take knowing where you're at now as opposed to nearly a year ago? If we do this I'd want to make sure it ties in with the direction of the project.

    Cheers @Andrew Fisher

  13. Former user Account Deleted

    Hi, is there anyone working on this? Has this been partially implemented?

    Is there a branch living somewhere that I could study and fork if I think I'm up to it?

    I know that many non EURO or dollar countries have to offer foreigners the possiblility to pay with and see prices in a well know currency as well as the local currency. This always comes up for me.

  14. Chris Moffitt repo owner

    There isn't any active work going on in this area now. My recommendation would be to make a fork and start applying these patches and get it to a working state. Then, we can look at merging back.

  15. hejsan

    Ok, how about this fork called satchmo-currency, do you know if thats a trusted/solid branch to adapt?

  16. Chris Moffitt repo owner

    I don't know much about that branch. It's probably worth a look but it probably needs some work to bring it up to synch with tip.

  17. Log in to comment