From 6c4bd3c1866651925e81a8f04987afaeafbb3e03 Mon Sep 17 00:00:00 2001 From: "Thomas Lefebvre (thle)" Date: Tue, 19 Mar 2024 09:44:48 +0100 Subject: [PATCH] [FIX] hr_holidays: apply timezone on request date Steps to reproduce: ------------------- - be in a UTC+08:00 (or more) timezone - go to Time Off dashboard - click on a day (to request a leave) Issue: ------ Default request dates are on 2 days instead of 1. Cause: ------ Default request dates are determined during an onchange. The datetimes (`default_date_from/to`) are set in the context in UTC calculated in relation to the client's timezone. Consequently, these datetimes can be set over several days. In the backend, we will use these datetimes and take only the day (because the `request_date_from/to` fields are of type date). Solution: --------- Put the values back into the client's timezone before they are truncated. opw-3789265 closes odoo/odoo#158042 Signed-off-by: Bertrand Dossogne (bedo) --- addons/hr_holidays/models/hr_leave.py | 13 +++++++++++-- addons/hr_holidays/tests/test_leave_requests.py | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index 4b89a1f2ab5..d2848401664 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -105,13 +105,22 @@ class HolidaysRequest(models.Model): # Instead of overwriting all the javascript methods to use # request_date_{from,to} instead of date_{from,to}, we just convert # date_{from,to} to request_date_{from,to} here. + + # Request dates are determined during an onchange scenario. + # To ensure that the values are correct in the client context (UI), + # the timezone must be applied (because no processing is carried out + # when these dates are received on the frontend). + # Note: + # Without the application of the timezone, days based on UTC datetimes + # will be returned (and will therefore not be correct for the client). + client_tz = timezone(self._context.get('tz') or self.env.user.tz or 'UTC') if values.get('date_from'): if not values.get('request_date_from'): - values['request_date_from'] = values['date_from'] + values['request_date_from'] = pytz.utc.localize(values['date_from']).astimezone(client_tz) del values['date_from'] if values.get('date_to'): if not values.get('request_date_to'): - values['request_date_to'] = values['date_to'] + values['request_date_to'] = pytz.utc.localize(values['date_to']).astimezone(client_tz) del values['date_to'] return values diff --git a/addons/hr_holidays/tests/test_leave_requests.py b/addons/hr_holidays/tests/test_leave_requests.py index 1389926a44e..52ecd50673d 100644 --- a/addons/hr_holidays/tests/test_leave_requests.py +++ b/addons/hr_holidays/tests/test_leave_requests.py @@ -1152,3 +1152,19 @@ class TestLeaveRequests(TestHrHolidaysCommon): }) holiday_status = self.holidays_type_4.with_user(self.user_employee_id) self._check_holidays_status(holiday_status, employee, 20.0, 0.0, 20.0, 16.0) + + def test_default_request_date_timezone(self): + """ + The purpose is to test whether the timezone is + taken into account when requesting a leave. + """ + self.user_employee.tz = 'Hongkong' # UTC +08:00 + context = { + # `date_from/to` in UTC to simulate client values + 'default_date_from': '2024-03-27 23:00:00', + 'default_date_to': '2024-03-28 08:00:00', + } + leave_form = Form(self.env['hr.leave'].with_user(self.user_employee).with_context(context)) + leave_form.holiday_status_id = self.holidays_type_2 + leave = leave_form.save() + self.assertEqual(leave.number_of_days, 1.0)