diff --git a/addons/mrp/models/mrp_abstract_workorder.py b/addons/mrp/models/mrp_abstract_workorder.py index 44fb34fdf1e..4a6e65648e4 100644 --- a/addons/mrp/models/mrp_abstract_workorder.py +++ b/addons/mrp/models/mrp_abstract_workorder.py @@ -40,8 +40,19 @@ class MrpAbstractWorkorder(models.AbstractModel): # Compute the new quantity for the current component rounding = move_raw.product_uom.rounding - new_qty = self.product_uom_id._compute_quantity( + if move_raw.product_id.tracking == 'serial': + uom = move_raw.product_id.uom_id + else: + uom = move_raw.product_uom + new_qty = move_raw.product_uom._compute_quantity( self.qty_producing * move_raw.unit_factor, + uom, + round=False + ) + # In case the production uom is different than the workorder uom + # it means the product is serial and production uom is not the reference + new_qty = self.product_uom_id._compute_quantity( + new_qty, self.production_id.product_uom_id, round=False ) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index b497dca8e6a..d8a957ba627 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -712,11 +712,15 @@ class MrpProduction(models.Model): duration_expected = (operation.workcenter_id.time_start + operation.workcenter_id.time_stop + cycle_number * operation.time_cycle * 100.0 / operation.workcenter_id.time_efficiency) + if self.product_uom_id.uom_type != 'reference': + todo_uom = self.env['uom.uom'].search([('category_id', '=', self.product_uom_id.category_id.id), ('uom_type', '=', 'reference')]).id + else: + todo_uom = self.product_uom_id.id workorder = workorders.create({ 'name': operation.name, 'production_id': self.id, 'workcenter_id': operation.workcenter_id.id, - 'product_uom_id': self.product_uom_id.id, + 'product_uom_id': todo_uom, 'operation_id': operation.id, 'duration_expected': duration_expected, 'state': len(workorders) == 0 and 'ready' or 'pending', diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py index a892db6e098..51ba548619f 100644 --- a/addons/mrp/models/mrp_workorder.py +++ b/addons/mrp/models/mrp_workorder.py @@ -215,7 +215,6 @@ class MrpWorkorder(models.Model): # If last work order, then post lots used # TODO: should be same as checking if for every workorder something has been done? if not self.next_work_order_id: - uom_id = self.production_id.product_uom_id self._update_finished_move() self.production_id.move_finished_ids.filtered( lambda move: move.product_id == self.product_id and diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index 2935b6b47f2..25e693f3d0f 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -719,3 +719,60 @@ class TestMrpOrder(TestMrpCommon): 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_produce_uom_2(self): + unit = self.env.ref("uom.product_uom_unit") + categ_unit_id = self.env.ref('uom.product_uom_categ_unit') + paire = self.env['uom.uom'].create({ + 'name': 'Paire', + 'factor_inv': 2, + 'uom_type': 'bigger', + 'rounding': 0.001, + 'category_id': categ_unit_id.id + }) + binocular = self.env['product.product'].create({ + 'name': 'Binocular', + 'type': 'product', + 'uom_id': unit.id, + 'uom_po_id': unit.id + }) + nocular = self.env['product.product'].create({ + 'name': 'Nocular', + 'type': 'product', + 'tracking': 'serial', + 'uom_id': unit.id, + 'uom_po_id': unit.id + }) + bom_binocular = self.env['mrp.bom'].create({ + 'product_tmpl_id': binocular.product_tmpl_id.id, + 'product_qty': 1, + 'product_uom_id': unit.id, + 'bom_line_ids': [(0, 0, { + 'product_id': nocular.id, + 'product_qty': 1, + 'product_uom_id': paire.id + })] + }) + mo_form = Form(self.env['mrp.production']) + mo_form.product_id = binocular + mo_form.bom_id = bom_binocular + mo_form.product_uom_id = unit + mo_form.product_qty = 1 + mo = mo_form.save() + + mo.action_confirm() + self.assertEqual(mo.move_raw_ids.product_uom_qty, 1, 'Quantity should be 1.') + self.assertEqual(mo.move_raw_ids.product_uom, paire, 'Move UoM should be "Paire".') + + # produce product + produce_form = Form(self.env['mrp.product.produce'].with_context({ + 'active_id': mo.id, + 'active_ids': [mo.id], + })) + product_produce = produce_form.save() + self.assertEqual(product_produce.qty_producing, 1) + self.assertEqual(len(product_produce.workorder_line_ids), 2, 'Should be 2 lines since the component tracking is serial and quantity 2.') + self.assertEqual(product_produce.workorder_line_ids[0].qty_to_consume, 1, 'Should be 1 unit since the tracking is serial and quantity 2.') + self.assertEqual(product_produce.workorder_line_ids[0].product_uom_id, unit, 'Should be the product uom so "unit"') + self.assertEqual(product_produce.workorder_line_ids[1].qty_to_consume, 1, 'Should be 1 unit since the tracking is serial and quantity 2.') + self.assertEqual(product_produce.workorder_line_ids[1].product_uom_id, unit, 'should be the product uom so "unit"')