From 17be15fd61aebb15979e85fc28734ad6c9372bc3 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 26 Aug 2016 16:35:42 +0200 Subject: [PATCH] [IMP] mrp: routing of phantom boms in bom When the routing of the phantom bom is the same as the parent BoM, the phantom BoM should not recreate the work orders, but use the same work orders as the parent BoM. That way, you can create one master routing and the "consumed in operation" of the phantom bom can be used linking to the master routing. If the phantom bom has no routing or the same, it can also use the "consumed in operation" of his parent bom line if none is defined. --- addons/mrp/models/mrp_bom.py | 13 ++++++------- addons/mrp/models/mrp_production.py | 16 +++++++++++----- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/addons/mrp/models/mrp_bom.py b/addons/mrp/models/mrp_bom.py index ab22fbc8584..91ee51bd9f1 100644 --- a/addons/mrp/models/mrp_bom.py +++ b/addons/mrp/models/mrp_bom.py @@ -111,13 +111,13 @@ class MrpBom(models.Model): return self.search(domain, order='sequence, product_id', limit=1) def explode(self, product, quantity, picking_type=False): - boms_done = [(self, {'qty': quantity, 'product': product, 'original_qty': quantity})] + boms_done = [(self, {'qty': quantity, 'product': product, 'original_qty': quantity, 'parent_line': False})] lines_done = [] templates_done = product.product_tmpl_id - bom_lines = [(bom_line, product, quantity) for bom_line in self.bom_line_ids] + bom_lines = [(bom_line, product, quantity, False) for bom_line in self.bom_line_ids] while bom_lines: - current_line, current_product, current_qty = bom_lines[0] + current_line, current_product, current_qty, parent_line = bom_lines[0] bom_lines = bom_lines[1:] if current_line._skip_bom_line(current_product): @@ -126,15 +126,14 @@ class MrpBom(models.Model): raise UserError(_('Recursion error! A product with a Bill of Material should not have itself in its BoM or child BoMs!')) line_quantity = current_qty * current_line.product_qty / current_line.bom_id.product_qty - bom = self._bom_find(product=current_line.product_id, picking_type=picking_type or self.picking_type_id, company_id=self.company_id.id) if bom.type == 'phantom': converted_line_quantity = self.env['product.uom']._compute_qty_obj(current_line.product_uom_id, line_quantity, bom.product_uom_id) - bom_lines = [(line, current_line.product_id, line_quantity) for line in bom.bom_line_ids] + bom_lines + bom_lines = [(line, current_line.product_id, line_quantity, current_line) for line in bom.bom_line_ids] + bom_lines templates_done |= current_line.product_id.product_tmpl_id - boms_done.append((bom, {'qty': converted_line_quantity, 'product': current_product, 'original_qty': quantity})) + boms_done.append((bom, {'qty': converted_line_quantity, 'product': current_product, 'original_qty': quantity, 'parent_line': current_line})) else: - lines_done.append((current_line, {'qty': line_quantity, 'product': current_product, 'original_qty': quantity})) + lines_done.append((current_line, {'qty': line_quantity, 'product': current_product, 'original_qty': quantity, 'parent_line': parent_line})) return boms_done, lines_done diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 503be6e2ac9..248ec9b1954 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -296,10 +296,13 @@ class MrpProduction(models.Model): self.ensure_one() moves = self.env['stock.move'] for bom_line, line_data in exploded_lines: - moves += self._generate_raw_move(bom_line, line_data['qty']) + moves += self._generate_raw_move(bom_line, line_data) return moves - def _generate_raw_move(self, bom_line, quantity): + def _generate_raw_move(self, bom_line, line_data): + quantity = line_data['qty'] + # alt_op needed for the case when you explode phantom bom and all the lines will be consumed in the operation given by the parent bom line + alt_op = line_data['parent_line'] and line_data['parent_line'].operation_id.id or False if bom_line.child_bom_id and bom_line.child_bom_id.type == 'phantom': return self.env['stock.move'] if bom_line.product_id.type not in ['product', 'consu']: @@ -321,7 +324,7 @@ class MrpProduction(models.Model): 'location_dest_id': self.product_id.property_stock_production.id, 'raw_material_production_id': self.id, 'company_id': self.company_id.id, - 'operation_id': bom_line.operation_id.id, + 'operation_id': bom_line.operation_id.id or alt_op, 'price_unit': bom_line.product_id.standard_price, 'procure_method': 'make_to_stock', 'origin': self.name, @@ -382,15 +385,18 @@ class MrpProduction(models.Model): def _generate_workorders(self, exploded_boms): workorders = self.env['mrp.workorder'] for bom, bom_data in exploded_boms: - workorders += self._workorders_create(bom, bom_data['qty']) + # If the routing of the parent BoM and phantom BoM are the same, don't recreate work orders, but use one master routing + if bom.routing_id.id and (not bom_data['parent_line'] or bom_data['parent_line'].bom_id.routing_id.id != bom.routing_id.id): + workorders += self._workorders_create(bom, bom_data) return workorders - def _workorders_create(self, bom, qty): + def _workorders_create(self, bom, bom_data): """ :param bom: in case of recursive boms: we could create work orders for child BoMs """ workorders = self.env['mrp.workorder'] + qty = bom_data['qty'] use_serial = any(product.tracking == 'serial' for product in self.mapped('move_finished_ids.product_id')) if use_serial: