From 2a37e3527c6da1032b2acf574feeb197a97744e0 Mon Sep 17 00:00:00 2001 From: roen-odoo Date: Tue, 19 Mar 2024 17:06:55 +0100 Subject: [PATCH] [FIX] mrp: make sure changing workcenter adapt finish date of workorder Current behavior: If you change the expected duration of a workorder, then move the workorder to another workcenter, the expected duration is recomputed to but the finish date is not adapted. This leads to an inconsistency in the gannt view. Visually it will look like the duration expected has not changed because the date are still the same. Fix: To fix this we make sure that the finish date is recomputed when the expected duration is modified. This way both date and expected duration are consistent. Steps to reproduce: - Create a product with a BOM - The BOM should have at least 1 operations with a duration of 1 hour linked to a workcenter - Create a manufacturing order for this product, confirm and plan it - Go to the planning by workcenter - Change the duration of the workorder by sliding its finishing date - At this point if you click on it the duration should have changed - Move the workorder to another workcenter - The duration has been recomputed, but the finish date is not adapted (You can click on the workorder to see the duration has changed) opw-3717361 closes odoo/odoo#161297 X-original-commit: 2c70160daa31736b0ab8d22f6c99c76bfa9c7301 Signed-off-by: William Henrotin (whe) Signed-off-by: Robin Engels (roen) --- addons/mrp/models/mrp_workorder.py | 3 ++ addons/mrp/tests/test_order.py | 55 ++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py index 6f3fe4b77c8..0f089bff3bf 100644 --- a/addons/mrp/models/mrp_workorder.py +++ b/addons/mrp/models/mrp_workorder.py @@ -436,6 +436,9 @@ class MrpWorkorder(models.Model): if workorder.state in ('progress', 'done', 'cancel'): raise UserError(_('You cannot change the workcenter of a work order that is in progress or done.')) workorder.leave_id.resource_id = self.env['mrp.workcenter'].browse(values['workcenter_id']).resource_id + workorder.duration_expected = workorder._get_duration_expected() + if workorder.date_start: + workorder.date_finished = workorder._calculate_date_finished() if 'date_start' in values or 'date_finished' in values: for workorder in self: date_start = fields.Datetime.to_datetime(values.get('date_start', workorder.date_start)) diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index 8e5778d3d10..9f1712d816d 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -3945,3 +3945,58 @@ class TestMrpOrder(TestMrpCommon): self.assertEqual(wos[0].date_finished, dt + timedelta(hours=1, minutes=1)) self.assertEqual(wos[1].date_finished, dt + timedelta(hours=1, minutes=2)) + + def test_update_workcenter_adapt_finish_date(self): + """ + Test that changing the workcenter of a workorder will adapt the end date to make + sure the duration expected is respected + """ + self.workcenter_4 = self.env['mrp.workcenter'].create({ + 'name': 'Test workcenter', + }) + + self.workcenter_5 = self.env['mrp.workcenter'].create({ + 'name': 'Test workcenter', + }) + + operation = self.env['mrp.routing.workcenter'].create({ + 'name': 'Test order', + 'workcenter_id': self.workcenter_4.id, + 'bom_id': self.bom_1.id, + 'time_cycle_manual': 30, + }) + + mo = self.env['mrp.production'].create({ + 'product_id': self.product.id, + 'product_uom_id': self.bom_1.product_uom_id.id, + }) + + dt = datetime(2024, 1, 17, 11) + wo = self.env['mrp.workorder'].create([ + { + 'name': 'Test order', + 'workcenter_id': self.workcenter_4.id, + 'product_uom_id': self.bom_1.product_uom_id.id, + 'production_id': mo.id, + 'duration_expected': 30.0, + 'date_start': dt, + 'operation_id': operation.id, + } + ]) + self.assertEqual(wo.date_start, dt) + self.assertEqual(wo.date_finished, dt + timedelta(hours=1, minutes=30)) + + # We change the date finished and make sure the duration expected is adapted + wo.write({ + 'date_finished': dt + timedelta(hours=2), + }) + self.assertEqual(wo.duration_expected, 60.0) + + # We change the workcenter and make sure the duration expected and the date finish + # is adapted accordingly + wo.write({ + 'workcenter_id': self.workcenter_5.id, + }) + self.assertEqual(wo.duration_expected, 30.0) + self.assertEqual(wo.date_start, dt) + self.assertEqual(wo.date_finished, dt + timedelta(hours=1, minutes=30))