From de47062e7ccfd8b0859e33c32557acd52ea2fe90 Mon Sep 17 00:00:00 2001 From: Philippe Wauthy Date: Wed, 29 Jun 2022 13:17:07 +0000 Subject: [PATCH] [FIX] hr_holidays: fix timezone issue To reproduce the issue, set the local timezone of the computer and the user to Pacific/Auckland. Create a new time off from the dashboard. The date_from and date_to are one day apart. task-2885980 closes odoo/odoo#99072 Signed-off-by: Kevin Baptiste --- addons/hr_holidays/models/hr_leave.py | 18 ++++++------------ .../time_off_calendar_model.js | 14 ++++++++++++-- .../hr_holidays/tests/test_leave_requests.py | 4 ++-- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index 8dd0ff29f5b..daa283325be 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -116,9 +116,9 @@ class HolidaysRequest(models.Model): def _default_get_request_parameters(self, values): new_values = dict(values) if values.get('date_from'): - new_values['request_date_from'] = values['date_from'].date() + new_values['request_date_from'] = self._adjust_date_based_on_tz(values['date_from'].date(), values['date_from'].time()) if values.get('date_to'): - new_values['request_date_to'] = values['date_to'].date() + new_values['request_date_to'] = self._adjust_date_based_on_tz(values['date_to'].date(), values['date_to'].time()) return new_values active = fields.Boolean(default=True, readonly=True) @@ -752,12 +752,7 @@ class HolidaysRequest(models.Model): """ user_tz = timezone(self.env.user.tz if self.env.user.tz else 'UTC') request_date_to_utc = UTC.localize(datetime.combine(leave_date, hour)).astimezone(user_tz).replace(tzinfo=None) - if request_date_to_utc.date() < leave_date: - return leave_date + timedelta(days=1) - elif request_date_to_utc.date() > leave_date: - return leave_date - timedelta(days=1) - else: - return leave_date + return request_date_to_utc.date() #################################################### # ORM Overrides methods @@ -900,8 +895,8 @@ class HolidaysRequest(models.Model): date_to = values.get('date_to') employee = employees.filtered(lambda emp: emp.id == employee_id) attendance_from, attendance_to = self._get_attendances(employee, date_from.date(), date_to.date()) - hour_from = max(values['date_from'].replace(tzinfo=UTC).astimezone(timezone(self.env.user.tz)).time(), float_to_time(attendance_from.hour_from)) - hour_to = min(values['date_to'].replace(tzinfo=UTC).astimezone(timezone(self.env.user.tz)).time(), float_to_time(attendance_to.hour_to)) + hour_from = float_to_time(attendance_from.hour_from) + hour_to = float_to_time(attendance_to.hour_to) hour_from = hour_from.hour + hour_from.minute / 60 hour_to = hour_to.hour + hour_to.minute / 60 @@ -1587,9 +1582,8 @@ class HolidaysRequest(models.Model): def _get_start_or_end_from_attendance(self, hour, date, employee): hour = float_to_time(float(hour)) - compensated_request_date = self._adjust_date_based_on_tz(date, hour) holiday_tz = timezone(employee.tz or self.env.user.tz) - return holiday_tz.localize(datetime.combine(compensated_request_date, hour)).astimezone(UTC).replace(tzinfo=None) + return holiday_tz.localize(datetime.combine(date, hour)).astimezone(UTC).replace(tzinfo=None) def _get_attendances(self, employee, request_date_from, request_date_to): resource_calendar_id = employee.resource_calendar_id or self.env.company.resource_calendar_id diff --git a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_model.js b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_model.js index f67566fb9db..de9d9c1fa98 100644 --- a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_model.js +++ b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_model.js @@ -11,8 +11,18 @@ export const TimeOffCalendarModel = CalendarModel.extend({ calendarEventToRecord(event) { const data = this._super(...arguments); if (event.allDay) { - data.date_from = data.date_from.utc().startOf('day'); - data.date_to = data.date_to.utc().endOf('day'); + let date_from = data.date_from.subtract(7, 'hours'); + date_from.add(this.getSession().getTZOffset(date_from), 'minutes'); + date_from = date_from.locale('en').format('YYYY-MM-DD HH:mm:ss'); + let date_to = data.date_to.add({ + 'hour': 4, + 'minute': 59, + 'second': 59 + }); + date_to.add(this.getSession().getTZOffset(date_to), 'minutes'); + date_to = date_to.locale('en').format('YYYY-MM-DD HH:mm:ss'); + data.date_from = date_from; + data.date_to = date_to; } return data; }, diff --git a/addons/hr_holidays/tests/test_leave_requests.py b/addons/hr_holidays/tests/test_leave_requests.py index 248d43ed073..1448d0acfe2 100644 --- a/addons/hr_holidays/tests/test_leave_requests.py +++ b/addons/hr_holidays/tests/test_leave_requests.py @@ -424,8 +424,8 @@ class TestLeaveRequests(TestHrHolidaysCommon): # Mimic what is done by the calendar widget when clicking on a day. It # will take the local datetime from 0:00 to 23:59 values = { - 'date_from': local_date_from, - 'date_to': local_date_to, # note that this can be the next day in UTC + 'date_from': tz.localize(local_date_from).astimezone(UTC).replace(tzinfo=None), + 'date_to': tz.localize(local_date_to).astimezone(UTC).replace(tzinfo=None), # note that this can be the next day in UTC } values.update(self.env['hr.leave'].with_user(self.user_employee_id)._default_get_request_parameters(values))