[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.
This commit is contained in:
Josse Colpaert
2016-08-30 13:59:53 +02:00
parent d985fa796e
commit 17be15fd61
2 changed files with 17 additions and 12 deletions
+6 -7
View File
@@ -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
+11 -5
View File
@@ -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: