[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:
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user