diff --git a/addons/resource/models/resource.py b/addons/resource/models/resource.py index e590bdc0643..44d4c7babb9 100644 --- a/addons/resource/models/resource.py +++ b/addons/resource/models/resource.py @@ -3,7 +3,6 @@ from collections import defaultdict import math -import logging from datetime import datetime, time, timedelta from dateutil.relativedelta import relativedelta from dateutil.rrule import rrule, DAILY, WEEKLY @@ -20,8 +19,6 @@ from odoo.tools.float_utils import float_round from odoo.tools import date_utils, float_utils from .resource_mixin import timezone_datetime -_logger = logging.getLogger(__name__) - # Default hour per day value. The one should # only be used when the one from the calendar # is not available. @@ -475,15 +472,16 @@ class ResourceCalendar(models.Model): def interval_dt(interval): return interval[1 if match_end else 0] + if not dt.tzinfo or search_range and not (search_range[0].tzinfo and search_range[1].tzinfo): + raise ValueError('Provided datetimes needs to be timezoned') + dt = dt.astimezone(timezone(self.tz)) + if not search_range: range_start = dt + relativedelta(hour=0, minute=0, second=0) range_end = dt + relativedelta(days=1, hour=0, minute=0, second=0) else: range_start, range_end = search_range - if not (dt.tzinfo and range_start.tzinfo and range_end.tzinfo): - raise ValueError('Provided datetimes needs to be timezoned') - if not range_start <= dt <= range_end: return None work_intervals = sorted( @@ -778,7 +776,8 @@ class ResourceResource(models.Model): for resource in self: calendar_start = resource.calendar_id._get_closest_work_time(start, resource=resource) search_range = None - if calendar_start and start.date() == end.date(): + tz = timezone(resource.tz) + if calendar_start and start.astimezone(tz).date() == end.astimezone(tz).date(): # Make sure to only search end after start search_range = ( start, diff --git a/addons/resource/tests/test_resource.py b/addons/resource/tests/test_resource.py index 123648855be..280447adf57 100644 --- a/addons/resource/tests/test_resource.py +++ b/addons/resource/tests/test_resource.py @@ -438,6 +438,10 @@ class TestCalendar(TestResourceCommon): calendar_dt = self.calendar_john._get_closest_work_time(dt, resource=self.john.resource_id) self.assertEqual(calendar_dt, start, "It should have taken john's specific attendances") + dt = datetime_tz(2020, 4, 4, 1, 0, 0, tzinfo='UTC') # The next day in UTC, but still the 3rd in john's timezone (America/Los_Angeles) + start = datetime_tz(2020, 4, 3, 16, 0, 0, tzinfo=self.john.tz) + calendar_dt = self.calendar_john._get_closest_work_time(dt, resource=self.john.resource_id) + self.assertEqual(calendar_dt, start, "It should have found the attendance on the 3rd April") class TestResMixin(TestResourceCommon): @@ -487,6 +491,21 @@ class TestResMixin(TestResourceCommon): datetime_tz(2020, 4, 3, 13, 0, 0, tzinfo=self.john.tz), )) + def test_adjust_calendar_timezone_after(self): + # Calendar: + # Tuesdays 8-16 + # Fridays 8-13 and 16-23 + tz = 'Europe/Brussels' + self.john.tz = tz + result = self.john._adjust_to_calendar( + datetime(2020, 4, 2, 23, 0, 0), # The previous day in UTC, but the 3rd in Europe/Brussels + datetime(2020, 4, 3, 20, 0, 0), + ) + self.assertEqual(result[self.john], ( + datetime(2020, 4, 3, 6, 0, 0), + datetime(2020, 4, 3, 21, 0, 0), + ), "It should have found a starting time the 3rd") + def test_work_days_data(self): # Looking at Jean's calendar