[FIX] mrp: correct interpretation of explode's quantity parameter
In previous versions, the quantity passed to the bom_explode was the number of times you needed to count the BoM. If the BoM was for 2 dozens and you pass 48 units, 2 was passed to the bom_explode method. We are now doing the same for the explode method and we check it is called this way everywhere.
This commit is contained in:
@@ -113,7 +113,8 @@ class MrpBom(models.Model):
|
||||
def explode(self, product, quantity, picking_type=False):
|
||||
"""
|
||||
Explodes the BoM and creates two lists with all the information you need: bom_done and line_done
|
||||
Quantity should be passed in the UoM of the BoM (don't divide by its quantity)
|
||||
Quantity describes the number of times you need the BoM: so the quantity divided by the number created by the BoM
|
||||
and converted into its UoM
|
||||
"""
|
||||
boms_done = [(self, {'qty': quantity, 'product': product, 'original_qty': quantity, 'parent_line': False})]
|
||||
lines_done = []
|
||||
@@ -129,11 +130,11 @@ class MrpBom(models.Model):
|
||||
if current_line.product_id.product_tmpl_id in templates_done:
|
||||
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
|
||||
line_quantity = current_qty * current_line.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, current_line) for line in bom.bom_line_ids] + bom_lines
|
||||
converted_line_quantity = self.env['product.uom']._compute_qty_obj(current_line.product_uom_id, line_quantity / bom.product_qty, bom.product_uom_id)
|
||||
bom_lines = [(line, current_line.product_id, converted_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, 'parent_line': current_line}))
|
||||
else:
|
||||
|
||||
@@ -264,7 +264,7 @@ class MrpProduction(models.Model):
|
||||
def _generate_moves(self):
|
||||
for production in self:
|
||||
production._generate_finished_moves()
|
||||
factor = self.env['product.uom']._compute_qty(production.product_uom_id.id, production.product_qty, production.bom_id.product_uom_id.id)
|
||||
factor = self.env['product.uom']._compute_qty(production.product_uom_id.id, production.product_qty, production.bom_id.product_uom_id.id) / production.bom_id.product_qty
|
||||
boms, lines = production.bom_id.explode(production.product_id, factor, picking_type=production.bom_id.picking_type_id)
|
||||
production._generate_raw_moves(lines)
|
||||
# Check for all draft moves whether they are mto or not
|
||||
@@ -382,7 +382,7 @@ class MrpProduction(models.Model):
|
||||
orders_to_plan = self.filtered(lambda order: order.routing_id and order.state == 'confirmed')
|
||||
UoM = self.env['product.uom']
|
||||
for order in orders_to_plan:
|
||||
quantity = UoM._compute_qty_obj(order.product_uom_id, order.product_qty, order.bom_id.product_uom_id)
|
||||
quantity = UoM._compute_qty_obj(order.product_uom_id, order.product_qty, order.bom_id.product_uom_id) / order.bom_id.product_qty
|
||||
boms, lines = order.bom_id.explode(order.product_id, quantity, picking_type=order.bom_id.picking_type_id)
|
||||
order._generate_workorders(boms)
|
||||
orders_to_plan.write({'state': 'planned'})
|
||||
@@ -402,18 +402,18 @@ class MrpProduction(models.Model):
|
||||
BoMs
|
||||
"""
|
||||
workorders = self.env['mrp.workorder']
|
||||
qty = bom_data['qty']
|
||||
bom_qty = bom_data['qty']
|
||||
|
||||
# Initial qty producing
|
||||
if self.product_id.tracking == 'serial':
|
||||
quantity = 1.0
|
||||
else:
|
||||
quantity = self.product_qty - sum(self.move_finished_ids.mapped('quantity_done'))
|
||||
quantity = quantity if (quantity > 0) else 0
|
||||
|
||||
# TDE FIXME: what is qty compared to quantity ??
|
||||
for operation in bom.routing_id.operation_ids:
|
||||
# create workorder
|
||||
cycle_number = math.ceil(qty / bom.product_qty / operation.workcenter_id.capacity) # TODO: float_round UP
|
||||
cycle_number = math.ceil(bom_qty / operation.workcenter_id.capacity) # TODO: float_round UP
|
||||
duration_expected = (operation.workcenter_id.time_start +
|
||||
operation.workcenter_id.time_stop +
|
||||
cycle_number * operation.time_cycle * 100.0 / operation.workcenter_id.time_efficiency)
|
||||
|
||||
@@ -154,8 +154,8 @@ class MrpUnbuild(models.Model):
|
||||
def _generate_produce_moves(self):
|
||||
moves = self.env['stock.move']
|
||||
for unbuild in self:
|
||||
factor = self.env['product.uom']._compute_qty(unbuild.product_uom_id.id, unbuild.product_qty, unbuild.bom_id.product_uom_id.id)
|
||||
boms, lines = unbuild.bom_id.explode(unbuild.product_id, factor / unbuild.bom_id.product_qty, picking_type=unbuild.bom_id.picking_type_id)
|
||||
factor = self.env['product.uom']._compute_qty(unbuild.product_uom_id.id, unbuild.product_qty, unbuild.bom_id.product_uom_id.id) / unbuild.bom_id.product_qty
|
||||
boms, lines = unbuild.bom_id.explode(unbuild.product_id, factor, picking_type=unbuild.bom_id.picking_type_id)
|
||||
for line, line_data in lines:
|
||||
moves += unbuild._generate_move_from_bom_line(line, line_data['qty'])
|
||||
return moves
|
||||
|
||||
@@ -44,7 +44,7 @@ class ChangeProductionQty(models.TransientModel):
|
||||
raise UserError(_("You have already processed %d. Please input a quantity higher than %d ")%(produced, produced))
|
||||
production.write({'product_qty': wizard.product_qty})
|
||||
bom_point = production.bom_id
|
||||
factor = self.env['product.uom']._compute_qty(production.product_uom_id.id, production.product_qty - production.qty_produced, production.bom_id.product_uom_id.id)
|
||||
factor = self.env['product.uom']._compute_qty(production.product_uom_id.id, production.product_qty - production.qty_produced, production.bom_id.product_uom_id.id) / production.bom_id.product_qty
|
||||
boms, lines = production.bom_id.explode(production.product_id, factor, picking_type=production.bom_id.picking_type_id)
|
||||
for line, line_data in lines:
|
||||
production._update_raw_move(line, line_data)
|
||||
@@ -61,7 +61,7 @@ class ChangeProductionQty(models.TransientModel):
|
||||
wo.qty_producing = quantity
|
||||
if wo.qty_produced < wo.qty_production and wo.state == 'done':
|
||||
wo.state = 'progress'
|
||||
# assign moves; last operation receive all unassigned moves (which case ?)
|
||||
# assign moves; last operation receive all unassigned moves
|
||||
operation = wo.operation_id
|
||||
|
||||
# TODO: following could be put in a function as it is similar as code in _workorders_create
|
||||
|
||||
@@ -27,7 +27,7 @@ class PurchaseOrderLine(models.Model):
|
||||
bom_delivered = {}
|
||||
if bom:
|
||||
bom_delivered[bom.id] = False
|
||||
product_uom_qty_bom = self.env['product.uom']._compute_qty_obj(self.product_uom, self.product_qty, bom.product_uom_id)
|
||||
product_uom_qty_bom = self.env['product.uom']._compute_qty_obj(self.product_uom, self.product_qty, bom.product_uom_id) / bom.product_qty
|
||||
boms, lines = bom.explode(self.product_id, product_uom_qty_bom)
|
||||
for bom_line, data in lines:
|
||||
qty = 0.0
|
||||
|
||||
@@ -38,7 +38,7 @@ class SaleOrderLine(models.Model):
|
||||
bom = self.env['mrp.bom']._bom_find(product=self.product_id)
|
||||
if bom and bom.type == 'phantom':
|
||||
bom_delivered[bom.id] = False
|
||||
product_uom_qty_bom = self.env['product.uom']._compute_qty_obj(self.product_uom, self.product_uom_qty, bom.product_uom_id)
|
||||
product_uom_qty_bom = self.env['product.uom']._compute_qty_obj(self.product_uom, self.product_uom_qty, bom.product_uom_id) / bom.product_qty
|
||||
boms, lines = bom.explode(self.product_id, product_uom_qty_bom)
|
||||
for bom_line, data in lines:
|
||||
qty = 0.0
|
||||
|
||||
Reference in New Issue
Block a user