def setUp(self): super(TestMultistepManufacturing, self).setUp() self.MrpProduction = self.env['mrp.production'] # Create warehouse warehouse_form = Form(self.env['stock.warehouse']) warehouse_form.name = 'Test' warehouse_form.code = 'Test' self.warehouse = warehouse_form.save() self.uom_unit = self.env.ref('uom.product_uom_unit') # Create manufactured product product_form = Form(self.env['product.product']) product_form.name = 'Stick' product_form.uom_id = self.uom_unit product_form.uom_po_id = self.uom_unit product_form.route_ids.clear() product_form.route_ids.add(self.warehouse.manufacture_pull_id.route_id) product_form.route_ids.add(self.warehouse.mto_pull_id.route_id) self.product_manu = product_form.save() # Create raw product for manufactured product product_form = Form(self.env['product.product']) product_form.name = 'Raw Stick' product_form.uom_id = self.uom_unit product_form.uom_po_id = self.uom_unit self.product_raw = product_form.save() # Create bom for manufactured product bom_product_form = Form(self.env['mrp.bom']) bom_product_form.product_id = self.product_manu bom_product_form.product_tmpl_id = self.product_manu.product_tmpl_id bom_product_form.product_qty = 1.0 bom_product_form.type = 'normal' with bom_product_form.bom_line_ids.new() as bom_line: bom_line.product_id = self.product_raw bom_line.product_qty = 2.0 self.bom_prod_manu = bom_product_form.save() # Create sale order sale_form = Form(self.env['sale.order']) sale_form.partner_id = self.env.ref('base.res_partner_1') sale_form.picking_policy = 'direct' sale_form.warehouse_id = self.warehouse with sale_form.order_line.new() as line: line.name = self.product_manu.name line.product_id = self.product_manu line.product_uom_qty = 1.0 line.product_uom = self.uom_unit line.price_unit = 10.0 self.sale_order = sale_form.save()
def test_reordering_rule(self): """ - Receive products in 2 steps - The product has a reordering rule - On the po generated, the source document should be the name of the reordering rule """ warehouse_1 = self.env['stock.warehouse'].search( [('company_id', '=', self.env.user.id)], limit=1) warehouse_1.write({'reception_steps': 'two_steps'}) # Create a supplier partner = self.env['res.partner'].create({'name': 'Smith'}) # create product and set the vendor product_form = Form(self.env['product.product']) product_form.name = 'Product A' product_form.type = 'product' with product_form.seller_ids.new() as seller: seller.name = partner product_form.route_ids.add( self.env.ref('purchase_stock.route_warehouse0_buy')) product_01 = product_form.save() # create reordering rule orderpoint_form = Form(self.env['stock.warehouse.orderpoint']) orderpoint_form.warehouse_id = warehouse_1 orderpoint_form.location_id = warehouse_1.lot_stock_id orderpoint_form.product_id = product_01 orderpoint_form.product_min_qty = 0.000 orderpoint_form.product_max_qty = 0.000 order_point = orderpoint_form.save() # Create Delivery Order of 10 product picking_form = Form(self.env['stock.picking']) picking_form.partner_id = partner picking_form.picking_type_id = self.env.ref('stock.picking_type_out') with picking_form.move_ids_without_package.new() as move: move.product_id = product_01 move.product_uom_qty = 10.0 customer_picking = picking_form.save() # picking confirm customer_picking.action_confirm() # Run scheduler self.env['procurement.group'].run_scheduler() # Check purchase order created or not purchase_order = self.env['purchase.order'].search([('partner_id', '=', partner.id)]) self.assertTrue(purchase_order, 'No purchase order created.') # On the po generated, the source document should be the name of the reordering rule self.assertEqual( order_point.name, purchase_order.origin, 'Source document on purchase order should be the name of the reordering rule.' )
def test_employee_resource(self): _tz = 'Pacific/Apia' self.res_users_hr_officer.company_id.resource_calendar_id.tz = _tz Employee = self.env['hr.employee'].with_user(self.res_users_hr_officer) employee_form = Form(Employee) employee_form.name = 'Raoul Grosbedon' employee_form.work_email = '*****@*****.**' employee = employee_form.save() self.assertEqual(employee.tz, _tz)
def setUp(self): super(TestMultistepManufacturingWarehouse, self).setUp() # Create warehouse self.customer_location = self.env['ir.model.data'].xmlid_to_res_id( 'stock.stock_location_customers') warehouse_form = Form(self.env['stock.warehouse']) warehouse_form.name = 'Test Warehouse' warehouse_form.code = 'TWH' self.warehouse = warehouse_form.save() self.uom_unit = self.env.ref('uom.product_uom_unit') # Create manufactured product product_form = Form(self.env['product.product']) product_form.name = 'Stick' product_form.uom_id = self.uom_unit product_form.uom_po_id = self.uom_unit product_form.type = 'product' product_form.route_ids.clear() product_form.route_ids.add(self.warehouse.manufacture_pull_id.route_id) product_form.route_ids.add(self.warehouse.mto_pull_id.route_id) self.finished_product = product_form.save() # Create raw product for manufactured product product_form = Form(self.env['product.product']) product_form.name = 'Raw Stick' product_form.type = 'product' product_form.uom_id = self.uom_unit product_form.uom_po_id = self.uom_unit self.raw_product = product_form.save() # Create bom for manufactured product bom_product_form = Form(self.env['mrp.bom']) bom_product_form.product_id = self.finished_product bom_product_form.product_tmpl_id = self.finished_product.product_tmpl_id bom_product_form.product_qty = 1.0 bom_product_form.type = 'normal' with bom_product_form.bom_line_ids.new() as bom_line: bom_line.product_id = self.raw_product bom_line.product_qty = 2.0 self.bom = bom_product_form.save()
def test_employee_from_user_tz_no_reset(self): _tz = 'Pacific/Apia' self.res_users_hr_officer.tz = False Employee = self.env['hr.employee'].with_user(self.res_users_hr_officer) employee_form = Form(Employee) employee_form.name = 'Raoul Grosbedon' employee_form.work_email = '*****@*****.**' employee_form.tz = _tz employee_form.user_id = self.res_users_hr_officer employee = employee_form.save() self.assertEqual(employee.name, 'Raoul Grosbedon') self.assertEqual(employee.work_email, self.res_users_hr_officer.email) self.assertEqual(employee.tz, _tz)
def test_employee_from_user(self): _tz = 'Pacific/Apia' _tz2 = 'America/Tijuana' self.res_users_hr_officer.company_id.resource_calendar_id.tz = _tz self.res_users_hr_officer.tz = _tz2 Employee = self.env['hr.employee'].with_user(self.res_users_hr_officer) employee_form = Form(Employee) employee_form.name = 'Raoul Grosbedon' employee_form.work_email = '*****@*****.**' employee_form.user_id = self.res_users_hr_officer employee = employee_form.save() self.assertEqual(employee.name, 'Raoul Grosbedon') self.assertEqual(employee.work_email, self.res_users_hr_officer.email) self.assertEqual(employee.tz, self.res_users_hr_officer.tz)
def test_toggle_active_warehouse_2(self): wh = Form(self.env['stock.warehouse']) wh.name = "The attic of Willy" wh.code = "WIL" wh.reception_steps = "two_steps" wh.delivery_steps = "pick_pack_ship" warehouse = wh.save() warehouse.resupply_wh_ids = [(6, 0, [self.warehouse_1.id])] custom_location = Form(self.env['stock.location']) custom_location.name = "A Trunk" custom_location.location_id = warehouse.lot_stock_id custom_location = custom_location.save() # Add a warehouse on the route. warehouse.reception_route_id.write( {'warehouse_ids': [(4, self.warehouse_1.id)]}) route = Form(self.env['stock.location.route']) route.name = "Stair" route = route.save() route.warehouse_ids = [(6, 0, [warehouse.id, self.warehouse_1.id])] # Pre archive a location and a route warehouse.delivery_route_id.toggle_active() warehouse.wh_pack_stock_loc_id.toggle_active() # Archive warehouse warehouse.toggle_active() # Global rule self.assertFalse(warehouse.mto_pull_id.active) # Route self.assertTrue(warehouse.reception_route_id.active) self.assertFalse(warehouse.delivery_route_id.active) self.assertTrue(route.active) # Location self.assertFalse(warehouse.lot_stock_id.active) self.assertFalse(warehouse.wh_input_stock_loc_id.active) self.assertFalse(warehouse.wh_qc_stock_loc_id.active) self.assertFalse(warehouse.wh_output_stock_loc_id.active) self.assertFalse(warehouse.wh_pack_stock_loc_id.active) self.assertFalse(custom_location.active) # Picking Type self.assertFalse(warehouse.in_type_id.active) self.assertFalse(warehouse.out_type_id.active) self.assertFalse(warehouse.int_type_id.active) self.assertFalse(warehouse.pick_type_id.active) self.assertFalse(warehouse.pack_type_id.active) # Active warehouse warehouse.toggle_active() # Global rule self.assertTrue(warehouse.mto_pull_id.active) # Route self.assertTrue(warehouse.reception_route_id.active) self.assertTrue(warehouse.delivery_route_id.active) # Location self.assertTrue(warehouse.lot_stock_id.active) self.assertTrue(warehouse.wh_input_stock_loc_id.active) self.assertFalse(warehouse.wh_qc_stock_loc_id.active) self.assertTrue(warehouse.wh_output_stock_loc_id.active) self.assertTrue(warehouse.wh_pack_stock_loc_id.active) self.assertTrue(custom_location.active) # Picking Type self.assertTrue(warehouse.in_type_id.active) self.assertTrue(warehouse.out_type_id.active) self.assertTrue(warehouse.int_type_id.active) self.assertTrue(warehouse.pick_type_id.active) self.assertTrue(warehouse.pack_type_id.active)
def test_toggle_active_warehouse_1(self): """ Basic test that create a warehouse with classic configuration. Archive it and check that locations, picking types, routes, rules are correclty active or archive. """ wh = Form(self.env['stock.warehouse']) wh.name = "The attic of Willy" wh.code = "WIL" warehouse = wh.save() custom_location = Form(self.env['stock.location']) custom_location.name = "A Trunk" custom_location.location_id = warehouse.lot_stock_id custom_location = custom_location.save() # Archive warehouse warehouse.toggle_active() # Global rule self.assertFalse(warehouse.mto_pull_id.active) # Route self.assertFalse(warehouse.reception_route_id.active) self.assertFalse(warehouse.delivery_route_id.active) # Location self.assertFalse(warehouse.lot_stock_id.active) self.assertFalse(warehouse.wh_input_stock_loc_id.active) self.assertFalse(warehouse.wh_qc_stock_loc_id.active) self.assertFalse(warehouse.wh_output_stock_loc_id.active) self.assertFalse(warehouse.wh_pack_stock_loc_id.active) self.assertFalse(custom_location.active) # Picking Type self.assertFalse(warehouse.in_type_id.active) self.assertFalse(warehouse.out_type_id.active) self.assertFalse(warehouse.int_type_id.active) self.assertFalse(warehouse.pick_type_id.active) self.assertFalse(warehouse.pack_type_id.active) # Active warehouse warehouse.toggle_active() # Global rule self.assertTrue(warehouse.mto_pull_id.active) # Route self.assertTrue(warehouse.reception_route_id.active) self.assertTrue(warehouse.delivery_route_id.active) # Location self.assertTrue(warehouse.lot_stock_id.active) self.assertFalse(warehouse.wh_input_stock_loc_id.active) self.assertFalse(warehouse.wh_qc_stock_loc_id.active) self.assertFalse(warehouse.wh_output_stock_loc_id.active) self.assertFalse(warehouse.wh_pack_stock_loc_id.active) self.assertTrue(custom_location.active) # Picking Type self.assertTrue(warehouse.in_type_id.active) self.assertTrue(warehouse.out_type_id.active) self.assertTrue(warehouse.int_type_id.active) self.assertFalse(warehouse.pick_type_id.active) self.assertFalse(warehouse.pack_type_id.active)
def test_01_compute_price_operation_cost(self): """Test calcuation of bom cost with operations.""" workcenter_from1 = Form(self.env['mrp.workcenter']) workcenter_from1.name = 'Workcenter' workcenter_from1.time_efficiency = 100 workcenter_from1.capacity = 2 workcenter_from1.oee_target = 100 workcenter_from1.time_start = 0 workcenter_from1.time_stop = 0 workcenter_from1.costs_hour = 100 workcenter_1 = workcenter_from1.save() routing_form1 = Form(self.Routing) routing_form1.name = 'Assembly Furniture' routing_1 = routing_form1.save() operation_1 = self.operation.create({ 'name': 'Cutting', 'workcenter_id': workcenter_1.id, 'routing_id': routing_1.id, 'time_mode': 'manual', 'time_cycle_manual': 20, 'batch': 'no', 'sequence': 1, }) operation_2 = self.operation.create({ 'name': 'Drilling', 'workcenter_id': workcenter_1.id, 'routing_id': routing_1.id, 'time_mode': 'manual', 'time_cycle_manual': 25, 'batch': 'no', 'sequence': 2, }) operation_3 = self.operation.create({ 'name': 'Fitting', 'workcenter_id': workcenter_1.id, 'routing_id': routing_1.id, 'time_mode': 'manual', 'time_cycle_manual': 30, 'batch': 'no', 'sequence': 3, }) # ----------------------------------------------------------------- # Dinning Table Operation Cost(1 Unit) # ----------------------------------------------------------------- # Operation cost calculate for 1 units # Cutting (20 / 60) * 100 = 33.33 # Drilling (25 / 60) * 100 = 41.67 # Fitting (30 / 60) * 100 = 50.00 # ---------------------------------------- # Operation Cost 1 unit = 125 # ----------------------------------------------------------------- self.bom_1.routing_id = routing_1.id # -------------------------------------------------------------------------- # Table Head Operation Cost (1 Dozen) # -------------------------------------------------------------------------- # Operation cost calculate for 1 dozens # Cutting (20 * 1 / 60) * 100 = 33,33 # Drilling (25 * 1 / 60) * 100 = 41,67 # Fitting (30 * 1 / 60) * 100 = 50 # ---------------------------------------- # Operation Cost 1 dozen (125 per dozen) and 10.42 for 1 Unit # -------------------------------------------------------------------------- self.bom_2.routing_id = routing_1.id self.assertEqual(self.dining_table.standard_price, 1000, "Initial price of the Product should be 1000") self.dining_table.button_bom_cost() # Total cost of Dining Table = (550) + Total cost of operations (125) = 675.0 self.assertEquals( float_round(self.dining_table.standard_price, precision_digits=2), 675.0, "After computing price from BoM price should be 612.5") self.Product.browse([self.dining_table.id, self.table_head.id]).action_bom_cost() # Total cost of Dining Table = (718.75) + Total cost of all operations (125 + 10.42) = 854.17 self.assertEquals( float_compare(self.dining_table.standard_price, 854.17, precision_digits=2), 0, "After computing price from BoM price should be 786.46")
def test_create_res_lang(self): lang_form = Form(self.env['res.lang']) lang_form.name = 'a lang name' lang_form.code = 'a lang code' lang_form.save()
def test_create_res_country(self): country_form = Form(self.env['res.country']) country_form.name = 'a country' country_form.save()
def test_create_res_bank(self): bank_form = Form(self.env['res.bank']) bank_form.name = 'a bank' bank_form.save()
def test_create_res_group(self): group_form = Form(self.env['res.groups']) group_form.name = 'a group' group_form.save()
def test_create_res_users(self): user_form = Form(self.env['res.users']) user_form.login = '******' user_form.name = 'a user name' user_form.save()
def test_create_res_partner(self): partner_form = Form(self.env['res.partner']) partner_form.name = 'a partner' partner_form.save()
def create_product(name): p = Form(self.env['product.product']) p.name = name p.type = 'product' return p.save()
def test_20_bom_report(self): """ Simulate a crumble receipt with mrp and open the bom structure report and check that data insde are correct. """ uom_kg = self.env.ref('uom.product_uom_kgm') uom_litre = self.env.ref('uom.product_uom_litre') crumble = self.env['product.product'].create({ 'name': 'Crumble', 'type': 'product', 'uom_id': uom_kg.id, 'uom_po_id': uom_kg.id, }) butter = self.env['product.product'].create({ 'name': 'Butter', 'type': 'product', 'uom_id': uom_kg.id, 'uom_po_id': uom_kg.id, 'standard_price': 7.01 }) biscuit = self.env['product.product'].create({ 'name': 'Biscuit', 'type': 'product', 'uom_id': uom_kg.id, 'uom_po_id': uom_kg.id, 'standard_price': 1.5 }) bom_form_crumble = Form(self.env['mrp.bom']) bom_form_crumble.product_tmpl_id = crumble.product_tmpl_id bom_form_crumble.product_qty = 11 bom_form_crumble.product_uom_id = uom_kg bom_crumble = bom_form_crumble.save() with Form(bom_crumble) as bom: with bom.bom_line_ids.new() as line: line.product_id = butter line.product_uom_id = uom_kg line.product_qty = 5 with bom.bom_line_ids.new() as line: line.product_id = biscuit line.product_uom_id = uom_kg line.product_qty = 6 workcenter = self.env['mrp.workcenter'].create({ 'costs_hour': 10, 'name': 'Deserts Table' }) routing_form = Form(self.env['mrp.routing']) routing_form.name = "Crumble process" routing_crumble = routing_form.save() with Form(routing_crumble) as routing: with routing.operation_ids.new() as operation: operation.workcenter_id = workcenter operation.name = 'Prepare biscuits' operation.time_cycle_manual = 5 with routing.operation_ids.new() as operation: operation.workcenter_id = workcenter operation.name = 'Prepare butter' operation.time_cycle_manual = 3 with routing.operation_ids.new() as operation: operation.workcenter_id = workcenter operation.name = 'Mix manually' operation.time_cycle_manual = 5 bom_crumble.routing_id = routing_crumble.id # TEST BOM STRUCTURE VALUE WITH BOM QUANTITY report_values = self.env[ 'report.mrp.report_bom_structure']._get_report_data( bom_id=bom_crumble.id, searchQty=11, searchVariant=False) # 5 min 'Prepare biscuits' + 3 min 'Prepare butter' + 5 min 'Mix manually' = 13 minutes self.assertEqual( report_values['lines']['operations_time'], 13.0, 'Operation time should be the same for 1 unit or for the batch') # Operation cost is the sum of operation line. operation_cost = float_round(5 / 60 * 10, precision_digits=2) * 2 + float_round( 3 / 60 * 10, precision_digits=2) self.assertEqual( float_compare(report_values['lines']['operations_cost'], operation_cost, precision_digits=2), 0, '13 minute for 10$/hours -> 2.16') for component_line in report_values['lines']['components']: # standard price * bom line quantity * current quantity / bom finished product quantity if component_line['prod_id'] == butter.id: # 5 kg of butter at 7.01$ for 11kg of crumble -> 35.05$ self.assertEqual( float_compare(component_line['total'], (7.01 * 5), precision_digits=2), 0) if component_line['prod_id'] == biscuit.id: # 6 kg of biscuits at 1.50$ for 11kg of crumble -> 9$ self.assertEqual( float_compare(component_line['total'], (1.5 * 6), precision_digits=2), 0) # total price = 35.05 + 9 + operation_cost(0.83 + 0.83 + 0.5 = 2.16) = 46,21 self.assertEqual( float_compare(report_values['lines']['total'], 46.21, precision_digits=2), 0, 'Product Bom Price is not correct') self.assertEqual( float_compare(report_values['lines']['total'] / 11.0, 4.20, precision_digits=2), 0, 'Product Unit Bom Price is not correct') # TEST BOM STRUCTURE VALUE BY UNIT report_values = self.env[ 'report.mrp.report_bom_structure']._get_report_data( bom_id=bom_crumble.id, searchQty=1, searchVariant=False) # 5 min 'Prepare biscuits' + 3 min 'Prepare butter' + 5 min 'Mix manually' = 13 minutes self.assertEqual( report_values['lines']['operations_time'], 13.0, 'Operation time should be the same for 1 unit or for the batch') # Operation cost is the sum of operation line. operation_cost = float_round(5 / 60 * 10, precision_digits=2) * 2 + float_round( 3 / 60 * 10, precision_digits=2) self.assertEqual( float_compare(report_values['lines']['operations_cost'], operation_cost, precision_digits=2), 0, '13 minute for 10$/hours -> 2.16') for component_line in report_values['lines']['components']: # standard price * bom line quantity * current quantity / bom finished product quantity if component_line['prod_id'] == butter.id: # 5 kg of butter at 7.01$ for 11kg of crumble -> / 11 for price per unit (3.19) self.assertEqual( float_compare(component_line['total'], (7.01 * 5) * (1 / 11), precision_digits=2), 0) if component_line['prod_id'] == biscuit.id: # 6 kg of biscuits at 1.50$ for 11kg of crumble -> / 11 for price per unit (0.82) self.assertEqual( float_compare(component_line['total'], (1.5 * 6) * (1 / 11), precision_digits=2), 0) # total price = 3.19 + 0.82 + operation_cost(0.83 + 0.83 + 0.5 = 2.16) = 6,17 self.assertEqual( float_compare(report_values['lines']['total'], 6.17, precision_digits=2), 0, 'Product Unit Bom Price is not correct') # TEST OPERATION COST WHEN PRODUCED QTY > BOM QUANTITY report_values_12 = self.env[ 'report.mrp.report_bom_structure']._get_report_data( bom_id=bom_crumble.id, searchQty=12, searchVariant=False) report_values_22 = self.env[ 'report.mrp.report_bom_structure']._get_report_data( bom_id=bom_crumble.id, searchQty=22, searchVariant=False) operation_cost = float_round(10 / 60 * 10, precision_digits=2) * 2 + float_round( 6 / 60 * 10, precision_digits=2) # Both needs 2 operation cycle self.assertEqual(report_values_12['lines']['operations_cost'], report_values_22['lines']['operations_cost']) self.assertEqual(report_values_22['lines']['operations_cost'], operation_cost) report_values_23 = self.env[ 'report.mrp.report_bom_structure']._get_report_data( bom_id=bom_crumble.id, searchQty=23, searchVariant=False) operation_cost = float_round(15 / 60 * 10, precision_digits=2) * 2 + float_round( 9 / 60 * 10, precision_digits=2) self.assertEqual(report_values_23['lines']['operations_cost'], operation_cost) # Create a more complex BoM with a sub product cheese_cake = self.env['product.product'].create({ 'name': 'Cheese Cake 300g', 'type': 'product', }) cream = self.env['product.product'].create({ 'name': 'cream', 'type': 'product', 'uom_id': uom_litre.id, 'uom_po_id': uom_litre.id, 'standard_price': 5.17, }) bom_form_cheese_cake = Form(self.env['mrp.bom']) bom_form_cheese_cake.product_tmpl_id = cheese_cake.product_tmpl_id bom_form_cheese_cake.product_qty = 60 bom_form_cheese_cake.product_uom_id = self.uom_unit bom_cheese_cake = bom_form_cheese_cake.save() with Form(bom_cheese_cake) as bom: with bom.bom_line_ids.new() as line: line.product_id = cream line.product_uom_id = uom_litre line.product_qty = 3 with bom.bom_line_ids.new() as line: line.product_id = crumble line.product_uom_id = uom_kg line.product_qty = 5.4 workcenter_2 = self.env['mrp.workcenter'].create({ 'name': 'cake mounting', 'costs_hour': 20, 'time_start': 10, 'time_stop': 15 }) routing_form = Form(self.env['mrp.routing']) routing_form.name = "Cheese cake process" routing_cheese = routing_form.save() with Form(routing_cheese) as routing: with routing.operation_ids.new() as operation: operation.workcenter_id = workcenter operation.name = 'Mix cheese and crumble' operation.time_cycle_manual = 10 with routing.operation_ids.new() as operation: operation.workcenter_id = workcenter_2 operation.name = 'Cake mounting' operation.time_cycle_manual = 5 bom_cheese_cake.routing_id = routing_cheese.id # TEST CHEESE BOM STRUCTURE VALUE WITH BOM QUANTITY report_values = self.env[ 'report.mrp.report_bom_structure']._get_report_data( bom_id=bom_cheese_cake.id, searchQty=60, searchVariant=False) self.assertEqual( report_values['lines']['operations_time'], 40.0, 'Operation time should be the same for 1 unit or for the batch') # Operation cost is the sum of operation line. operation_cost = float_round( 10 / 60 * 10, precision_digits=2) + float_round(30 / 60 * 20, precision_digits=2) self.assertEqual( float_compare(report_values['lines']['operations_cost'], operation_cost, precision_digits=2), 0) for component_line in report_values['lines']['components']: # standard price * bom line quantity * current quantity / bom finished product quantity if component_line['prod_id'] == cream.id: # 3 liter of cream at 5.17$ for 60 unit of cheese cake -> 15.51$ self.assertEqual( float_compare(component_line['total'], (3 * 5.17), precision_digits=2), 0) if component_line['prod_id'] == crumble.id: # 5.4 kg of crumble at the cost of a batch. crumble_cost = self.env[ 'report.mrp.report_bom_structure']._get_report_data( bom_id=bom_crumble.id, searchQty=5.4, searchVariant=False)['lines']['total'] self.assertEqual( float_compare(component_line['total'], crumble_cost, precision_digits=2), 0) # total price = 15.51 + crumble_cost + operation_cost(10 + 1.67 = 11.67) = 27.18 + crumble_cost self.assertEqual( float_compare(report_values['lines']['total'], 27.18 + crumble_cost, precision_digits=2), 0, 'Product Bom Price is not correct')