Reputation: 528
I'm adding multi-currency support to an e-commerce application. The way I approached the problem was to keep the application in it's base currency and have the template call a priceDisplay() function/plugin anytime it displays a price. So the template continues to receive prices in dollar amounts. The priceDisplay function correctly converts the price if needed and adds the correct $ or Euro sign depending on the viewers settings, stored in the session. On order submit, the application will store the order in dollar amount as well as the currencyCode and currencyRate. Additionally we will charge the customer's credit card in their currency to ensure they get billed exactly what was shown on the order screen.
Now the issue I am having is when displaying the cart totals in the cart as well as during checkout. As an example, the application sends the template the prices to display in the shopping cart:
subtotal: 9.75
ship: 5.95
total: 15.70
The template takes these amounts and calls the priceDisplay function on each item. If the currency rate is 1.1, then we get displayed to the user:
subtotal: 10.725 -> 10.73
ship: 6.545 -> 6.55
total: 17.27
You can see that the subtotal + ship = 17.28, but the total converted is 17.27.
So couple of options I think could work, though not thought all the way through:
If it makes any difference, application is in PHP and template is Smarty.
You can also see the same issue in adding the line totals of the cart items:
3 items x 9.75 each = 29.25
converted:
3 items x 10.73 (10.725) = 32.18 (32.175)
but 3 x 10.73 = 32.19 != 32.18
Upvotes: 3
Views: 2199
Reputation: 170745
Don't use floating point numbers for money, ever! You are letting yourself into a world of hurt with rounding for no good reason. Since PHP doesn't have a decimal fixed point type, do all money calculations with integers. See William's links.
Upvotes: 0
Reputation: 3673
I'm firmly in the 1 camp. Currency conversion is core business logic, and belongs in your models, not your views.
Further, although money looks like floating-point numbers, it isn't. Money changes hands in integer quantities of whatever your base unit is. In the US, for example, If gumballs are 10 cents each and I buy ten, then I'm trading 100 pennies for 10 gumballs. Even if I give a dollar bill, from a software perspective, it's best to count that as 100 pennies.
For more on this, see Martin Fowler's "Patterns of Enterprise Application Architecture" and "Analysis Patterns". He talks through all the issues in detail and gives good sample code. You can also find some of that info on the web:
If you need the accounting to work, I'd also talk to the accountant. Currency conversion is often complicated by changing rates, weird fees, and other nonsense, and you can spend a long time chasing pennies to make the books balance if you don't get it right from the get-go.
Upvotes: 6
Reputation: 1375
If you are billing based on the converted currency, you really shouldn't be doing that calculation in your view logic.
Upvotes: 1
Reputation: 17099
Well personally, I would just make the total amount, the subtotal added to the ship amount. This is obviously the simplest method to use, and no-one will miss the extra penny.
Upvotes: 0