From 7f260ab517ebde634fc274e928eb062463f0d88f Mon Sep 17 00:00:00 2001 From: Joren Van Onder Date: Tue, 28 Mar 2017 16:42:56 -0700 Subject: [PATCH] [FIX] point_of_sale: round product.product price analogous to backend A rounding issue was resolved in ee33593351a148d0f678b36fc01e8524fe1452b6. It however introduced another issue. Rounding functions (both round_precision in web.utils and float_round in openerp.tools) are not perfect due to IEEE floating point limitations. However both should produce the same output given the same input. An example: rounding 13.95 to 2 digits yields 13.950000000000001. The additional rounding introduced in ee33593351a148d0f678b36fc01e8524fe1452b6 on price lead to issues in certain cases. One example occurs when applying a 90% discount on a product costing 13.95. The POS will do the following: > 13.950000000000001 * 0.09999999999999998 1.3949999999999998 > round_pr(1.3949999999999998, .01) 1.4000000000000001 whereas the backend will do (as eg. in sale.order.line) >>> 13.95 * 0.09999999999999998 1.3949999999999996 >>> round(1.3949999999999996, 2) 1.3900000000000001 Causing a difference of 0.01. The core of the issue is that in the backend 13.95 is rounded differently. When a Float gets written to the database doesn't just pass through the regular float_round. It passes through _symbol_set_float which truncates characters exceeding the precision. This implements the same approach in the POS. opw-715506 Closes #16119 --- addons/point_of_sale/static/src/js/models.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 4f753ffcb6e..c35baad9e7e 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -821,7 +821,9 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal this.trigger('change',this); }, get_unit_price: function(){ - return round_di(this.price || 0, this.pos.dp['Product Price']) + var digits = this.pos.dp['Product Price']; + // round and truncate to mimic _sybmbol_set behavior + return parseFloat(round_di(this.price || 0, digits).toFixed(digits)); }, get_base_price: function(){ var rounding = this.pos.currency.rounding;