[IMP] mrp : Crash when products of type service in BoM
Before Commit: If a product type service in a bom, create a manufacturing order of product's bom they returns empty recordset because if product type is not storable and consumable is returns empty object of stock move else they returns the data dictionary. After Commit: If product type service in a bom, create a manufacturing order we returns the empty dictionary rather than empty object of stock move Add a testcases 1) to check manufacturing order is generated of product type of service in bom or not. 2) to check manufacturing order is generate from sale order of product type sevice in bom or not. Task ID - 1981790 closes odoo/odoo#33337 Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
This commit is contained in:
committed by
Arnold Moyaux
parent
867fb21b05
commit
41870f0000
@@ -507,6 +507,9 @@ class MrpProduction(models.Model):
|
||||
factor = production.product_uom_id._compute_quantity(production.product_qty, production.bom_id.product_uom_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 bom_line, line_data in lines:
|
||||
if bom_line.child_bom_id and bom_line.child_bom_id.type == 'phantom' or\
|
||||
bom_line.product_id.type not in ['product', 'consu']:
|
||||
continue
|
||||
moves.append(production._get_move_raw_values(bom_line, line_data))
|
||||
return moves
|
||||
|
||||
@@ -514,10 +517,6 @@ class MrpProduction(models.Model):
|
||||
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']:
|
||||
return self.env['stock.move']
|
||||
source_location = self._get_raw_location()
|
||||
data = {
|
||||
'sequence': bom_line.sequence,
|
||||
|
||||
@@ -942,3 +942,36 @@ class TestMrpOrder(TestMrpCommon):
|
||||
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"')
|
||||
|
||||
def test_product_type_service_1(self):
|
||||
# Create finished product
|
||||
finished_product = self.env['product.product'].create({
|
||||
'name': 'Geyser',
|
||||
'type': 'product',
|
||||
})
|
||||
|
||||
# Create service type product
|
||||
product_raw = self.env['product.product'].create({
|
||||
'name': 'raw Geyser',
|
||||
'type': 'service',
|
||||
})
|
||||
|
||||
# Create bom for finish product
|
||||
bom = self.env['mrp.bom'].create({
|
||||
'product_id': finished_product.id,
|
||||
'product_tmpl_id': finished_product.product_tmpl_id.id,
|
||||
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
|
||||
'product_qty': 1.0,
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [(5, 0), (0, 0, {'product_id': product_raw.id})]
|
||||
})
|
||||
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
mo_form.product_id = finished_product
|
||||
mo_form.bom_id = bom
|
||||
mo_form.product_uom_id = self.env.ref('uom.product_uom_unit')
|
||||
mo_form.product_qty = 1
|
||||
mo = mo_form.save()
|
||||
|
||||
# Check Mo is created or not
|
||||
self.assertTrue(mo, "Mo is created")
|
||||
|
||||
@@ -54,6 +54,9 @@ class ChangeProductionQty(models.TransientModel):
|
||||
boms, lines = production.bom_id.explode(production.product_id, factor, picking_type=production.bom_id.picking_type_id)
|
||||
documents = {}
|
||||
for line, line_data in lines:
|
||||
if line.child_bom_id and line.child_bom_id.type == 'phantom' or\
|
||||
line.product_id.type not in ['product', 'consu']:
|
||||
continue
|
||||
move, old_qty, new_qty = production._update_raw_move(line, line_data)
|
||||
iterate_key = production._get_document_iterate_key(move)
|
||||
if iterate_key:
|
||||
|
||||
@@ -1446,3 +1446,48 @@ class TestSaleMrpFlow(common.TransactionCase):
|
||||
move_component_kg = order.picking_ids[0].move_lines - move_component_unit
|
||||
self.assertEquals(move_component_unit.product_uom_qty, 0.5)
|
||||
self.assertEquals(move_component_kg.product_uom_qty, 0.583)
|
||||
|
||||
def test_product_type_service_1(self):
|
||||
route_manufacture = self.warehouse.manufacture_pull_id.route_id.id
|
||||
route_mto = self.warehouse.mto_pull_id.route_id.id
|
||||
self.uom_unit = self.env.ref('uom.product_uom_unit')
|
||||
|
||||
# Create finished product
|
||||
finished_product = self.env['product.product'].create({
|
||||
'name': 'Geyser',
|
||||
'type': 'product',
|
||||
'route_ids': [(4, route_mto), (4, route_manufacture)],
|
||||
})
|
||||
|
||||
# Create service type product
|
||||
product_raw = self.env['product.product'].create({
|
||||
'name': 'raw Geyser',
|
||||
'type': 'service',
|
||||
})
|
||||
|
||||
# Create bom for finish product
|
||||
bom = self.env['mrp.bom'].create({
|
||||
'product_id': finished_product.id,
|
||||
'product_tmpl_id': finished_product.product_tmpl_id.id,
|
||||
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
|
||||
'product_qty': 1.0,
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [(5, 0), (0, 0, {'product_id': product_raw.id})]
|
||||
})
|
||||
|
||||
# Create sale order
|
||||
sale_form = Form(self.env['sale.order'])
|
||||
sale_form.partner_id = self.env.ref('base.res_partner_1')
|
||||
with sale_form.order_line.new() as line:
|
||||
line.name = finished_product.name
|
||||
line.product_id = finished_product
|
||||
line.product_uom_qty = 1.0
|
||||
line.product_uom = self.uom_unit
|
||||
line.price_unit = 10.0
|
||||
sale_order = sale_form.save()
|
||||
|
||||
sale_order.action_confirm()
|
||||
|
||||
mo = self.env['mrp.production'].search([('product_id', '=', finished_product.id)])
|
||||
|
||||
self.assertTrue(mo, 'Manufacturing order created.')
|
||||
|
||||
Reference in New Issue
Block a user