diff --git a/addons/mrp/models/mrp_workcenter.py b/addons/mrp/models/mrp_workcenter.py index 8444985e490..809ef27301d 100644 --- a/addons/mrp/models/mrp_workcenter.py +++ b/addons/mrp/models/mrp_workcenter.py @@ -299,12 +299,10 @@ class MrpWorkcenter(models.Model): def _get_expected_duration(self, product_id): """Compute the expected duration when using this work-center - Always include workcenter startup time and clean-up time. - In case there are specific capacities defined in the workcenter - that matches the product we are producing. Add the extra-time. + Always use the startup / clean-up time from specific capacity if defined. """ capacity = self.capacity_ids.filtered(lambda p: p.product_id == product_id) - return self.time_start + self.time_stop + (capacity.time_start + capacity.time_stop if capacity else 0.0) + return capacity.time_start + capacity.time_stop if capacity else self.time_start + self.time_stop class WorkcenterTag(models.Model): @@ -478,12 +476,20 @@ class MrpWorkCenterCapacity(models.Model): _description = 'Work Center Capacity' _check_company_auto = True + def _default_time_start(self): + workcenter_id = self.workcenter_id.id or self.env.context.get('default_workcenter_id') + return self.env['mrp.workcenter'].browse(workcenter_id).time_start if workcenter_id else 0.0 + + def _default_time_stop(self): + workcenter_id = self.workcenter_id.id or self.env.context.get('default_workcenter_id') + return self.env['mrp.workcenter'].browse(workcenter_id).time_stop if workcenter_id else 0.0 + workcenter_id = fields.Many2one('mrp.workcenter', string='Work Center', required=True) product_id = fields.Many2one('product.product', string='Product', required=True) product_uom_id = fields.Many2one('uom.uom', string='Product UoM', related='product_id.uom_id') capacity = fields.Float('Capacity', default=1.0, help="Number of pieces that can be produced in parallel for this product.") - time_start = fields.Float('Setup Time (minutes)', help="Time in minutes for the setup.") - time_stop = fields.Float('Cleanup Time (minutes)', help="Time in minutes for the cleaning.") + time_start = fields.Float('Setup Time (minutes)', default=_default_time_start, help="Time in minutes for the setup.") + time_stop = fields.Float('Cleanup Time (minutes)', default=_default_time_stop, help="Time in minutes for the cleaning.") _sql_constraints = [ ('positive_capacity', 'CHECK(capacity > 0)', 'Capacity should be a positive number.'), diff --git a/addons/mrp/tests/test_bom.py b/addons/mrp/tests/test_bom.py index 28691a2c9b2..9685b2ed4be 100644 --- a/addons/mrp/tests/test_bom.py +++ b/addons/mrp/tests/test_bom.py @@ -602,8 +602,8 @@ class TestBoM(TestMrpCommon): self.env['mrp.workcenter.capacity'].create({ 'product_id': cheese_cake.id, 'workcenter_id': workcenter_2.id, - 'time_start': 2, - 'time_stop': 1, + 'time_start': 12, + 'time_stop': 16, }) with Form(bom_cheese_cake) as bom: @@ -628,7 +628,7 @@ class TestBoM(TestMrpCommon): # 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) - #Operation time = 15 min * 60 + time_start + time_stop + capacity_time_start + capacity_time_stop= 928 + # Operation time = 15 min * 60 + capacity_time_start + capacity_time_stop = 928 self.assertEqual(report_values['lines']['operations_time'], 928.0, 'Operation time should be the same for 1 unit or for the batch') # Operation cost is the sum of operation line : (60 * 10)/60 * 10€ + (10 + 15 + 60 * 5)/60 * 20€ + (1 + 2)/60 * 20€ = 209,33€ self.assertEqual(float_compare(report_values['lines']['operations_cost'], 209.33, precision_digits=2), 0) diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index 28bdd0b2d7c..962a26b37b5 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -3239,3 +3239,41 @@ class TestMrpOrder(TestMrpCommon): mo_form.picking_type_id = warehouse02.manu_type_id mo_form.bom_id = bom_wh02 self.assertEqual(mo_form.picking_type_id, warehouse01.manu_type_id, 'Should be adapted because of the default value') + + def test_workcenter_specific_capacities(self): + """ Test that the duraction expected is correctly computed when specific capacities are defined on the workcenter. + """ + # Required for `workorder_ids` to be visible in the view + self.env.user.groups_id += self.env.ref('mrp.group_mrp_routings') + self.workcenter_2.update({ + 'time_start': 10, + 'time_stop': 20, + }) + self.env['mrp.workcenter.capacity'].create({ + 'product_id': self.product_4.id, + 'workcenter_id': self.workcenter_2.id, + 'time_start': 5, + 'time_stop': 10, + }) + + production_form = Form(self.env['mrp.production']) + production_form.product_id = self.product_5 + production = production_form.save() + + with Form(production) as mo_form: + with mo_form.workorder_ids.new() as wo: + wo.name = "OP1" + wo.workcenter_id = self.workcenter_2 + + # Since no duration was given, only duration from the workcenter setup/cleanup time should be added in : 10 + 20 = 30 + self.assertEqual(production.workorder_ids[0].duration_expected, 30.0, "Workcenter setup time (10) + workcenter cleanup time (20)") + + # Change the product so that it uses a specific capacity of that workcenter + with Form(production) as mo_form: + mo_form.product_id = self.product_4 + with mo_form.workorder_ids.new() as wo: + wo.name = "OP1" + wo.workcenter_id = self.workcenter_2 + + # Only duration from the workcenter specific capacity setup/cleanup times since there is one defined for this product. + self.assertEqual(production.workorder_ids[0].duration_expected, 15.0, "Capacity setup time (5) + capacity cleanup time (10)") diff --git a/addons/mrp/views/mrp_workcenter_views.xml b/addons/mrp/views/mrp_workcenter_views.xml index b4d50ee285d..d6ee74f820a 100644 --- a/addons/mrp/views/mrp_workcenter_views.xml +++ b/addons/mrp/views/mrp_workcenter_views.xml @@ -392,8 +392,8 @@ - - + + diff --git a/addons/mrp_account/tests/test_bom_price.py b/addons/mrp_account/tests/test_bom_price.py index e27fc767066..9dac7d1f605 100644 --- a/addons/mrp_account/tests/test_bom_price.py +++ b/addons/mrp_account/tests/test_bom_price.py @@ -124,8 +124,8 @@ class TestBomPrice(TestBomPriceCommon): self.env['mrp.workcenter.capacity'].create({ 'product_id': self.dining_table.id, 'workcenter_id': workcenter_1.id, - 'time_start': 2, - 'time_stop': 1, + 'time_start': 17, + 'time_stop': 16, }) self.bom_1.write({