summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémy Voet (ryv) <ryv@odoo.com>2020-08-28 14:37:25 +0000
committeryhu-odoo <yhu@odoo.com>2020-09-07 08:36:21 +0000
commitf0da27e7eb474e6db4cd999306c420804aaa6f9b (patch)
treeccf5d0d47297131c2b29bb415af2b5b7135a2e00
parent460ec0402a2352a5b179d81935f7230f6bc97cb7 (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.py18
-rw-r--r--addons/mrp/tests/test_order.py63
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({