# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from datetime import timedelta from odoo import fields from odoo.addons.stock.tests.common import TestStockCommon from odoo.tests import Form class TestSaleMrpLeadTime(TestStockCommon): @classmethod def setUpClass(cls): super().setUpClass() cls.env.ref('stock.route_warehouse0_mto').active = True # Update the product_1 with type, route, Manufacturing Lead Time and Customer Lead Time with Form(cls.product_1) as p1: # `type` is invisible in the view, # and it's a compute field based on `type` which is the field visible in the view p1.is_storable = True p1.sale_delay = 5.0 p1.route_ids.clear() p1.route_ids.add(cls.warehouse_1.manufacture_pull_id.route_id) p1.route_ids.add(cls.warehouse_1.mto_pull_id.route_id) # Update the product_2 with type with Form(cls.product_2) as p2: # `type` is invisible in the view, # and it's a compute field based on `type` which is the field visible in the view p2.type = 'consu' # Create Bill of materials for product_1 with Form(cls.env['mrp.bom']) as bom: bom.product_tmpl_id = cls.product_1.product_tmpl_id bom.product_qty = 2 bom.produce_delay = 5.0 with bom.bom_line_ids.new() as line: line.product_id = cls.product_2 line.product_qty = 4 cls.warehouse_3_steps_pull = cls.env['stock.warehouse'].create({ 'name': 'Warehouse 3 steps', 'code': '3S', 'delivery_steps': 'pick_pack_ship', }) delivery_route_3 = cls.warehouse_3_steps_pull.delivery_route_id delivery_route_3.rule_ids[0].write({ 'location_dest_id': delivery_route_3.rule_ids[1].location_src_id.id, }) delivery_route_3.rule_ids[1].write({'action': 'pull'}) delivery_route_3.rule_ids[2].write({'action': 'pull'}) cls.warehouse_3_steps_pull.mto_pull_id.write({ 'location_dest_id': delivery_route_3.rule_ids[1].location_src_id.id, }) def test_00_product_company_level_delays(self): """ In order to check schedule date, set product's Manufacturing Lead Time and Customer Lead Time and also set company's Manufacturing Lead Time and Sales Safety Days.""" company = self.env.ref('base.main_company') # Update company with Manufacturing Lead Time and Sales Safety Days company.write({'manufacturing_lead': 3.0, 'security_lead': 3.0}) # Create sale order of product_1 order_form = Form(self.env['sale.order']) order_form.partner_id = self.partner_1 with order_form.order_line.new() as line: line.product_id = self.product_1 line.product_uom_qty = 10 order = order_form.save() # Confirm sale order order.action_confirm() # Check manufacturing order created or not manufacturing_order = self.env['mrp.production'].search([('product_id', '=', self.product_1.id), ('move_dest_ids', 'in', order.picking_ids[0].move_ids.ids)]) self.assertTrue(manufacturing_order, 'Manufacturing order should be created.') # Check schedule date of picking deadline_picking = fields.Datetime.from_string(order.date_order) + timedelta(days=self.product_1.sale_delay) out_date = deadline_picking - timedelta(days=company.security_lead) self.assertAlmostEqual( order.picking_ids[0].scheduled_date, out_date, delta=timedelta(seconds=1), msg='Schedule date of picking should be equal to: Order date + Customer Lead Time - Sales Safety Days.' ) self.assertAlmostEqual( order.picking_ids[0].date_deadline, deadline_picking, delta=timedelta(seconds=1), msg='Deadline date of picking should be equal to: Order date + Customer Lead Time.' ) # Check schedule date and deadline of manufacturing order mo_date_start = out_date - timedelta(days=manufacturing_order.bom_id.produce_delay) - timedelta(days=company.manufacturing_lead) self.assertAlmostEqual( fields.Datetime.from_string(manufacturing_order.date_start), mo_date_start, delta=timedelta(seconds=1), msg="Schedule date of manufacturing order should be equal to: Schedule date of picking - product's Manufacturing Lead Time - company's Manufacturing Lead Time." ) self.assertAlmostEqual( fields.Datetime.from_string(manufacturing_order.date_deadline), deadline_picking, delta=timedelta(seconds=1), msg="Deadline date of manufacturing order should be equal to the deadline of sale picking" ) def test_01_product_route_level_delays(self): """ In order to check schedule dates, set product's Manufacturing Lead Time and Customer Lead Time and also set warehouse route's delay.""" warehouse = self.warehouse_3_steps_pull # Set delay on pull rule for pull_rule in warehouse.delivery_route_id.rule_ids: pull_rule.write({'delay': 2}) # Create sale order of product_1 order_form = Form(self.env['sale.order']) order_form.partner_id = self.partner_1 order_form.warehouse_id = warehouse with order_form.order_line.new() as line: line.product_id = self.product_1 line.product_uom_qty = 6 order = order_form.save() # Confirm sale order order.action_confirm() # Run scheduler self.env['procurement.group'].run_scheduler() # Check manufacturing order created or not manufacturing_order = self.env['mrp.production'].search([('product_id', '=', self.product_1.id)]) self.assertTrue(manufacturing_order, 'Manufacturing order should be created.') # Check the picking crated or not self.assertTrue(order.picking_ids, "Pickings should be created.") # Check schedule date of ship type picking out = order.picking_ids.filtered(lambda r: r.picking_type_id == warehouse.out_type_id) out_min_date = fields.Datetime.from_string(out.scheduled_date) out_date = fields.Datetime.from_string(order.date_order) + timedelta(days=self.product_1.sale_delay) - timedelta(days=out.move_ids[0].rule_id.delay) self.assertAlmostEqual( out_min_date, out_date, delta=timedelta(seconds=10), msg='Schedule date of ship type picking should be equal to: order date + Customer Lead Time - pull rule delay.' ) # Check schedule date of pack type picking pack = order.picking_ids.filtered(lambda r: r.picking_type_id == warehouse.pack_type_id) pack_min_date = fields.Datetime.from_string(pack.scheduled_date) pack_date = out_date - timedelta(days=pack.move_ids[0].rule_id.delay) self.assertAlmostEqual( pack_min_date, pack_date, delta=timedelta(seconds=10), msg='Schedule date of pack type picking should be equal to: Schedule date of ship type picking - pull rule delay.' ) # Check schedule date of pick type picking pick = order.picking_ids.filtered(lambda r: r.picking_type_id == warehouse.pick_type_id) pick_min_date = fields.Datetime.from_string(pick.scheduled_date) self.assertAlmostEqual( pick_min_date, pack_date, delta=timedelta(seconds=10), msg='Schedule date of pick type picking should be equal to: Schedule date of pack type picking.' ) # Check schedule date and deadline date of manufacturing order mo_date_start = out_date - timedelta(days=manufacturing_order.bom_id.produce_delay) - timedelta(days=warehouse.delivery_route_id.rule_ids[0].delay) - timedelta(days=self.env.ref('base.main_company').manufacturing_lead) self.assertAlmostEqual( fields.Datetime.from_string(manufacturing_order.date_start), mo_date_start, delta=timedelta(seconds=1), msg="Schedule date of manufacturing order should be equal to: Schedule date of picking - product's Manufacturing Lead Time- delay pull_rule." ) self.assertAlmostEqual( manufacturing_order.date_deadline, order.picking_ids[0].date_deadline, delta=timedelta(seconds=1), msg="Deadline date of manufacturing order should be equal to the deadline of sale picking" )