diff options
| author | Rémy Voet (ryv) <ryv@odoo.com> | 2020-08-28 14:37:25 +0000 |
|---|---|---|
| committer | yhu-odoo <yhu@odoo.com> | 2020-09-07 08:36:21 +0000 |
| commit | f0da27e7eb474e6db4cd999306c420804aaa6f9b (patch) | |
| tree | ccf5d0d47297131c2b29bb415af2b5b7135a2e00 | |
| parent | 460ec0402a2352a5b179d81935f7230f6bc97cb7 (diff) | |
[FIX] mrp: force the UoM in case of serial number tracking
In case of manufacturing a product tracked by serial number,
there is no reason to be able to make it with a different UoM of
the product (which lead to rouding issue).
Then when we confirm the MO in this case, the UoM and quantity
will be converted to product UoM.
PR #56000
Related: odoo/enterprise#12454
Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
| -rw-r--r-- | addons/mrp/models/mrp_production.py | 18 | ||||
| -rw-r--r-- | addons/mrp/tests/test_order.py | 63 |
2 files changed, 75 insertions, 6 deletions
diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 3c7ef33f02c..2f704d033c1 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -1062,6 +1062,17 @@ class MrpProduction(models.Model): production.consumption = production.bom_id.consumption if not production.move_raw_ids: raise UserError(_("Add some materials to consume before marking this MO as to do.")) + # In case of Serial number tracking, force the UoM to the UoM of product + if production.product_tracking == 'serial' and production.product_uom_id != production.product_id.uom_id: + production.write({ + 'product_qty': production.product_uom_id._compute_quantity(production.product_qty, production.product_id.uom_id), + 'product_uom_id': production.product_id.uom_id + }) + for move_finish in production.move_finished_ids.filtered(lambda m: m.product_id == production.product_id): + move_finish.write({ + 'product_uom_qty': move_finish.product_uom._compute_quantity(move_finish.product_uom_qty, move_finish.product_id.uom_id), + 'product_uom': move_finish.product_id.uom_id + }) production.move_raw_ids._adjust_procure_method() (production.move_raw_ids | production.move_finished_ids)._action_confirm() production.workorder_ids._action_confirm() @@ -1318,12 +1329,7 @@ class MrpProduction(models.Model): finish_moves = order.move_finished_ids.filtered(lambda m: m.product_id == order.product_id and m.state not in ('done', 'cancel')) # the finish move can already be completed by the workorder. if not finish_moves.quantity_done: - if order.product_tracking == 'serial': - uom = order.product_id.uom_id - finish_moves.quantity_done = order.product_uom_id._compute_quantity(order.qty_producing, uom, round='HALF-UP') - finish_moves.move_line_ids.product_uom_id = uom - else: - finish_moves.quantity_done = float_round(order.qty_producing - order.qty_produced, precision_rounding=order.product_uom_id.rounding, rounding_method='HALF-UP') + finish_moves.quantity_done = float_round(order.qty_producing - order.qty_produced, precision_rounding=order.product_uom_id.rounding, rounding_method='HALF-UP') finish_moves.move_line_ids.lot_id = order.lot_producing_id order._cal_price(moves_to_do) diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index 940aedfd5ee..a7e024f146e 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -1118,6 +1118,69 @@ 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({ |
