ctilley79
ctilley79

Reputation: 2195

Ruby/Rails How to Calculate and Round Prices?

Developing an invoice, I am running into math rounding issues where my unit prices and totals are not adding up perfectly. The issue comes because of a business requirement where a hidden commission is passed down to the customer based on certain conditions. I have to go behind the scenes and multiply every price and total by the commission percentage.

For example the unrounded calculated price multiplied by a commission for example.

Item            Name         qty    Price2  qty2    Price   Total
Kitchen Counter Uba Tuba     100.0  72.4275 100.0   18.125  9055.249999999999   9055.249999999999
Vanity          Uba Tuba     100.0  72.4275 100.0   18.125  9055.249999999999   9055.249999999999
                                        Grand Total         18110.5

Now using rails number_to_currency helper applied, the numbers are off

Kitchen Counter Uba Tuba     100.0  $72.43  100.0   $18.13  1   $9,055.25   $9,055.25
Vanity          Uba Tuba     100.0  $72.43  100.0   $18.13  1   $9,055.25   $9,055.25

Due to the rounding of the prices, if a customer does their own math, the totals are off.

rounded total = $9056.00

How do you solve this programmatically?

Upvotes: 0

Views: 1682

Answers (2)

Patrick Oscity
Patrick Oscity

Reputation: 54704

If you want to eliminate the rounding error in the line item total, you need to round the discounted unit prices to two decimals before calculating the total, i.e.

qty = 100.0
price = 18.125
qty2 = 100.00
price2 = 72.4275

total = qty * price.round(2) + qty2 * price2.round(2)
total.round(2) # happens in number_to_currency
#=> 9056.0

instead of what you're currently doing

total = qty * price + qty2 * price2
total.round(2) # happens in number_to_currency
#=> 9055.25

Upvotes: 1

xlembouras
xlembouras

Reputation: 8295

Maybe the money and the money-rails gems will be of use!

If you want to do things manually, you should consider storing your prices as Integer values! Where a price of x would mean x $ cents or x tens of $ cents. By doing that you can get rid of all the rounding provblems in your db.

Also the use of number_to_currency helper will help you display things properly to your views.

Upvotes: 2

Related Questions