From 4f9af6838ff714cddfd8ea1f5ecd10d3788fa0ef Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 22 Aug 2016 12:18:40 +0200 Subject: [PATCH] [FIX] mrp: use unit_factor when generating lots in work orders and make sure to generate lots when necessary When (re)generating the stock.move.lots in the workorder, it should use the unit_factor on the move like everywhere else. This makes sure we do well with the explosion of phantom boms too. It is also important that if there is no operation_id given explicitly in the "consumed in operation" on the bom line, that it still generates the necessary stock.move.lots in the last work order. Also, in the work order it is better to set the quantities done already. That way we don't forget to consume them. --- addons/mrp/models/mrp_production.py | 4 ++-- addons/mrp/models/mrp_workorder.py | 17 +++++++++-------- addons/mrp/tests/test_order.py | 3 ++- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 7292c8c5768..84de39aa85f 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -421,8 +421,8 @@ class MrpProduction(models.Model): # assign moves; last operation receive all unassigned moves (which case ?) moves_raw = self.move_raw_ids.filtered(lambda move: move.operation_id == operation) if len(workorders) == len(bom.routing_id.operation_ids): - moves_raw |= self.move_raw_ids.filtered(lambda move: move.operation_id == False) - moves_finished = self.move_finished_ids.filtered(lambda move: move.operation_id == operation) + moves_raw |= self.move_raw_ids.filtered(lambda move: not move.operation_id) + moves_finished = self.move_finished_ids.filtered(lambda move: move.operation_id == operation) #TODO: code does nothing, unless maybe by_products? moves_raw.mapped('move_lot_ids').write({'workorder_id': workorder.id}) (moves_finished + moves_raw).write({'workorder_id': workorder.id}) diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py index 980c0054834..ea3346635fc 100644 --- a/addons/mrp/models/mrp_workorder.py +++ b/addons/mrp/models/mrp_workorder.py @@ -189,25 +189,26 @@ class MrpWorkorder(models.Model): move_lots = self.active_move_lot_ids.filtered(lambda move_lot: move_lot.move_id == move) if not move_lots: continue - new_qty = move.bom_line_id.product_qty * self.qty_producing / move.bom_line_id.bom_id.product_qty + new_qty = move.unit_factor * self.qty_producing if move.product_id.tracking == 'lot': move_lots[0].quantity = new_qty + move_lots[0].quantity_done = new_qty elif move.product_id.tracking == 'serial': # Create extra pseudo record qty_todo = new_qty - sum(move_lots.mapped('quantity')) - if qty_todo > 0.0: # TDE: float compare - while qty_todo > 0: + if float_compare(qty_todo, 0.0, precision_rounding=move.product_uom.rounding) > 0: + while float_compare(qty_todo, 0.0, precision_rounding=move.product_uom.rounding) > 0: self.active_move_lot_ids += self.env['stock.move.lots'].new({ 'move_id': move.id, 'product_id': move.product_id.id, 'lot_id': False, 'quantity': min(1.0, qty_todo), - 'quantity_done': 0, + 'quantity_done': min(1.0, qty_todo), 'workorder_id': self.id, 'done_wo': False }) qty_todo -= 1 - elif qty_todo < 0.0: + elif float_compare(qty_todo, 0.0, precision_rounding=move.product_uom.rounding) < 0: qty_todo = abs(qty_todo) for move_lot in move_lots: if qty_todo <= 0: @@ -232,13 +233,13 @@ class MrpWorkorder(models.Model): tracked_moves = self.move_raw_ids.filtered( lambda move: move.state not in ('done', 'cancel') and move.product_id.tracking != 'none' and move.product_id != self.production_id.product_id) for move in tracked_moves: - qty = self.qty_producing / move.bom_line_id.bom_id.product_qty * move.bom_line_id.product_qty + qty = move.unit_factor * self.qty_producing if move.product_id.tracking == 'serial': while float_compare(qty, 0.0, precision_rounding=move.product_uom.rounding) > 0: MoveLot.create({ 'move_id': move.id, 'quantity': min(1, qty), - 'quantity_done': 0, + 'quantity_done': min(1, qty), 'production_id': self.production_id.id, 'workorder_id': self.id, 'product_id': move.product_id.id, @@ -249,7 +250,7 @@ class MrpWorkorder(models.Model): MoveLot.create({ 'move_id': move.id, 'quantity': qty, - 'quantity_done': 0, + 'quantity_done': qty, 'product_id': move.product_id.id, 'production_id': self.production_id.id, 'workorder_id': self.id, diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index 172078ae656..5e5535b9137 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -187,7 +187,7 @@ class TestMrpOrder(TestMrpCommon): }).change_product_qty() (self.product_2 | self.product_4).write({ - 'tracking': 'lot', + 'tracking': 'none', }) # assign consume material man_order.action_assign() @@ -273,6 +273,7 @@ class TestMrpOrder(TestMrpCommon): 'final_lot_id': finished_lot.id, 'qty_producing': 48 }) + kit_wo.record_production() self.assertEqual(kit_wo.state, 'done', "Workorder should be in done state.")