From a14874d623bc707a015eb9760d3c20cc01c78756 Mon Sep 17 00:00:00 2001 From: "Guillaume (guva)" Date: Thu, 14 Oct 2021 14:45:40 +0000 Subject: [PATCH] [FIX] mrp: Delivered quantity with kit Steps to reproduce: - Set the Decimal Accuracy at 5 digits for Product UoM - Create a product X - Create a kit BOM for X with a component Y, and qty 0.08600 - Create a Sale Order for 10 product X, confirm and deliver all Issue - On the SO, quantity delevered is 9.00000 instead of 10.00000, same issue occur with the same flow with a Purchase Order. Cause As the quantity per kit was rounded when calling _compute_qty, the calcul of quantity ratio was not well computed. Solution Avoid rounding the quantity per kit, as the quantity ratio is rounded a few steps after. opw-2590126 closes odoo/odoo#78516 X-original-commit: 2a2b198ea6ce1d0553c606404e6db1117dc1c4a2 Signed-off-by: William Henrotin Signed-off-by: guva-odoo --- addons/mrp/models/stock_move.py | 2 +- .../sale_mrp/tests/test_sale_mrp_kit_bom.py | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index d08f8fb3a28..38577c2b640 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -429,7 +429,7 @@ class StockMove(models.Model): # Then, we collect every relevant moves related to a specific component # to know how many are considered delivered. uom_qty_per_kit = bom_line_data['qty'] / bom_line_data['original_qty'] - qty_per_kit = bom_line.product_uom_id._compute_quantity(uom_qty_per_kit, bom_line.product_id.uom_id) + qty_per_kit = bom_line.product_uom_id._compute_quantity(uom_qty_per_kit, bom_line.product_id.uom_id, round=False) if not qty_per_kit: continue incoming_moves = bom_line_moves.filtered(filters['incoming_moves']) diff --git a/addons/sale_mrp/tests/test_sale_mrp_kit_bom.py b/addons/sale_mrp/tests/test_sale_mrp_kit_bom.py index ab733dd2dac..55c71dff34d 100644 --- a/addons/sale_mrp/tests/test_sale_mrp_kit_bom.py +++ b/addons/sale_mrp/tests/test_sale_mrp_kit_bom.py @@ -296,3 +296,51 @@ class TestSaleMrpKitBom(TransactionCase): line = so.order_line purchase_price = line.product_id.with_company(line.company_id)._compute_average_price(0, line.product_uom_qty, line.move_ids) self.assertEqual(purchase_price, 92, "The purchase price must be the total cost of the components multiplied by their unit of measure") + + def test_qty_delivered_with_bom(self): + """Check the quantity delivered, when a bom line has a non integer quantity""" + + self.env.ref('product.decimal_product_uom').digits = 5 + + self.kit = self._create_product('Kit', 'product', 0.00) + self.comp = self._create_product('Component', 'product', 0.00) + + # Create BoM for Kit + bom_product_form = Form(self.env['mrp.bom']) + bom_product_form.product_id = self.kit + bom_product_form.product_tmpl_id = self.kit.product_tmpl_id + bom_product_form.product_qty = 1.0 + bom_product_form.type = 'phantom' + with bom_product_form.bom_line_ids.new() as bom_line: + bom_line.product_id = self.comp + bom_line.product_qty = 0.08600 + self.bom = bom_product_form.save() + + + self.customer = self.env['res.partner'].create({ + 'name': 'customer', + }) + + so = self.env['sale.order'].create({ + 'partner_id': self.customer.id, + 'order_line': [ + (0, 0, { + 'name': self.kit.name, + 'product_id': self.kit.id, + 'product_uom_qty': 10.0, + 'product_uom': self.kit.uom_id.id, + 'price_unit': 1, + 'tax_id': False, + })], + }) + so.action_confirm() + + self.assertTrue(so.picking_ids) + self.assertEqual(so.order_line.qty_delivered, 0) + + picking = so.picking_ids + picking.move_lines.quantity_done = 0.86000 + picking.button_validate() + + # Checks the delivery amount (must be 10). + self.assertEqual(so.order_line.qty_delivered, 10)