From 2c5ce41c423e6ab92053b1f082086035bdc151f8 Mon Sep 17 00:00:00 2001
From: yhu-odoo <yhu@odoo.com>
Date: Mon, 17 Aug 2020 08:45:28 +0000
Subject: [PATCH] [IMP] uom: change default rounding to two

Change the default rouning digits of all UoMs to be two, also change the
decimal.precision of UoM to be two. Adapt all the tests.
Also to avoid hardcoded digits in `should_consume_qty` widget.

PR #56000

X-original-commit: 460ec0402a2352a5b179d81935f7230f6bc97cb7
---
 addons/mrp/models/mrp_production.py           |  2 +-
 addons/mrp/models/stock_move.py               |  2 +-
 .../mrp/static/src/js/mrp_should_consume.js   |  3 +-
 addons/mrp/tests/test_order.py                | 63 -------------------
 addons/mrp/tests/test_traceability.py         |  2 +-
 addons/mrp/views/mrp_production_views.xml     |  2 +-
 .../static/tests/tours/point_of_sale.js       |  4 +-
 addons/product/data/product_data.xml          |  2 +-
 .../tours/purchase_product_matrix_tour.js     |  4 +-
 addons/sale/tests/test_sale_to_invoice.py     |  8 +--
 addons/sale_mrp/tests/test_sale_mrp_flow.py   | 10 +--
 .../tours/product_configurator_edition_ui.js  |  2 +-
 .../tests/tours/sale_product_matrix_tour.js   |  4 +-
 addons/stock/tests/test_packing.py            |  4 +-
 addons/stock/tests/test_stock_flow.py         |  2 +
 addons/uom/data/uom_data.xml                  |  2 -
 addons/uom/tests/test_uom.py                  |  2 +-
 17 files changed, 26 insertions(+), 92 deletions(-)

diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py
index 4b1703e4da5e..250935da182f 100644
--- a/addons/mrp/models/mrp_production.py
+++ b/addons/mrp/models/mrp_production.py
@@ -102,7 +102,7 @@ class MrpProduction(models.Model):
     lot_producing_id = fields.Many2one(
         'stock.production.lot', string='Lot/Serial Number', copy=False,
         domain="[('product_id', '=', product_id), ('company_id', '=', company_id)]", check_company=True)
-    qty_producing = fields.Float(string="Quantity Producing", copy=False)
+    qty_producing = fields.Float(string="Quantity Producing", digits='Product Unit of Measure', copy=False)
     product_uom_category_id = fields.Many2one(related='product_id.uom_id.category_id')
     product_uom_qty = fields.Float(string='Total Quantity', compute='_compute_product_uom_qty', store=True)
     picking_type_id = fields.Many2one(
diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py
index 2f76496467c4..044c6208fc99 100644
--- a/addons/mrp/models/stock_move.py
+++ b/addons/mrp/models/stock_move.py
@@ -107,7 +107,7 @@ class StockMove(models.Model):
         store=True,
         help='Technical Field to order moves')
     order_finished_lot_ids = fields.Many2many('stock.production.lot', string="Finished Lot/Serial Number", compute='_compute_order_finished_lot_ids')
-    should_consume_qty = fields.Float('Quantity To Consume', compute='_compute_should_consume_qty')
+    should_consume_qty = fields.Float('Quantity To Consume', compute='_compute_should_consume_qty', digits='Product Unit of Measure')
 
     def _unreserve_initial_demand(self, new_move):
         # If you were already putting stock.move.lots on the next one in the work order, transfer those to the new move
diff --git a/addons/mrp/static/src/js/mrp_should_consume.js b/addons/mrp/static/src/js/mrp_should_consume.js
index dcf236a09f11..d432c5cf3f73 100644
--- a/addons/mrp/static/src/js/mrp_should_consume.js
+++ b/addons/mrp/static/src/js/mrp_should_consume.js
@@ -20,8 +20,7 @@ const MrpShouldConsume = FieldFloat.extend({
     init: function (parent, name, params) {
         this._super.apply(this, arguments);
         this.displayShouldConsume = !['done', 'draft', 'cancel'].includes(params.data.state);
-        const options = {'digits': [false, 3]};
-        this.should_consume_qty = field_utils.format.float(params.data.should_consume_qty, false, options);
+        this.should_consume_qty = field_utils.format.float(params.data.should_consume_qty, params.fields.should_consume_qty, this.nodeOptions);
     },
 
     //--------------------------------------------------------------------------
diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py
index a7e024f146e8..940aedfd5eef 100644
--- a/addons/mrp/tests/test_order.py
+++ b/addons/mrp/tests/test_order.py
@@ -1118,69 +1118,6 @@ class TestMrpOrder(TestMrpCommon):
         details_operation_form.save()
         mo2.button_mark_done()
 
-    def test_product_produce_uom(self):
-        """ Produce a finished product tracked by serial number. Set another
-        UoM on the bom. The produce wizard should keep the UoM of the product (unit)
-        and quantity = 1."""
-        dozen = self.env.ref('uom.product_uom_dozen')
-        unit = self.env.ref('uom.product_uom_unit')
-        plastic_laminate = self.env['product.product'].create({
-            'name': 'Plastic Laminate',
-            'type': 'product',
-            'uom_id': unit.id,
-            'uom_po_id': unit.id,
-            'tracking': 'serial',
-        })
-        ply_veneer = self.env['product.product'].create({
-            'name': 'Ply Veneer',
-            'type': 'product',
-            'uom_id': unit.id,
-            'uom_po_id': unit.id,
-        })
-        bom = self.env['mrp.bom'].create({
-            'product_tmpl_id': plastic_laminate.product_tmpl_id.id,
-            'product_uom_id': unit.id,
-            'sequence': 1,
-            'bom_line_ids': [(0, 0, {
-                'product_id': ply_veneer.id,
-                'product_qty': 1,
-                'product_uom_id': unit.id,
-                'sequence': 1,
-            })]
-        })
-
-        mo_form = Form(self.env['mrp.production'])
-        mo_form.product_id = plastic_laminate
-        mo_form.bom_id = bom
-        mo_form.product_uom_id = dozen
-        mo_form.product_qty = 1
-        mo = mo_form.save()
-
-        final_product_lot = self.env['stock.production.lot'].create({
-            'name': 'lot1',
-            'product_id': plastic_laminate.id,
-            'company_id': self.env.company.id,
-        })
-
-        mo.action_confirm()
-        mo.action_assign()
-        self.assertEqual(mo.move_raw_ids.product_qty, 12, '12 units should be reserved.')
-
-        # produce product
-        mo_form = Form(mo)
-        mo_form.qty_producing = 1/12.0
-        mo_form.lot_producing_id = final_product_lot
-        mo = mo_form.save()
-
-        move_line_raw = mo.move_raw_ids.mapped('move_line_ids').filtered(lambda m: m.qty_done)
-        self.assertEqual(move_line_raw.qty_done, 1)
-        self.assertEqual(move_line_raw.product_uom_id, unit, 'Should be 1 unit since the tracking is serial.')
-
-        mo._post_inventory()
-        move_line_finished = mo.move_finished_ids.mapped('move_line_ids').filtered(lambda m: m.qty_done)
-        self.assertEqual(move_line_finished.qty_done, 1)
-        self.assertEqual(move_line_finished.product_uom_id, unit, 'Should be 1 unit since the tracking is serial.')
-
     def test_product_type_service_1(self):
         # Create finished product
         finished_product = self.env['product.product'].create({
diff --git a/addons/mrp/tests/test_traceability.py b/addons/mrp/tests/test_traceability.py
index ea861c2cefe1..502cac0519d6 100644
--- a/addons/mrp/tests/test_traceability.py
+++ b/addons/mrp/tests/test_traceability.py
@@ -107,7 +107,7 @@ class TestTraceability(TestMrpCommon):
             for line in lines:
                 tracking = line['columns'][1].split(' ')[1]
                 self.assertEqual(
-                    line['columns'][-1], "1.000 Units", 'Part with tracking type "%s", should have quantity = 1' % (tracking)
+                    line['columns'][-1], "1.00 Units", 'Part with tracking type "%s", should have quantity = 1' % (tracking)
                 )
                 unfoldable = False if tracking == 'none' else True
                 self.assertEqual(
diff --git a/addons/mrp/views/mrp_production_views.xml b/addons/mrp/views/mrp_production_views.xml
index b05c6970e550..c45c6524027e 100644
--- a/addons/mrp/views/mrp_production_views.xml
+++ b/addons/mrp/views/mrp_production_views.xml
@@ -151,7 +151,7 @@
                             <label for="product_qty" string="Quantity"/>
                             <div class="o_row no-gutters d-flex">
                                 <div attrs="{'invisible': [('state', '=', 'draft')]}" class="o_row">
-                                    <field name="qty_producing" digits="[12,3]" class="text-left"  attrs="{'readonly': ['|', ('state', '=', 'cancel'), '&amp;', ('state', '=', 'done'), ('is_locked', '=', True)]}"/>
+                                    <field name="qty_producing" class="text-left" attrs="{'readonly': ['|', ('state', '=', 'cancel'), '&amp;', ('state', '=', 'done'), ('is_locked', '=', True)]}"/>
                                     /
                                 </div>
                                 <field name="product_qty" class="oe_inline text-left" attrs="{'readonly': [('state', '!=', 'draft')], 'invisible': [('state', 'not in', ('draft', 'done'))]}"/>
diff --git a/addons/point_of_sale/static/tests/tours/point_of_sale.js b/addons/point_of_sale/static/tests/tours/point_of_sale.js
index fe2b8e5e6636..2380fef68b97 100644
--- a/addons/point_of_sale/static/tests/tours/point_of_sale.js
+++ b/addons/point_of_sale/static/tests/tours/point_of_sale.js
@@ -408,10 +408,8 @@ odoo.define('point_of_sale.tour.acceptance', function (require) {
     steps = steps.concat(selected_orderline_has({product: 'Desk Organizer', quantity: '0.9', price: '4.59'}));
     steps = steps.concat(press_product_numpad('9'))
     steps = steps.concat(selected_orderline_has({product: 'Desk Organizer', quantity: '0.99', price: '5.05'}));
-    steps = steps.concat(press_product_numpad('9'))
-    steps = steps.concat(selected_orderline_has({product: 'Desk Organizer', quantity: '0.999', price: '5.09'}));
     steps = steps.concat(goto_payment_screen_and_select_payment_method());
-    steps = steps.concat(selected_payment_has('Cash', '5.09'));
+    steps = steps.concat(selected_payment_has('Cash', '5.05'));
     steps = steps.concat(finish_order());
 
     // Test fiscal position one2many map (align with backend)
diff --git a/addons/product/data/product_data.xml b/addons/product/data/product_data.xml
index 15c7e6f6e542..afc860df10fb 100644
--- a/addons/product/data/product_data.xml
+++ b/addons/product/data/product_data.xml
@@ -34,7 +34,7 @@
         </record>
         <record forcecreate="True" id="decimal_product_uom" model="decimal.precision">
             <field name="name">Product Unit of Measure</field>
-            <field name="digits" eval="3"/>
+            <field name="digits" eval="2"/>
         </record>
 
         <!--
diff --git a/addons/purchase_product_matrix/static/tests/tours/purchase_product_matrix_tour.js b/addons/purchase_product_matrix/static/tests/tours/purchase_product_matrix_tour.js
index 5afd5b5dd8ea..010c0b18b4f5 100644
--- a/addons/purchase_product_matrix/static/tests/tours/purchase_product_matrix_tour.js
+++ b/addons/purchase_product_matrix/static/tests/tours/purchase_product_matrix_tour.js
@@ -69,7 +69,7 @@ tour.register('purchase_matrix_tour', {
     run: 'click' // apply the matrix
 }, {
     trigger: '.o_form_button_save:contains("Save")',
-    extra_trigger: '.o_field_cell.o_data_cell.o_list_number:contains("4.000")',
+    extra_trigger: '.o_field_cell.o_data_cell.o_list_number:contains("4.00")',
     run: 'click' // SAVE Sales Order, after matrix has been applied (extra_trigger).
 }, {
     trigger: '.o_form_button_edit:contains("Edit")',
@@ -102,7 +102,7 @@ tour.register('purchase_matrix_tour', {
     run: 'click' // apply the matrix
 }, {
     trigger: '.o_form_button_save:contains("Save")',
-    extra_trigger: '.o_field_cell.o_data_cell.o_list_number:contains("8.200")',
+    extra_trigger: '.o_field_cell.o_data_cell.o_list_number:contains("8.20")',
     run: 'click' // SAVE Sales Order, after matrix has been applied (extra_trigger).
 },
 ]);
diff --git a/addons/sale/tests/test_sale_to_invoice.py b/addons/sale/tests/test_sale_to_invoice.py
index 2e945be978c4..67ca71b30249 100644
--- a/addons/sale/tests/test_sale_to_invoice.py
+++ b/addons/sale/tests/test_sale_to_invoice.py
@@ -304,22 +304,22 @@ class TestSaleToInvoice(TestSaleCommon):
         self.assertEqual(sol_prod_deliver.qty_invoiced, 5.0)
         # We would have to change the digits of the field to
         # test a greater decimal precision.
-        quantity = 5.003
+        quantity = 5.13
         move_form = Form(sale_order.invoice_ids)
         with move_form.invoice_line_ids.edit(0) as line_form:
             line_form.quantity = quantity
         move_form.save()
 
-        # Default uom rounding to 0.001
+        # Default uom rounding to 0.01
         qty_invoiced_field = sol_prod_deliver._fields.get('qty_invoiced')
         sol_prod_deliver.env.add_to_compute(qty_invoiced_field, sol_prod_deliver)
         self.assertEqual(sol_prod_deliver.qty_invoiced, quantity)
 
-        # Rounding to 0.01, should be rounded with UP (ceil) rounding_method
+        # Rounding to 0.1, should be rounded with UP (ceil) rounding_method
         # Not floor or half up rounding.
         sol_prod_deliver.product_uom.rounding *= 10
         sol_prod_deliver.product_uom.flush(['rounding'])
-        expected_qty = 5.01
+        expected_qty = 5.2
         qty_invoiced_field = sol_prod_deliver._fields.get('qty_invoiced')
         sol_prod_deliver.env.add_to_compute(qty_invoiced_field, sol_prod_deliver)
         self.assertEqual(sol_prod_deliver.qty_invoiced, expected_qty)
diff --git a/addons/sale_mrp/tests/test_sale_mrp_flow.py b/addons/sale_mrp/tests/test_sale_mrp_flow.py
index 017af4004129..7534c2f0faf7 100644
--- a/addons/sale_mrp/tests/test_sale_mrp_flow.py
+++ b/addons/sale_mrp/tests/test_sale_mrp_flow.py
@@ -1242,7 +1242,7 @@ class TestSaleMrpFlow(ValuationReconciliationTestCommon):
         # kit_uom_in_kit --|- component_uom_gm  x3 Test-KG
         #                  |- kit_uom_1         x2 Test-Dozen --|- component_uom_unit    x2 Test-Dozen
         #                                                       |- component_uom_dozen   x1 Test-Dozen
-        #                                                       |- component_uom_kg      x3 Test-G
+        #                                                       |- component_uom_kg      x5 Test-G
 
         kit_uom_1 = self._create_product('Sub Kit 1', self.uom_unit)
         kit_uom_in_kit = self._create_product('Parent Kit', self.uom_unit)
@@ -1265,7 +1265,7 @@ class TestSaleMrpFlow(ValuationReconciliationTestCommon):
             'bom_id': bom_kit_uom_1.id})
         BomLine.create({
             'product_id': component_uom_kg.id,
-            'product_qty': 3.0,
+            'product_qty': 5.0,
             'product_uom_id': self.uom_gm.id,
             'bom_id': bom_kit_uom_1.id})
 
@@ -1294,7 +1294,7 @@ class TestSaleMrpFlow(ValuationReconciliationTestCommon):
         # Set enough quantities to make 1 kit_uom_in_kit in WH1
         self.env['stock.quant']._update_available_quantity(component_uom_unit, warehouse_1.lot_stock_id, 576)
         self.env['stock.quant']._update_available_quantity(component_uom_dozen, warehouse_1.lot_stock_id, 24)
-        self.env['stock.quant']._update_available_quantity(component_uom_kg, warehouse_1.lot_stock_id, 0.072)
+        self.env['stock.quant']._update_available_quantity(component_uom_kg, warehouse_1.lot_stock_id, 0.12)
         self.env['stock.quant']._update_available_quantity(component_uom_gm, warehouse_1.lot_stock_id, 3000)
 
         # Creation of a sale order for x5 kit_uom_in_kit
@@ -1323,7 +1323,7 @@ class TestSaleMrpFlow(ValuationReconciliationTestCommon):
         qty_to_process = {
             component_uom_unit: (1152, self.uom_unit),
             component_uom_dozen: (48, self.uom_dozen),
-            component_uom_kg: (0.144, self.uom_kg),
+            component_uom_kg: (0.24, self.uom_kg),
             component_uom_gm: (6000, self.uom_gm)
         }
         self._create_move_quantities(qty_to_process, components, warehouse_1)
@@ -1488,7 +1488,7 @@ class TestSaleMrpFlow(ValuationReconciliationTestCommon):
         move_component_unit = order.picking_ids[0].move_lines.filtered(lambda m: m.product_id == component_unit)
         move_component_kg = order.picking_ids[0].move_lines - move_component_unit
         self.assertEqual(move_component_unit.product_uom_qty, 0.5)
-        self.assertEqual(move_component_kg.product_uom_qty, 0.583)
+        self.assertEqual(move_component_kg.product_uom_qty, 0.58)
 
     def test_product_type_service_1(self):
         route_manufacture = self.company_data['default_warehouse'].manufacture_pull_id.route_id.id
diff --git a/addons/sale_product_configurator/static/tests/tours/product_configurator_edition_ui.js b/addons/sale_product_configurator/static/tests/tours/product_configurator_edition_ui.js
index 14cf07663ee7..dc7663d64176 100644
--- a/addons/sale_product_configurator/static/tests/tours/product_configurator_edition_ui.js
+++ b/addons/sale_product_configurator/static/tests/tours/product_configurator_edition_ui.js
@@ -141,7 +141,7 @@ tour.register('sale_product_configurator_edition_tour', {
 }, {
     trigger: '.o_sale_product_configurator_edit',
 }, {
-    trigger: 'td.o_data_cell:contains("2.000")',
+    trigger: 'td.o_data_cell:contains("2.00")',
     run: function (){} // check quantity
 }, {
     trigger: 'td.o_product_configurator_cell',
diff --git a/addons/sale_product_matrix/static/tests/tours/sale_product_matrix_tour.js b/addons/sale_product_matrix/static/tests/tours/sale_product_matrix_tour.js
index 10259a98176c..c01587633c9a 100644
--- a/addons/sale_product_matrix/static/tests/tours/sale_product_matrix_tour.js
+++ b/addons/sale_product_matrix/static/tests/tours/sale_product_matrix_tour.js
@@ -101,7 +101,7 @@ tour.register('sale_matrix_tour', {
     run: 'click' // apply the matrix
 }, {
     trigger: '.o_form_button_save:contains("Save")',
-    extra_trigger: '.o_field_cell.o_data_cell.o_list_number:contains("4.000")',
+    extra_trigger: '.o_field_cell.o_data_cell.o_list_number:contains("4.00")',
     run: 'click' // SAVE Sales Order, after matrix has been applied (extra_trigger).
 }, {
     trigger: '.o_form_button_edit:contains("Edit")',
@@ -134,7 +134,7 @@ tour.register('sale_matrix_tour', {
     run: 'click' // apply the matrix
 }, {
     trigger: '.o_form_button_save:contains("Save")',
-    extra_trigger: '.o_field_cell.o_data_cell.o_list_number:contains("8.200")',
+    extra_trigger: '.o_field_cell.o_data_cell.o_list_number:contains("8.20")',
     run: 'click' // SAVE Sales Order, after matrix has been applied (extra_trigger).
 },
 ]);
diff --git a/addons/stock/tests/test_packing.py b/addons/stock/tests/test_packing.py
index 89ef70a0b1aa..758107101c51 100644
--- a/addons/stock/tests/test_packing.py
+++ b/addons/stock/tests/test_packing.py
@@ -275,10 +275,10 @@ class TestPacking(TestPackingCommon):
 
     def test_move_picking_with_package(self):
         """
-        355.4 rounded with 0.001 precision is 355.40000000000003.
+        355.4 rounded with 0.01 precision is 355.40000000000003.
         check that nonetheless, moving a picking is accepted
         """
-        self.assertEqual(self.productA.uom_id.rounding, 0.001)
+        self.assertEqual(self.productA.uom_id.rounding, 0.01)
         self.assertEqual(
             float_round(355.4, precision_rounding=self.productA.uom_id.rounding),
             355.40000000000003,
diff --git a/addons/stock/tests/test_stock_flow.py b/addons/stock/tests/test_stock_flow.py
index 58bd6a3d16f3..bf9782f4199d 100644
--- a/addons/stock/tests/test_stock_flow.py
+++ b/addons/stock/tests/test_stock_flow.py
@@ -9,6 +9,8 @@ from odoo import fields
 class TestStockFlow(TestStockCommon):
     def setUp(cls):
         super(TestStockFlow, cls).setUp()
+        decimal_product_uom = cls.env.ref('product.decimal_product_uom')
+        decimal_product_uom.digits = 3
         cls.partner_company2 = cls.env['res.partner'].create({
             'name': 'My Company (Chicago)-demo',
             'email': 'chicago@yourcompany.com',
diff --git a/addons/uom/data/uom_data.xml b/addons/uom/data/uom_data.xml
index 049fce2f51d7..3682dd17557e 100644
--- a/addons/uom/data/uom_data.xml
+++ b/addons/uom/data/uom_data.xml
@@ -27,7 +27,6 @@
             <field name="name">Units</field>
             <field name="factor" eval="1.0"/>
             <field name="uom_type">reference</field>
-            <field name="rounding" eval="0.001"/>
         </record>
        <record id="product_uom_dozen" model="uom.uom">
             <field name="category_id" ref="uom.product_uom_categ_unit"/>
@@ -41,7 +40,6 @@
             <field name="name">kg</field>
             <field name="factor" eval="1"/>
             <field name="uom_type">reference</field>
-            <field name="rounding" eval="0.001"/>
         </record>
         <record id="product_uom_gram" model="uom.uom">
             <field name="category_id" ref="product_uom_categ_kgm"/>
diff --git a/addons/uom/tests/test_uom.py b/addons/uom/tests/test_uom.py
index 48728b18bcd5..9abe66e55ba2 100644
--- a/addons/uom/tests/test_uom.py
+++ b/addons/uom/tests/test_uom.py
@@ -35,7 +35,7 @@ class TestUom(TransactionCase):
         # into Kilograms should work even if grams are rounded to 1.
         self.uom_gram.write({'rounding': 1})
         qty = self.uom_gram._compute_quantity(1234, self.uom_kgm)
-        self.assertEqual(qty, 1.234, "Converted quantity does not correspond.")
+        self.assertEqual(qty, 1.24, "Converted quantity does not correspond.")
 
     def test_20_rounding(self):
         product_uom = self.env['uom.uom'].create({
-- 
GitLab