diff --git a/addons/mrp/models/__init__.py b/addons/mrp/models/__init__.py index 7b3b3958084..295d045c1e8 100644 --- a/addons/mrp/models/__init__.py +++ b/addons/mrp/models/__init__.py @@ -16,5 +16,6 @@ from . import product from . import res_company from . import stock_move from . import stock_picking +from . import stock_production_lot from . import stock_scrap from . import stock_warehouse diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py index 723f4c8f75a..4e8244da860 100644 --- a/addons/mrp/models/mrp_workorder.py +++ b/addons/mrp/models/mrp_workorder.py @@ -271,6 +271,10 @@ class MrpWorkorder(models.Model): 'location_dest_id': move.location_dest_id.id, }) + def _assign_default_final_lot_id(self): + self.final_lot_id = self.env['stock.production.lot'].search([('use_next_on_work_order_id', '=', self.id)], + order='create_date', limit=1) + @api.multi def record_production(self): self.ensure_one() @@ -308,8 +312,6 @@ class MrpWorkorder(models.Model): # One a piece is produced, you can launch the next work order if self.next_work_order_id.state == 'pending': self.next_work_order_id.state = 'ready' - if self.next_work_order_id and self.final_lot_id and not self.next_work_order_id.final_lot_id: - self.next_work_order_id.final_lot_id = self.final_lot_id.id self.move_line_ids.filtered( lambda move_line: not move_line.done_move and not move_line.lot_produced_id and move_line.qty_done > 0 @@ -342,18 +344,24 @@ class MrpWorkorder(models.Model): # Update workorder quantity produced self.qty_produced += self.qty_producing + if self.final_lot_id: + self.final_lot_id.use_next_on_work_order_id = self.next_work_order_id + self.final_lot_id = False + # Set a qty producing if self.qty_produced >= self.production_id.product_qty: self.qty_producing = 0 elif self.production_id.product_id.tracking == 'serial': + self._assign_default_final_lot_id() self.qty_producing = 1.0 self._generate_lot_ids() else: self.qty_producing = self.production_id.product_qty - self.qty_produced self._generate_lot_ids() - self.final_lot_id = False if self.qty_produced >= self.production_id.product_qty: + if self.next_work_order_id and self.production_id.product_id.tracking != 'none': + self.next_work_order_id._assign_default_final_lot_id() self.button_finish() return True diff --git a/addons/mrp/models/stock_production_lot.py b/addons/mrp/models/stock_production_lot.py new file mode 100644 index 00000000000..9c2470c64ef --- /dev/null +++ b/addons/mrp/models/stock_production_lot.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, exceptions, fields, models, _ + + +class StockProductionLot(models.Model): + _inherit = 'stock.production.lot' + + use_next_on_work_order_id = fields.Many2one('mrp.workorder', + help='Technical: used to figure out default serial number on work orders') diff --git a/addons/mrp/tests/test_workorder_operation.py b/addons/mrp/tests/test_workorder_operation.py index 15adcd236c8..bbbd8efd08d 100644 --- a/addons/mrp/tests/test_workorder_operation.py +++ b/addons/mrp/tests/test_workorder_operation.py @@ -408,3 +408,56 @@ class TestWorkOrderProcess(common.TransactionCase): # self.assertEqual(move_product_b.quant_ids.qty, move_product_b.product_qty) # self.assertEqual(move_product_c.quant_ids.qty, 3) # self.assertEqual(move_product_c.quant_ids.product_uom_id.id, kg) + + def test_03_test_serial_number_defaults(self): + """ Test that the correct serial number is suggested on consecutive work orders. """ + laptop = self.env.ref("product.product_product_25") + graphics_card = self.env.ref("product.product_product_24") + unit = self.env.ref("product.product_uom_unit") + three_step_routing = self.env.ref("mrp.mrp_routing_1") + + laptop.tracking = 'serial' + + bom_laptop = self.env['mrp.bom'].create({ + 'product_tmpl_id': laptop.product_tmpl_id.id, + 'product_qty': 1, + 'product_uom_id': unit.id, + 'bom_line_ids': [(0, 0, { + 'product_id': graphics_card.id, + 'product_qty': 1, + 'product_uom_id': unit.id + })], + 'routing_id': three_step_routing.id + }) + + mo_laptop = self.env['mrp.production'].create({ + 'product_id': laptop.id, + 'product_qty': 3, + 'product_uom_id': unit.id, + 'bom_id': bom_laptop.id + }) + + mo_laptop.button_plan() + workorders = mo_laptop.workorder_ids + self.assertEqual(len(workorders), 3) + + workorders[0].button_start() + serial_a = self.env['stock.production.lot'].create({'product_id': laptop.id}) + workorders[0].final_lot_id = serial_a + workorders[0].record_production() + serial_b = self.env['stock.production.lot'].create({'product_id': laptop.id}) + workorders[0].final_lot_id = serial_b + workorders[0].record_production() + serial_c = self.env['stock.production.lot'].create({'product_id': laptop.id}) + workorders[0].final_lot_id = serial_c + workorders[0].record_production() + self.assertEqual(workorders[0].state, 'done') + + for workorder in workorders - workorders[0]: + self.assertEqual(workorder.final_lot_id, serial_a) + workorder.record_production() + self.assertEqual(workorder.final_lot_id, serial_b) + workorder.record_production() + self.assertEqual(workorder.final_lot_id, serial_c) + workorder.record_production() + self.assertEqual(workorder.state, 'done')