[FIX] mrp: uom management in workorder
Usecase : create a bom in unit with a component tracked by serial and quantity to produce = 1 unit Create a manufacturing order with a UoM different that the bom one (e.g. Production request = 1 dozen) Launching the produce wizard or a workorder will show to the user a workorder line with 12 component units to consume. But as the component is tracked by serial. We would like to get 12 differents lines of 1 unit. This commit take care of this specific case.
This commit is contained in:
@@ -40,8 +40,19 @@ class MrpAbstractWorkorder(models.AbstractModel):
|
||||
|
||||
# Compute the new quantity for the current component
|
||||
rounding = move_raw.product_uom.rounding
|
||||
new_qty = self.product_uom_id._compute_quantity(
|
||||
if move_raw.product_id.tracking == 'serial':
|
||||
uom = move_raw.product_id.uom_id
|
||||
else:
|
||||
uom = move_raw.product_uom
|
||||
new_qty = move_raw.product_uom._compute_quantity(
|
||||
self.qty_producing * move_raw.unit_factor,
|
||||
uom,
|
||||
round=False
|
||||
)
|
||||
# In case the production uom is different than the workorder uom
|
||||
# it means the product is serial and production uom is not the reference
|
||||
new_qty = self.product_uom_id._compute_quantity(
|
||||
new_qty,
|
||||
self.production_id.product_uom_id,
|
||||
round=False
|
||||
)
|
||||
|
||||
@@ -712,11 +712,15 @@ class MrpProduction(models.Model):
|
||||
duration_expected = (operation.workcenter_id.time_start +
|
||||
operation.workcenter_id.time_stop +
|
||||
cycle_number * operation.time_cycle * 100.0 / operation.workcenter_id.time_efficiency)
|
||||
if self.product_uom_id.uom_type != 'reference':
|
||||
todo_uom = self.env['uom.uom'].search([('category_id', '=', self.product_uom_id.category_id.id), ('uom_type', '=', 'reference')]).id
|
||||
else:
|
||||
todo_uom = self.product_uom_id.id
|
||||
workorder = workorders.create({
|
||||
'name': operation.name,
|
||||
'production_id': self.id,
|
||||
'workcenter_id': operation.workcenter_id.id,
|
||||
'product_uom_id': self.product_uom_id.id,
|
||||
'product_uom_id': todo_uom,
|
||||
'operation_id': operation.id,
|
||||
'duration_expected': duration_expected,
|
||||
'state': len(workorders) == 0 and 'ready' or 'pending',
|
||||
|
||||
@@ -215,7 +215,6 @@ class MrpWorkorder(models.Model):
|
||||
# If last work order, then post lots used
|
||||
# TODO: should be same as checking if for every workorder something has been done?
|
||||
if not self.next_work_order_id:
|
||||
uom_id = self.production_id.product_uom_id
|
||||
self._update_finished_move()
|
||||
self.production_id.move_finished_ids.filtered(
|
||||
lambda move: move.product_id == self.product_id and
|
||||
|
||||
@@ -719,3 +719,60 @@ class TestMrpOrder(TestMrpCommon):
|
||||
move_line_finished = mo.move_finished_ids.mapped('move_line_ids').filtered(lambda m: m.qty_done)
|
||||
self.assertEqual(move_line_finished.qty_done, 1)
|
||||
self.assertEqual(move_line_finished.product_uom_id, unit, 'Should be 1 unit since the tracking is serial.')
|
||||
|
||||
def test_product_produce_uom_2(self):
|
||||
unit = self.env.ref("uom.product_uom_unit")
|
||||
categ_unit_id = self.env.ref('uom.product_uom_categ_unit')
|
||||
paire = self.env['uom.uom'].create({
|
||||
'name': 'Paire',
|
||||
'factor_inv': 2,
|
||||
'uom_type': 'bigger',
|
||||
'rounding': 0.001,
|
||||
'category_id': categ_unit_id.id
|
||||
})
|
||||
binocular = self.env['product.product'].create({
|
||||
'name': 'Binocular',
|
||||
'type': 'product',
|
||||
'uom_id': unit.id,
|
||||
'uom_po_id': unit.id
|
||||
})
|
||||
nocular = self.env['product.product'].create({
|
||||
'name': 'Nocular',
|
||||
'type': 'product',
|
||||
'tracking': 'serial',
|
||||
'uom_id': unit.id,
|
||||
'uom_po_id': unit.id
|
||||
})
|
||||
bom_binocular = self.env['mrp.bom'].create({
|
||||
'product_tmpl_id': binocular.product_tmpl_id.id,
|
||||
'product_qty': 1,
|
||||
'product_uom_id': unit.id,
|
||||
'bom_line_ids': [(0, 0, {
|
||||
'product_id': nocular.id,
|
||||
'product_qty': 1,
|
||||
'product_uom_id': paire.id
|
||||
})]
|
||||
})
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
mo_form.product_id = binocular
|
||||
mo_form.bom_id = bom_binocular
|
||||
mo_form.product_uom_id = unit
|
||||
mo_form.product_qty = 1
|
||||
mo = mo_form.save()
|
||||
|
||||
mo.action_confirm()
|
||||
self.assertEqual(mo.move_raw_ids.product_uom_qty, 1, 'Quantity should be 1.')
|
||||
self.assertEqual(mo.move_raw_ids.product_uom, paire, 'Move UoM should be "Paire".')
|
||||
|
||||
# produce product
|
||||
produce_form = Form(self.env['mrp.product.produce'].with_context({
|
||||
'active_id': mo.id,
|
||||
'active_ids': [mo.id],
|
||||
}))
|
||||
product_produce = produce_form.save()
|
||||
self.assertEqual(product_produce.qty_producing, 1)
|
||||
self.assertEqual(len(product_produce.workorder_line_ids), 2, 'Should be 2 lines since the component tracking is serial and quantity 2.')
|
||||
self.assertEqual(product_produce.workorder_line_ids[0].qty_to_consume, 1, 'Should be 1 unit since the tracking is serial and quantity 2.')
|
||||
self.assertEqual(product_produce.workorder_line_ids[0].product_uom_id, unit, 'Should be the product uom so "unit"')
|
||||
self.assertEqual(product_produce.workorder_line_ids[1].qty_to_consume, 1, 'Should be 1 unit since the tracking is serial and quantity 2.')
|
||||
self.assertEqual(product_produce.workorder_line_ids[1].product_uom_id, unit, 'should be the product uom so "unit"')
|
||||
|
||||
Reference in New Issue
Block a user