Skip to content

Commit

Permalink
[FIX] hr_holidays: apply timezone on request date
Browse files Browse the repository at this point in the history
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 #158042

Signed-off-by: Bertrand Dossogne (bedo) <bedo@odoo.com>
  • Loading branch information
thle-odoo committed Mar 26, 2024
1 parent f4b56dc commit 6c4bd3c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
13 changes: 11 additions & 2 deletions addons/hr_holidays/models/hr_leave.py
Expand Up @@ -105,13 +105,22 @@ def _default_get_request_dates(self, values):
# 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

Expand Down
16 changes: 16 additions & 0 deletions addons/hr_holidays/tests/test_leave_requests.py
Expand Up @@ -1152,3 +1152,19 @@ def test_undefined_working_hours(self):
})
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)

0 comments on commit 6c4bd3c

Please sign in to comment.