[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:
Ankita Raval
2019-06-14 14:39:44 +00:00
committed by Arnold Moyaux
parent 867fb21b05
commit 41870f0000
4 changed files with 84 additions and 4 deletions
+3 -4
View File
@@ -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,
+33
View File
@@ -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.')