If you create a product kit with, say, 20 products and a total price of $19.95, each product has some irrational number as its price (19.95/20). Everything works out price-wise until you get to the payment confirmation page, where it shows you that you ordered one product for $19.95 and your subtotal is $19.96.

The one cent discrepancy can occur in either direction, and only with certain combinations of prices and product numbers.

I found it occurs because when the order is saved into the uc_order_products table, each product in the product kit is saved along with its price. The price db field stores 3 places beyond the decimal point. When there are many products, those 3 places are not enough to ensure the correct pricing total when you add up all the product prices for the kit.

Each price gets rounded into that table by as much as 0.05 cents. Therefore once you have 20 products, you can be off by one cent. If you add another decimal point to the field then it would take more like 200 products to run into trouble. So, I think we should have at least 5 decimal places, just to be safe. If anyone puts 2000 products in their kit, their server will probably explode anyway due to all the node loads that would be happening all at once.

db_query("ALTER TABLE {uc_order_products} CHANGE price price DECIMAL(15, 5) NOT NULL DEFAULT '0.000'");

I think this is a product-kit-specific problem because a real product would not have a crazy long number for its price.

Comments

longwave’s picture

Decimal rounding is an issue across other parts of Ubercart too, perhaps this should be dealt with as part of #479784: Order rounding?

Island Usurper’s picture

Status: Active » Closed (duplicate)

Yeah, I think we can deal with all of the price fields at once in that issue.