summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrien Widart <awt@odoo.com>2021-05-17 08:20:45 +0000
committerAdrien Widart <awt@odoo.com>2021-05-26 11:24:49 +0000
commit012de9c86fbd1b85d180e279740d5053b9ba4b0f (patch)
tree2fa2eed61fd52ba52b2cf4c0d0f9652ecd62f457
parente18e256137e4593aee0cb6f1d0fcc4168dff79c1 (diff)
[FIX] mrp: use work center's TZ to plan operations
When planning a Manufacturing Order, if an operation takes place in work center with a different time zone, the computed date may be incorrect (the start date may be outside the working hours) To reproduce the error: (Use demo data. Current timezone: Europe/Brussels) 1. In Settings, enable "Work Orders" 2. Open an existing Work Center 3. Click on "Standard 40 hours/week" 4. Set Timezone to "Asia/Bangkok" - Note that all slots are between 8:00-12:00 and 13:00-17:00 5. Create two storable products P_compo and P_finished 6. Create a Bill of Materials BM: - Product: P_finished - BoM Type: Manufacture this product - Components: 1 x P_compo - Operations: 3 x Operation with existing work centers 7. Create a Manufacturing Order: - Bill of Material: BM - Quantity: 100 8. Save, Confirm, Plan Error: (it depends on the time the test is done) The 'Scheduled Start Date' of the second operation is incorrect. Adding the time zone difference gives a time that is outside the work center's timetable (i.e., outside 8:00-12:00 and 13:00-17:00). The computations do not consider the time zone of the work center. OPW-2393330 closes odoo/odoo#70841 Related: odoo/enterprise#18524 Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
-rw-r--r--addons/mrp/models/mrp_workcenter.py5
-rw-r--r--addons/mrp/tests/test_order.py42
2 files changed, 45 insertions, 2 deletions
diff --git a/addons/mrp/models/mrp_workcenter.py b/addons/mrp/models/mrp_workcenter.py
index 1062b1dac03..190581ee543 100644
--- a/addons/mrp/models/mrp_workcenter.py
+++ b/addons/mrp/models/mrp_workcenter.py
@@ -5,6 +5,7 @@ from dateutil import relativedelta
from datetime import timedelta
from functools import partial
import datetime
+from pytz import timezone
from odoo import api, exceptions, fields, models, _
from odoo.exceptions import ValidationError
@@ -223,8 +224,8 @@ class MrpWorkcenter(models.Model):
self.ensure_one()
start_datetime, revert = make_aware(start_datetime)
- get_available_intervals = partial(self.resource_calendar_id._work_intervals, domain=[('time_type', 'in', ['other', 'leave'])], resource=self.resource_id)
- get_workorder_intervals = partial(self.resource_calendar_id._leave_intervals, domain=[('time_type', '=', 'other')], resource=self.resource_id)
+ get_available_intervals = partial(self.resource_calendar_id._work_intervals, domain=[('time_type', 'in', ['other', 'leave'])], resource=self.resource_id, tz=timezone(self.resource_calendar_id.tz))
+ get_workorder_intervals = partial(self.resource_calendar_id._leave_intervals, domain=[('time_type', '=', 'other')], resource=self.resource_id, tz=timezone(self.resource_calendar_id.tz))
remaining = duration
start_interval = start_datetime
diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py
index bdfeea4d545..6028211b07f 100644
--- a/addons/mrp/tests/test_order.py
+++ b/addons/mrp/tests/test_order.py
@@ -1708,3 +1708,45 @@ class TestMrpOrder(TestMrpCommon):
wizard.process()
self.assertEqual(mo_1.state, 'done')
self.assertEqual(mo_2.state, 'done')
+
+ def test_workcenter_timezone(self):
+ # Workcenter is based in Bangkok
+ # Possible working hours are Monday to Friday, from 8:00 to 12:00 and from 13:00 to 17:00 (UTC+7)
+ workcenter = self.workcenter_1
+ workcenter.resource_calendar_id.tz = 'Asia/Bangkok'
+
+ bom = self.env['mrp.bom'].create({
+ 'product_tmpl_id': self.product_1.product_tmpl_id.id,
+ 'bom_line_ids': [(0, 0, {
+ 'product_id': self.product_2.id,
+ })],
+ 'operation_ids': [(0, 0, {
+ 'name': 'SuperOperation01',
+ 'workcenter_id': workcenter.id,
+ }), (0, 0, {
+ 'name': 'SuperOperation01',
+ 'workcenter_id': workcenter.id,
+ })],
+ })
+
+ # Next Monday at 6:00 am UTC
+ date_planned = (Dt.now() + timedelta(days=7 - Dt.now().weekday())).replace(hour=6, minute=0, second=0)
+ mo_form = Form(self.env['mrp.production'])
+ mo_form.bom_id = bom
+ mo_form.date_planned_start = date_planned
+ mo = mo_form.save()
+
+ mo.workorder_ids[0].duration_expected = 240
+ mo.workorder_ids[1].duration_expected = 60
+
+ mo.action_confirm()
+ mo.button_plan()
+
+ # Asia/Bangkok is UTC+7 and the start date is on Monday at 06:00 UTC (i.e., 13:00 UTC+7).
+ # So, in Bangkok, the first workorder uses the entire Monday afternoon slot 13:00 - 17:00 UTC+7 (i.e., 06:00 - 10:00 UTC)
+ # The second job uses the beginning of the Tuesday morning slot: 08:00 - 09:00 UTC+7 (i.e., 01:00 - 02:00 UTC)
+ self.assertEqual(mo.workorder_ids[0].date_planned_start, date_planned)
+ self.assertEqual(mo.workorder_ids[0].date_planned_finished, date_planned + timedelta(hours=4))
+ tuesday = date_planned + timedelta(days=1)
+ self.assertEqual(mo.workorder_ids[1].date_planned_start, tuesday.replace(hour=1))
+ self.assertEqual(mo.workorder_ids[1].date_planned_finished, tuesday.replace(hour=2))