diff options
| author | Ankita Raval <anr@odoo.com> | 2019-05-13 05:26:10 +0000 |
|---|---|---|
| committer | Arnold Moyaux <arm@odoo.com> | 2019-06-14 14:39:44 +0000 |
| commit | 41870f0000b2b078d7f6588551beef808f3171cf (patch) | |
| tree | 13b5296b101c10393483ffd2f70a327c528c0de3 /addons | |
| parent | 867fb21b051e21e2e8ef2941bda8e306b7bb1aa1 (diff) | |
[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>
Diffstat (limited to 'addons')
| -rw-r--r-- | addons/mrp/models/mrp_production.py | 7 | ||||
| -rw-r--r-- | addons/mrp/tests/test_order.py | 33 | ||||
| -rw-r--r-- | addons/mrp/wizard/change_production_qty.py | 3 | ||||
| -rw-r--r-- | addons/sale_mrp/tests/test_sale_mrp_flow.py | 45 |
4 files changed, 84 insertions, 4 deletions
diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index db7f824aadc..739ce795fe7 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -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, diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index f45dc86d3f9..1445e240e97 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -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") diff --git a/addons/mrp/wizard/change_production_qty.py b/addons/mrp/wizard/change_production_qty.py index a701ddb01b0..9e40bb63b67 100644 --- a/addons/mrp/wizard/change_production_qty.py +++ b/addons/mrp/wizard/change_production_qty.py @@ -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: diff --git a/addons/sale_mrp/tests/test_sale_mrp_flow.py b/addons/sale_mrp/tests/test_sale_mrp_flow.py index 5f46e0b969e..ea99ad2b5fc 100644 --- a/addons/sale_mrp/tests/test_sale_mrp_flow.py +++ b/addons/sale_mrp/tests/test_sale_mrp_flow.py @@ -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.') |
