From b2e5c057094bbbe9dd03fcb35d7aab6a57c2fe3c Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Tue, 3 Sep 2024 13:40:19 +0200 Subject: [PATCH 01/11] [ADD] resource_multi_week_work_time_from_contracts Signed-off-by: Carmen Bianca BAKKER --- .../__init__.py | 5 ++ .../__manifest__.py | 22 ++++++ .../models/__init__.py | 5 ++ .../models/resource_calendar.py | 23 ++++++ .../models/resource_mixin.py | 13 ++++ .../readme/CONTRIBUTORS.rst | 3 + .../readme/DESCRIPTION.rst | 1 + .../tests/__init__.py | 7 ++ .../tests/common.py | 77 +++++++++++++++++++ .../tests/test_calendar.py | 33 ++++++++ .../tests/test_work_time.py | 66 ++++++++++++++++ ...source_multi_week_work_time_from_contracts | 1 + .../setup.py | 6 ++ 13 files changed, 262 insertions(+) create mode 100644 resource_multi_week_work_time_from_contracts/__init__.py create mode 100644 resource_multi_week_work_time_from_contracts/__manifest__.py create mode 100644 resource_multi_week_work_time_from_contracts/models/__init__.py create mode 100644 resource_multi_week_work_time_from_contracts/models/resource_calendar.py create mode 100644 resource_multi_week_work_time_from_contracts/models/resource_mixin.py create mode 100644 resource_multi_week_work_time_from_contracts/readme/CONTRIBUTORS.rst create mode 100644 resource_multi_week_work_time_from_contracts/readme/DESCRIPTION.rst create mode 100644 resource_multi_week_work_time_from_contracts/tests/__init__.py create mode 100644 resource_multi_week_work_time_from_contracts/tests/common.py create mode 100644 resource_multi_week_work_time_from_contracts/tests/test_calendar.py create mode 100644 resource_multi_week_work_time_from_contracts/tests/test_work_time.py create mode 120000 setup/resource_multi_week_work_time_from_contracts/odoo/addons/resource_multi_week_work_time_from_contracts create mode 100644 setup/resource_multi_week_work_time_from_contracts/setup.py diff --git a/resource_multi_week_work_time_from_contracts/__init__.py b/resource_multi_week_work_time_from_contracts/__init__.py new file mode 100644 index 000000000..3eb78877c --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/__init__.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import models diff --git a/resource_multi_week_work_time_from_contracts/__manifest__.py b/resource_multi_week_work_time_from_contracts/__manifest__.py new file mode 100644 index 000000000..8e41e268b --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/__manifest__.py @@ -0,0 +1,22 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +{ + "name": "Multi-week calendars with work time from contracts", + "summary": """ + A compatibility module.""", + "version": "12.0.1.0.0", + "category": "Hidden", + "website": "https://coopiteasy.be", + "author": "Coop IT Easy SC", + "maintainers": ["carmenbianca"], + "license": "AGPL-3", + "application": False, + "depends": [ + "resource_multi_week_calendar", + "resource_work_time_from_contracts", + ], + "auto_install": True, + "data": [], +} diff --git a/resource_multi_week_work_time_from_contracts/models/__init__.py b/resource_multi_week_work_time_from_contracts/models/__init__.py new file mode 100644 index 000000000..7a85334ad --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/models/__init__.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import resource_calendar diff --git a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py new file mode 100644 index 000000000..1dbea53d9 --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from odoo import models + + +class ResourceCalendar(models.Model): + _inherit = "resource.calendar" + + def _get_first_attendance(self, date_from): + if not self.is_multi_week: + return super()._get_first_attendance(date_from) + return super( + ResourceCalendar, self._get_calendar(date_from) + )._get_first_attendance(date_from) + + def _get_last_attendance(self, date_to): + if not self.is_multi_week: + return super()._get_last_attendance(date_to) + return super( + ResourceCalendar, self._get_calendar(date_to) + )._get_last_attendance(date_to) diff --git a/resource_multi_week_work_time_from_contracts/models/resource_mixin.py b/resource_multi_week_work_time_from_contracts/models/resource_mixin.py new file mode 100644 index 000000000..0aa35e419 --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/models/resource_mixin.py @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from odoo import models + + +class ResourceMixing(models.AbstractModel): + _inherit = "resource.mixin" + + def get_calendar_for_date(self, date): + calendar = super().get_calendar_for_date(date) + return calendar._get_calendar(day=date) diff --git a/resource_multi_week_work_time_from_contracts/readme/CONTRIBUTORS.rst b/resource_multi_week_work_time_from_contracts/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..f1ac67577 --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Coop IT Easy SC `_: + + * Carmen Bianca BAKKER diff --git a/resource_multi_week_work_time_from_contracts/readme/DESCRIPTION.rst b/resource_multi_week_work_time_from_contracts/readme/DESCRIPTION.rst new file mode 100644 index 000000000..ef5a6edbb --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +A compatibility module. diff --git a/resource_multi_week_work_time_from_contracts/tests/__init__.py b/resource_multi_week_work_time_from_contracts/tests/__init__.py new file mode 100644 index 000000000..c17b58251 --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/tests/__init__.py @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import common +from . import test_calendar +from . import test_work_time diff --git a/resource_multi_week_work_time_from_contracts/tests/common.py b/resource_multi_week_work_time_from_contracts/tests/common.py new file mode 100644 index 000000000..94949543b --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/tests/common.py @@ -0,0 +1,77 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from odoo.tests.common import SavepointCase + + +class TestCalendarCommon(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.Calendar = cls.env["resource.calendar"] + cls.parent_calendar = cls.Calendar.create( + { + "name": "Parent", + # This date is a Monday. + "multi_week_epoch_date": "2024-07-08", + } + ) + cls.child_1 = cls.Calendar.create( + { + "name": "Child 1", + "parent_calendar_id": cls.parent_calendar.id, + "week_sequence": 1, + "attendance_ids": [ + ( + 0, + False, + { + "name": "Wednesday morning", + "dayofweek": "2", + "hour_from": 8, + "hour_to": 12, + }, + ), + ( + 0, + False, + { + "name": "Thursday morning", + "dayofweek": "3", + "hour_from": 8, + "hour_to": 12, + }, + ), + ], + } + ) + cls.child_2 = cls.Calendar.create( + { + "name": "Child 2", + "parent_calendar_id": cls.parent_calendar.id, + "week_sequence": 2, + "attendance_ids": [ + ( + 0, + False, + { + "name": "Monday morning", + "dayofweek": "0", + "hour_from": 8, + "hour_to": 12, + }, + ), + ( + 0, + False, + { + "name": "Friday morning", + "dayofweek": "4", + "hour_from": 8, + "hour_to": 12, + }, + ), + ], + } + ) diff --git a/resource_multi_week_work_time_from_contracts/tests/test_calendar.py b/resource_multi_week_work_time_from_contracts/tests/test_calendar.py new file mode 100644 index 000000000..0d7029058 --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/tests/test_calendar.py @@ -0,0 +1,33 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +import datetime + +from .common import TestCalendarCommon + + +class TestCalendar(TestCalendarCommon): + def test_first_last_attendance_both_weeks(self): + result = self.parent_calendar.get_first_last_attendance( + datetime.datetime.fromisoformat("2024-07-08T00:00:00+00:00"), + datetime.datetime.fromisoformat("2024-07-21T23:59:59+00:00"), + ) + # First date/attendance is the Wednesday. + self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-10")) + self.assertEqual(result[0][1], self.child_1.attendance_ids[0]) + # Last date/attendance is the Friday. + self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[1][1], self.child_2.attendance_ids[-1]) + + def test_first_last_attendance_middle_to_middle(self): + result = self.parent_calendar.get_first_last_attendance( + datetime.datetime.fromisoformat("2024-07-11T00:00:00+00:00"), + datetime.datetime.fromisoformat("2024-07-16T23:59:59+00:00"), + ) + # First date/attendance is the Thursday. + self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-11")) + self.assertEqual(result[0][1], self.child_1.attendance_ids[1]) + # Last date/attendance is the Monday. + self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-15")) + self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) diff --git a/resource_multi_week_work_time_from_contracts/tests/test_work_time.py b/resource_multi_week_work_time_from_contracts/tests/test_work_time.py new file mode 100644 index 000000000..62cb313f1 --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/tests/test_work_time.py @@ -0,0 +1,66 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +import datetime + +import pytz + +from .common import TestCalendarCommon + + +class TestWorkTime(TestCalendarCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.timezone = pytz.timezone(cls.env.user.tz) + + cls.user1 = cls.env["res.users"].create( + { + "name": "User 1", + "login": "user1", + "password": "user1", + "groups_id": [(6, 0, cls.env.ref("base.group_user").ids)], + } + ) + + cls.employee1 = cls.env["hr.employee"].create( + { + "name": "Employee 1", + "user_id": cls.user1.id, + "address_id": cls.user1.partner_id.id, + } + ) + + def local_datetime(self, year, month, day, *args, **kwargs): + """ + Create a datetime with the local timezone from local time values + """ + return self.timezone.localize( + datetime.datetime(year, month, day, *args, **kwargs) + ) + + def test_single_contract(self): + """A very rudimentary test that checks whether the glue module works. It + does not test any corner cases. + """ + self.env["hr.contract"].create( + { + "name": "Contract 1", + "employee_id": self.employee1.id, + "wage": 0.0, + "resource_calendar_id": self.parent_calendar.id, + "date_start": "2020-10-18", + } + ) + self.assertEqual( + self.employee1.list_work_time_per_day( + self.local_datetime(2024, 7, 8), self.local_datetime(2024, 7, 21) + ), + [ + (datetime.date(2024, 7, 10), 4), + (datetime.date(2024, 7, 11), 4), + (datetime.date(2024, 7, 15), 4), + (datetime.date(2024, 7, 19), 4), + ], + ) diff --git a/setup/resource_multi_week_work_time_from_contracts/odoo/addons/resource_multi_week_work_time_from_contracts b/setup/resource_multi_week_work_time_from_contracts/odoo/addons/resource_multi_week_work_time_from_contracts new file mode 120000 index 000000000..16b845310 --- /dev/null +++ b/setup/resource_multi_week_work_time_from_contracts/odoo/addons/resource_multi_week_work_time_from_contracts @@ -0,0 +1 @@ +../../../../resource_multi_week_work_time_from_contracts \ No newline at end of file diff --git a/setup/resource_multi_week_work_time_from_contracts/setup.py b/setup/resource_multi_week_work_time_from_contracts/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/resource_multi_week_work_time_from_contracts/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 96cd7cbebcfaf68095c736e615e5c462ff5378ed Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Tue, 3 Sep 2024 16:31:03 +0200 Subject: [PATCH 02/11] [FIX] resource_multi_week_work_time_from_contracts: Address corner case Signed-off-by: Carmen Bianca BAKKER --- .../models/resource_calendar.py | 36 +++++++++++++++++-- .../tests/test_calendar.py | 24 +++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py index 1dbea53d9..fabd78774 100644 --- a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py +++ b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py @@ -2,6 +2,8 @@ # # SPDX-License-Identifier: AGPL-3.0-or-later +import datetime + from odoo import models @@ -11,13 +13,43 @@ class ResourceCalendar(models.Model): def _get_first_attendance(self, date_from): if not self.is_multi_week: return super()._get_first_attendance(date_from) - return super( + candidate = super( ResourceCalendar, self._get_calendar(date_from) )._get_first_attendance(date_from) + # Week numbers not equal. This means we are AFTER any of the attendances + # in the target week. So get the first attendance of the succeeding + # week. + # + # TODO: This implementation assumes that the calendar is populated with + # at least one attendance. + if candidate and candidate[0].isocalendar()[1] != date_from.isocalendar()[1]: + days_to_monday = (7 - date_from.weekday()) % 7 + next_monday = (date_from + datetime.timedelta(days=days_to_monday)).replace( + hour=0, minute=0, second=0, microsecond=0 + ) + candidate = super( + ResourceCalendar, self._get_calendar(next_monday) + )._get_first_attendance(next_monday) + return candidate def _get_last_attendance(self, date_to): if not self.is_multi_week: return super()._get_last_attendance(date_to) - return super( + candidate = super( ResourceCalendar, self._get_calendar(date_to) )._get_last_attendance(date_to) + # Week numbers not equal. This means we are BEFORE any of the + # attendances in the target week. So get the last attendance of the + # preceding week. + # + # TODO: This implementation assumes that the calendar is populated with + # at least one attendance. + if candidate and candidate[0].isocalendar()[1] != date_to.isocalendar()[1]: + days_since_sunday = date_to.weekday() + 1 + last_sunday = ( + date_to - datetime.timedelta(days=days_since_sunday) + ).replace(hour=23, minute=59, second=59, microsecond=99999) + candidate = super( + ResourceCalendar, self._get_calendar(last_sunday) + )._get_last_attendance(last_sunday) + return candidate diff --git a/resource_multi_week_work_time_from_contracts/tests/test_calendar.py b/resource_multi_week_work_time_from_contracts/tests/test_calendar.py index 0d7029058..dd3ba0aeb 100644 --- a/resource_multi_week_work_time_from_contracts/tests/test_calendar.py +++ b/resource_multi_week_work_time_from_contracts/tests/test_calendar.py @@ -31,3 +31,27 @@ def test_first_last_attendance_middle_to_middle(self): # Last date/attendance is the Monday. self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-15")) self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) + + def test_first_last_attendance_middle_to_before(self): + result = self.parent_calendar.get_first_last_attendance( + datetime.datetime.fromisoformat("2024-07-16T00:00:00+00:00"), + datetime.datetime.fromisoformat("2024-07-22T23:59:59+00:00"), + ) + # First date/attendance is the Friday. + self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[0][1], self.child_2.attendance_ids[1]) + # Last date/attendance is the Friday of the week preceding the target date. + self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[1][1], self.child_2.attendance_ids[1]) + + def test_first_last_attendance_after_to_middle(self): + result = self.parent_calendar.get_first_last_attendance( + datetime.datetime.fromisoformat("2024-07-12T00:00:00+00:00"), + datetime.datetime.fromisoformat("2024-07-17T23:59:59+00:00"), + ) + # First date/attendance is the Monday of the week succeeding the target date. + self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-15")) + self.assertEqual(result[0][1], self.child_2.attendance_ids[0]) + # Last date/attendance is the Monday. + self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-15")) + self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) From c61923243b704a335839d1ea7f79ee0b49133eb6 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Tue, 3 Sep 2024 17:25:41 +0200 Subject: [PATCH 03/11] [FIX] resource_multi_week_work_time_from_contracts: Skip empty calendars Signed-off-by: Carmen Bianca BAKKER --- .../models/resource_calendar.py | 48 +++++++++++-------- .../tests/common.py | 4 +- .../tests/test_calendar.py | 47 ++++++++++++++++++ 3 files changed, 77 insertions(+), 22 deletions(-) diff --git a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py index fabd78774..5a7065874 100644 --- a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py +++ b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py @@ -19,17 +19,21 @@ def _get_first_attendance(self, date_from): # Week numbers not equal. This means we are AFTER any of the attendances # in the target week. So get the first attendance of the succeeding # week. - # - # TODO: This implementation assumes that the calendar is populated with - # at least one attendance. if candidate and candidate[0].isocalendar()[1] != date_from.isocalendar()[1]: - days_to_monday = (7 - date_from.weekday()) % 7 - next_monday = (date_from + datetime.timedelta(days=days_to_monday)).replace( - hour=0, minute=0, second=0, microsecond=0 - ) - candidate = super( - ResourceCalendar, self._get_calendar(next_monday) - )._get_first_attendance(next_monday) + candidate = False + next_monday = date_from + # Keep searching succeeding weeks until a match is found. Loop as + # many times as there are calendars. + for _ in self.family_calendar_ids: + days_to_monday = (7 - next_monday.weekday()) % 7 or 7 + next_monday = ( + next_monday + datetime.timedelta(days=days_to_monday) + ).replace(hour=0, minute=0, second=0, microsecond=0) + candidate = super( + ResourceCalendar, self._get_calendar(next_monday) + )._get_first_attendance(next_monday) + if candidate: + break return candidate def _get_last_attendance(self, date_to): @@ -41,15 +45,19 @@ def _get_last_attendance(self, date_to): # Week numbers not equal. This means we are BEFORE any of the # attendances in the target week. So get the last attendance of the # preceding week. - # - # TODO: This implementation assumes that the calendar is populated with - # at least one attendance. if candidate and candidate[0].isocalendar()[1] != date_to.isocalendar()[1]: - days_since_sunday = date_to.weekday() + 1 - last_sunday = ( - date_to - datetime.timedelta(days=days_since_sunday) - ).replace(hour=23, minute=59, second=59, microsecond=99999) - candidate = super( - ResourceCalendar, self._get_calendar(last_sunday) - )._get_last_attendance(last_sunday) + candidate = False + last_sunday = date_to + # Keep searching preceding weeks until a match is found. Loop as + # many times as there are calendars. + for _ in self.family_calendar_ids: + days_since_sunday = last_sunday.weekday() + 1 + last_sunday = ( + last_sunday - datetime.timedelta(days=days_since_sunday) + ).replace(hour=23, minute=59, second=59, microsecond=99999) + candidate = super( + ResourceCalendar, self._get_calendar(last_sunday) + )._get_last_attendance(last_sunday) + if candidate: + break return candidate diff --git a/resource_multi_week_work_time_from_contracts/tests/common.py b/resource_multi_week_work_time_from_contracts/tests/common.py index 94949543b..6ece7bd0f 100644 --- a/resource_multi_week_work_time_from_contracts/tests/common.py +++ b/resource_multi_week_work_time_from_contracts/tests/common.py @@ -21,7 +21,7 @@ def setUpClass(cls): { "name": "Child 1", "parent_calendar_id": cls.parent_calendar.id, - "week_sequence": 1, + "week_sequence": 10, "attendance_ids": [ ( 0, @@ -50,7 +50,7 @@ def setUpClass(cls): { "name": "Child 2", "parent_calendar_id": cls.parent_calendar.id, - "week_sequence": 2, + "week_sequence": 20, "attendance_ids": [ ( 0, diff --git a/resource_multi_week_work_time_from_contracts/tests/test_calendar.py b/resource_multi_week_work_time_from_contracts/tests/test_calendar.py index dd3ba0aeb..d1693eb6e 100644 --- a/resource_multi_week_work_time_from_contracts/tests/test_calendar.py +++ b/resource_multi_week_work_time_from_contracts/tests/test_calendar.py @@ -44,6 +44,29 @@ def test_first_last_attendance_middle_to_before(self): self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-19")) self.assertEqual(result[1][1], self.child_2.attendance_ids[1]) + def test_first_last_attendance_middle_to_before_skip_a_week(self): + self.Calendar.create( + { + "name": "Empty child 3", + "parent_calendar_id": self.parent_calendar.id, + "week_sequence": 30, # After week 2. + "attendance_ids": [], + } + ) + result = self.parent_calendar.get_first_last_attendance( + # Multi-week 2 + datetime.datetime.fromisoformat("2024-07-16T00:00:00+00:00"), + # Multi-week 1 + datetime.datetime.fromisoformat("2024-07-30T23:59:59+00:00"), + ) + # First date/attendance is the Friday. + self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[0][1], self.child_2.attendance_ids[1]) + # Last date/attendance is the Friday of the second week preceding the + # target date. + self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[1][1], self.child_2.attendance_ids[1]) + def test_first_last_attendance_after_to_middle(self): result = self.parent_calendar.get_first_last_attendance( datetime.datetime.fromisoformat("2024-07-12T00:00:00+00:00"), @@ -55,3 +78,27 @@ def test_first_last_attendance_after_to_middle(self): # Last date/attendance is the Monday. self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-15")) self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) + + def test_first_last_attendance_after_to_middle_skip_a_week(self): + self.Calendar.create( + { + "name": "Empty child 3", + "parent_calendar_id": self.parent_calendar.id, + # In between week 1 and 2, meaning child 2 is now week 3. + "week_sequence": 15, + "attendance_ids": [], + } + ) + result = self.parent_calendar.get_first_last_attendance( + # Multi-week 1. + datetime.datetime.fromisoformat("2024-07-12T00:00:00+00:00"), + # Multi-week 3. + datetime.datetime.fromisoformat("2024-07-24T23:59:59+00:00"), + ) + # First date/attendance is the Monday of the second week succeeding the + # target date. + self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-22")) + self.assertEqual(result[0][1], self.child_2.attendance_ids[0]) + # Last date/attendance is the Monday. + self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-22")) + self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) From 7463e2b74abed61e9a17370eebd9540b4d0a5044 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Wed, 4 Sep 2024 15:42:02 +0200 Subject: [PATCH 04/11] [FIX] resource_multi_week_work_time_from_contracts: Change names after refactoring I changed some names in a refactor upstream. This commit reflects those changes. Signed-off-by: Carmen Bianca BAKKER --- .../models/resource_calendar.py | 12 ++++++------ .../models/resource_mixin.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py index 5a7065874..736d0cd52 100644 --- a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py +++ b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py @@ -14,7 +14,7 @@ def _get_first_attendance(self, date_from): if not self.is_multi_week: return super()._get_first_attendance(date_from) candidate = super( - ResourceCalendar, self._get_calendar(date_from) + ResourceCalendar, self._get_multi_week_calendar(date_from) )._get_first_attendance(date_from) # Week numbers not equal. This means we are AFTER any of the attendances # in the target week. So get the first attendance of the succeeding @@ -24,13 +24,13 @@ def _get_first_attendance(self, date_from): next_monday = date_from # Keep searching succeeding weeks until a match is found. Loop as # many times as there are calendars. - for _ in self.family_calendar_ids: + for _ in self.multi_week_calendar_ids: days_to_monday = (7 - next_monday.weekday()) % 7 or 7 next_monday = ( next_monday + datetime.timedelta(days=days_to_monday) ).replace(hour=0, minute=0, second=0, microsecond=0) candidate = super( - ResourceCalendar, self._get_calendar(next_monday) + ResourceCalendar, self._get_multi_week_calendar(next_monday) )._get_first_attendance(next_monday) if candidate: break @@ -40,7 +40,7 @@ def _get_last_attendance(self, date_to): if not self.is_multi_week: return super()._get_last_attendance(date_to) candidate = super( - ResourceCalendar, self._get_calendar(date_to) + ResourceCalendar, self._get_multi_week_calendar(date_to) )._get_last_attendance(date_to) # Week numbers not equal. This means we are BEFORE any of the # attendances in the target week. So get the last attendance of the @@ -50,13 +50,13 @@ def _get_last_attendance(self, date_to): last_sunday = date_to # Keep searching preceding weeks until a match is found. Loop as # many times as there are calendars. - for _ in self.family_calendar_ids: + for _ in self.multi_week_calendar_ids: days_since_sunday = last_sunday.weekday() + 1 last_sunday = ( last_sunday - datetime.timedelta(days=days_since_sunday) ).replace(hour=23, minute=59, second=59, microsecond=99999) candidate = super( - ResourceCalendar, self._get_calendar(last_sunday) + ResourceCalendar, self._get_multi_week_calendar(last_sunday) )._get_last_attendance(last_sunday) if candidate: break diff --git a/resource_multi_week_work_time_from_contracts/models/resource_mixin.py b/resource_multi_week_work_time_from_contracts/models/resource_mixin.py index 0aa35e419..b9c22acc6 100644 --- a/resource_multi_week_work_time_from_contracts/models/resource_mixin.py +++ b/resource_multi_week_work_time_from_contracts/models/resource_mixin.py @@ -10,4 +10,4 @@ class ResourceMixing(models.AbstractModel): def get_calendar_for_date(self, date): calendar = super().get_calendar_for_date(date) - return calendar._get_calendar(day=date) + return calendar._get_multi_week_calendar(day=date) From 02707cc1e0d450feb46e8dd7aafdade63fd8a44d Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Thu, 5 Sep 2024 11:53:37 +0200 Subject: [PATCH 05/11] [IMP] resource_multi_week_work_time_from_contracts: Only show parents in contract view Signed-off-by: Carmen Bianca BAKKER --- .../__manifest__.py | 4 +++- .../views/hr_contract_views.xml | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 resource_multi_week_work_time_from_contracts/views/hr_contract_views.xml diff --git a/resource_multi_week_work_time_from_contracts/__manifest__.py b/resource_multi_week_work_time_from_contracts/__manifest__.py index 8e41e268b..5c873ce17 100644 --- a/resource_multi_week_work_time_from_contracts/__manifest__.py +++ b/resource_multi_week_work_time_from_contracts/__manifest__.py @@ -18,5 +18,7 @@ "resource_work_time_from_contracts", ], "auto_install": True, - "data": [], + "data": [ + "views/hr_contract_views.xml", + ], } diff --git a/resource_multi_week_work_time_from_contracts/views/hr_contract_views.xml b/resource_multi_week_work_time_from_contracts/views/hr_contract_views.xml new file mode 100644 index 000000000..d5ba4d120 --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/views/hr_contract_views.xml @@ -0,0 +1,20 @@ + + + + + hr.contract.form + hr.contract + + + + [('parent_calendar_id', '=', False)] + + + + From eea84a9fa5d682c4cd25c3595ca6654769d3e65f Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Thu, 5 Sep 2024 15:25:47 +0200 Subject: [PATCH 06/11] [FIX] resource_multi_week_work_time_from_contracts: Use date type, not datetime I wrongly assumed that get_first_last_attendance used datetime objects. This is not true. It uses date objects. This rectifies that. Signed-off-by: Carmen Bianca BAKKER --- .../models/resource_calendar.py | 8 +--- .../tests/test_calendar.py | 48 +++++++++---------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py index 736d0cd52..a6a3dd3fc 100644 --- a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py +++ b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py @@ -26,9 +26,7 @@ def _get_first_attendance(self, date_from): # many times as there are calendars. for _ in self.multi_week_calendar_ids: days_to_monday = (7 - next_monday.weekday()) % 7 or 7 - next_monday = ( - next_monday + datetime.timedelta(days=days_to_monday) - ).replace(hour=0, minute=0, second=0, microsecond=0) + next_monday = next_monday + datetime.timedelta(days=days_to_monday) candidate = super( ResourceCalendar, self._get_multi_week_calendar(next_monday) )._get_first_attendance(next_monday) @@ -52,9 +50,7 @@ def _get_last_attendance(self, date_to): # many times as there are calendars. for _ in self.multi_week_calendar_ids: days_since_sunday = last_sunday.weekday() + 1 - last_sunday = ( - last_sunday - datetime.timedelta(days=days_since_sunday) - ).replace(hour=23, minute=59, second=59, microsecond=99999) + last_sunday = last_sunday - datetime.timedelta(days=days_since_sunday) candidate = super( ResourceCalendar, self._get_multi_week_calendar(last_sunday) )._get_last_attendance(last_sunday) diff --git a/resource_multi_week_work_time_from_contracts/tests/test_calendar.py b/resource_multi_week_work_time_from_contracts/tests/test_calendar.py index d1693eb6e..e602883a2 100644 --- a/resource_multi_week_work_time_from_contracts/tests/test_calendar.py +++ b/resource_multi_week_work_time_from_contracts/tests/test_calendar.py @@ -10,38 +10,38 @@ class TestCalendar(TestCalendarCommon): def test_first_last_attendance_both_weeks(self): result = self.parent_calendar.get_first_last_attendance( - datetime.datetime.fromisoformat("2024-07-08T00:00:00+00:00"), - datetime.datetime.fromisoformat("2024-07-21T23:59:59+00:00"), + datetime.date.fromisoformat("2024-07-08"), + datetime.date.fromisoformat("2024-07-21"), ) # First date/attendance is the Wednesday. - self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-10")) + self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-10")) self.assertEqual(result[0][1], self.child_1.attendance_ids[0]) # Last date/attendance is the Friday. - self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-19")) self.assertEqual(result[1][1], self.child_2.attendance_ids[-1]) def test_first_last_attendance_middle_to_middle(self): result = self.parent_calendar.get_first_last_attendance( - datetime.datetime.fromisoformat("2024-07-11T00:00:00+00:00"), - datetime.datetime.fromisoformat("2024-07-16T23:59:59+00:00"), + datetime.date.fromisoformat("2024-07-11"), + datetime.date.fromisoformat("2024-07-16"), ) # First date/attendance is the Thursday. - self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-11")) + self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-11")) self.assertEqual(result[0][1], self.child_1.attendance_ids[1]) # Last date/attendance is the Monday. - self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-15")) + self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-15")) self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) def test_first_last_attendance_middle_to_before(self): result = self.parent_calendar.get_first_last_attendance( - datetime.datetime.fromisoformat("2024-07-16T00:00:00+00:00"), - datetime.datetime.fromisoformat("2024-07-22T23:59:59+00:00"), + datetime.date.fromisoformat("2024-07-16"), + datetime.date.fromisoformat("2024-07-22"), ) # First date/attendance is the Friday. - self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-19")) self.assertEqual(result[0][1], self.child_2.attendance_ids[1]) # Last date/attendance is the Friday of the week preceding the target date. - self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-19")) self.assertEqual(result[1][1], self.child_2.attendance_ids[1]) def test_first_last_attendance_middle_to_before_skip_a_week(self): @@ -55,28 +55,28 @@ def test_first_last_attendance_middle_to_before_skip_a_week(self): ) result = self.parent_calendar.get_first_last_attendance( # Multi-week 2 - datetime.datetime.fromisoformat("2024-07-16T00:00:00+00:00"), + datetime.date.fromisoformat("2024-07-16"), # Multi-week 1 - datetime.datetime.fromisoformat("2024-07-30T23:59:59+00:00"), + datetime.date.fromisoformat("2024-07-30"), ) # First date/attendance is the Friday. - self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-19")) self.assertEqual(result[0][1], self.child_2.attendance_ids[1]) # Last date/attendance is the Friday of the second week preceding the # target date. - self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-19")) self.assertEqual(result[1][1], self.child_2.attendance_ids[1]) def test_first_last_attendance_after_to_middle(self): result = self.parent_calendar.get_first_last_attendance( - datetime.datetime.fromisoformat("2024-07-12T00:00:00+00:00"), - datetime.datetime.fromisoformat("2024-07-17T23:59:59+00:00"), + datetime.date.fromisoformat("2024-07-12"), + datetime.date.fromisoformat("2024-07-17"), ) # First date/attendance is the Monday of the week succeeding the target date. - self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-15")) + self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-15")) self.assertEqual(result[0][1], self.child_2.attendance_ids[0]) # Last date/attendance is the Monday. - self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-15")) + self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-15")) self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) def test_first_last_attendance_after_to_middle_skip_a_week(self): @@ -91,14 +91,14 @@ def test_first_last_attendance_after_to_middle_skip_a_week(self): ) result = self.parent_calendar.get_first_last_attendance( # Multi-week 1. - datetime.datetime.fromisoformat("2024-07-12T00:00:00+00:00"), + datetime.date.fromisoformat("2024-07-12"), # Multi-week 3. - datetime.datetime.fromisoformat("2024-07-24T23:59:59+00:00"), + datetime.date.fromisoformat("2024-07-24"), ) # First date/attendance is the Monday of the second week succeeding the # target date. - self.assertEqual(result[0][0].date(), datetime.date.fromisoformat("2024-07-22")) + self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-22")) self.assertEqual(result[0][1], self.child_2.attendance_ids[0]) # Last date/attendance is the Monday. - self.assertEqual(result[1][0].date(), datetime.date.fromisoformat("2024-07-22")) + self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-22")) self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) From dd69804c25d01fa11a5d58eb0f65a3eddabfeea7 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Thu, 5 Sep 2024 15:32:24 +0200 Subject: [PATCH 07/11] [IMP] resource_multi_week_work_time_from_contracts: Make easier to read code Signed-off-by: Carmen Bianca BAKKER --- .../models/resource_calendar.py | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py index a6a3dd3fc..8633a2502 100644 --- a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py +++ b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py @@ -21,17 +21,18 @@ def _get_first_attendance(self, date_from): # week. if candidate and candidate[0].isocalendar()[1] != date_from.isocalendar()[1]: candidate = False - next_monday = date_from - # Keep searching succeeding weeks until a match is found. Loop as - # many times as there are calendars. + days_to_monday = (7 - date_from.weekday()) % 7 or 7 + new_date_from = date_from + # Keep searching the Mondays of succeeding weeks until a match is + # found. Loop as many times as there are calendars. for _ in self.multi_week_calendar_ids: - days_to_monday = (7 - next_monday.weekday()) % 7 or 7 - next_monday = next_monday + datetime.timedelta(days=days_to_monday) + new_date_from = new_date_from + datetime.timedelta(days=days_to_monday) candidate = super( - ResourceCalendar, self._get_multi_week_calendar(next_monday) - )._get_first_attendance(next_monday) + ResourceCalendar, self._get_multi_week_calendar(new_date_from) + )._get_first_attendance(new_date_from) if candidate: break + days_to_monday = 7 return candidate def _get_last_attendance(self, date_to): @@ -45,15 +46,16 @@ def _get_last_attendance(self, date_to): # preceding week. if candidate and candidate[0].isocalendar()[1] != date_to.isocalendar()[1]: candidate = False - last_sunday = date_to - # Keep searching preceding weeks until a match is found. Loop as - # many times as there are calendars. + days_since_sunday = date_to.weekday() + 1 + new_date_to = date_to + # Keep searching the Sundays of preceding weeks until a match is + # found. Loop as many times as there are calendars. for _ in self.multi_week_calendar_ids: - days_since_sunday = last_sunday.weekday() + 1 - last_sunday = last_sunday - datetime.timedelta(days=days_since_sunday) + new_date_to = new_date_to - datetime.timedelta(days=days_since_sunday) candidate = super( - ResourceCalendar, self._get_multi_week_calendar(last_sunday) - )._get_last_attendance(last_sunday) + ResourceCalendar, self._get_multi_week_calendar(new_date_to) + )._get_last_attendance(new_date_to) if candidate: break + days_since_sunday = 7 return candidate From dbcd0348f213deb4de9c386aa625c3ce9f9f93f1 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Thu, 5 Sep 2024 15:34:26 +0200 Subject: [PATCH 08/11] [FIX] resource_multi_week_work_time_from_contracts: Return expected None value Upstream returns None, not False. Signed-off-by: Carmen Bianca BAKKER --- .../models/resource_calendar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py index 8633a2502..b72f72a0b 100644 --- a/resource_multi_week_work_time_from_contracts/models/resource_calendar.py +++ b/resource_multi_week_work_time_from_contracts/models/resource_calendar.py @@ -20,7 +20,7 @@ def _get_first_attendance(self, date_from): # in the target week. So get the first attendance of the succeeding # week. if candidate and candidate[0].isocalendar()[1] != date_from.isocalendar()[1]: - candidate = False + candidate = None days_to_monday = (7 - date_from.weekday()) % 7 or 7 new_date_from = date_from # Keep searching the Mondays of succeeding weeks until a match is @@ -45,7 +45,7 @@ def _get_last_attendance(self, date_to): # attendances in the target week. So get the last attendance of the # preceding week. if candidate and candidate[0].isocalendar()[1] != date_to.isocalendar()[1]: - candidate = False + candidate = None days_since_sunday = date_to.weekday() + 1 new_date_to = date_to # Keep searching the Sundays of preceding weeks until a match is From f34a53e693b64e87bdd4e24200b1f9cc043e924e Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Mon, 9 Sep 2024 14:51:29 +0200 Subject: [PATCH 09/11] [FIX] resource_multi_week_work_time_from_contracts: Import resource_mixin.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hugues de keyzer --- resource_multi_week_work_time_from_contracts/models/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/resource_multi_week_work_time_from_contracts/models/__init__.py b/resource_multi_week_work_time_from_contracts/models/__init__.py index 7a85334ad..54f6e2dad 100644 --- a/resource_multi_week_work_time_from_contracts/models/__init__.py +++ b/resource_multi_week_work_time_from_contracts/models/__init__.py @@ -3,3 +3,4 @@ # SPDX-License-Identifier: AGPL-3.0-or-later from . import resource_calendar +from . import resource_mixin From 12ea19d1078e3121e5fce9b19192dbc4d212544a Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Mon, 9 Sep 2024 15:52:42 +0200 Subject: [PATCH 10/11] [IMP] resource_multi_week_work_time_from_contracts: Move domain from view to model Signed-off-by: Carmen Bianca BAKKER --- .../__manifest__.py | 3 --- .../models/hr_contract.py | 15 ++++++++++++++ .../views/hr_contract_views.xml | 20 ------------------- 3 files changed, 15 insertions(+), 23 deletions(-) create mode 100644 resource_multi_week_work_time_from_contracts/models/hr_contract.py delete mode 100644 resource_multi_week_work_time_from_contracts/views/hr_contract_views.xml diff --git a/resource_multi_week_work_time_from_contracts/__manifest__.py b/resource_multi_week_work_time_from_contracts/__manifest__.py index 5c873ce17..0597db756 100644 --- a/resource_multi_week_work_time_from_contracts/__manifest__.py +++ b/resource_multi_week_work_time_from_contracts/__manifest__.py @@ -18,7 +18,4 @@ "resource_work_time_from_contracts", ], "auto_install": True, - "data": [ - "views/hr_contract_views.xml", - ], } diff --git a/resource_multi_week_work_time_from_contracts/models/hr_contract.py b/resource_multi_week_work_time_from_contracts/models/hr_contract.py new file mode 100644 index 000000000..c7252be83 --- /dev/null +++ b/resource_multi_week_work_time_from_contracts/models/hr_contract.py @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from odoo import fields, models + + +class HrContract(models.Model): + _inherit = "hr.contract" + + # Add a domain. + resource_calendar_id = fields.Many2one( + "resource.calendar", + domain="[('parent_calendar_id', '=', False)]", + ) diff --git a/resource_multi_week_work_time_from_contracts/views/hr_contract_views.xml b/resource_multi_week_work_time_from_contracts/views/hr_contract_views.xml deleted file mode 100644 index d5ba4d120..000000000 --- a/resource_multi_week_work_time_from_contracts/views/hr_contract_views.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - hr.contract.form - hr.contract - - - - [('parent_calendar_id', '=', False)] - - - - From e8a370092192e0b8417a357dd219ec2ac5679f95 Mon Sep 17 00:00:00 2001 From: hugues de keyzer Date: Wed, 9 Oct 2024 15:45:03 +0200 Subject: [PATCH 11/11] [FIX] fix tests --- company_today/tests/test_today.py | 2 +- oca_dependencies.txt | 1 + .../tests/test_calendar.py | 48 +++++++++---------- test-requirements.txt | 2 + 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/company_today/tests/test_today.py b/company_today/tests/test_today.py index a97654934..33b97d507 100644 --- a/company_today/tests/test_today.py +++ b/company_today/tests/test_today.py @@ -12,7 +12,7 @@ class TestToday(SavepointCase): @classmethod def setUpClass(cls): super().setUpClass() - cls.company = cls.ref("base.main_company") + cls.company = cls.env.ref("base.main_company") def test_today(self): self.company.cron_update_today() diff --git a/oca_dependencies.txt b/oca_dependencies.txt index 4575bb7b2..735a74f52 100644 --- a/oca_dependencies.txt +++ b/oca_dependencies.txt @@ -1,6 +1,7 @@ # List the OCA project dependencies, one per line # Add a repository url and branch if you need a forked version +hr https://github.com/coopiteasy/hr partner-contact timesheet obeesdoo https://github.com/beescoop/Obeesdoo diff --git a/resource_multi_week_work_time_from_contracts/tests/test_calendar.py b/resource_multi_week_work_time_from_contracts/tests/test_calendar.py index e602883a2..7e2ef55f1 100644 --- a/resource_multi_week_work_time_from_contracts/tests/test_calendar.py +++ b/resource_multi_week_work_time_from_contracts/tests/test_calendar.py @@ -10,38 +10,38 @@ class TestCalendar(TestCalendarCommon): def test_first_last_attendance_both_weeks(self): result = self.parent_calendar.get_first_last_attendance( - datetime.date.fromisoformat("2024-07-08"), - datetime.date.fromisoformat("2024-07-21"), + datetime.date(2024, 7, 8), + datetime.date(2024, 7, 21), ) # First date/attendance is the Wednesday. - self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-10")) + self.assertEqual(result[0][0], datetime.date(2024, 7, 10)) self.assertEqual(result[0][1], self.child_1.attendance_ids[0]) # Last date/attendance is the Friday. - self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[1][0], datetime.date(2024, 7, 19)) self.assertEqual(result[1][1], self.child_2.attendance_ids[-1]) def test_first_last_attendance_middle_to_middle(self): result = self.parent_calendar.get_first_last_attendance( - datetime.date.fromisoformat("2024-07-11"), - datetime.date.fromisoformat("2024-07-16"), + datetime.date(2024, 7, 11), + datetime.date(2024, 7, 16), ) # First date/attendance is the Thursday. - self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-11")) + self.assertEqual(result[0][0], datetime.date(2024, 7, 11)) self.assertEqual(result[0][1], self.child_1.attendance_ids[1]) # Last date/attendance is the Monday. - self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-15")) + self.assertEqual(result[1][0], datetime.date(2024, 7, 15)) self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) def test_first_last_attendance_middle_to_before(self): result = self.parent_calendar.get_first_last_attendance( - datetime.date.fromisoformat("2024-07-16"), - datetime.date.fromisoformat("2024-07-22"), + datetime.date(2024, 7, 16), + datetime.date(2024, 7, 22), ) # First date/attendance is the Friday. - self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[0][0], datetime.date(2024, 7, 19)) self.assertEqual(result[0][1], self.child_2.attendance_ids[1]) # Last date/attendance is the Friday of the week preceding the target date. - self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[1][0], datetime.date(2024, 7, 19)) self.assertEqual(result[1][1], self.child_2.attendance_ids[1]) def test_first_last_attendance_middle_to_before_skip_a_week(self): @@ -55,28 +55,28 @@ def test_first_last_attendance_middle_to_before_skip_a_week(self): ) result = self.parent_calendar.get_first_last_attendance( # Multi-week 2 - datetime.date.fromisoformat("2024-07-16"), + datetime.date(2024, 7, 16), # Multi-week 1 - datetime.date.fromisoformat("2024-07-30"), + datetime.date(2024, 7, 30), ) # First date/attendance is the Friday. - self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[0][0], datetime.date(2024, 7, 19)) self.assertEqual(result[0][1], self.child_2.attendance_ids[1]) # Last date/attendance is the Friday of the second week preceding the # target date. - self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-19")) + self.assertEqual(result[1][0], datetime.date(2024, 7, 19)) self.assertEqual(result[1][1], self.child_2.attendance_ids[1]) def test_first_last_attendance_after_to_middle(self): result = self.parent_calendar.get_first_last_attendance( - datetime.date.fromisoformat("2024-07-12"), - datetime.date.fromisoformat("2024-07-17"), + datetime.date(2024, 7, 12), + datetime.date(2024, 7, 17), ) # First date/attendance is the Monday of the week succeeding the target date. - self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-15")) + self.assertEqual(result[0][0], datetime.date(2024, 7, 15)) self.assertEqual(result[0][1], self.child_2.attendance_ids[0]) # Last date/attendance is the Monday. - self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-15")) + self.assertEqual(result[1][0], datetime.date(2024, 7, 15)) self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) def test_first_last_attendance_after_to_middle_skip_a_week(self): @@ -91,14 +91,14 @@ def test_first_last_attendance_after_to_middle_skip_a_week(self): ) result = self.parent_calendar.get_first_last_attendance( # Multi-week 1. - datetime.date.fromisoformat("2024-07-12"), + datetime.date(2024, 7, 12), # Multi-week 3. - datetime.date.fromisoformat("2024-07-24"), + datetime.date(2024, 7, 24), ) # First date/attendance is the Monday of the second week succeeding the # target date. - self.assertEqual(result[0][0], datetime.date.fromisoformat("2024-07-22")) + self.assertEqual(result[0][0], datetime.date(2024, 7, 22)) self.assertEqual(result[0][1], self.child_2.attendance_ids[0]) # Last date/attendance is the Monday. - self.assertEqual(result[1][0], datetime.date.fromisoformat("2024-07-22")) + self.assertEqual(result[1][0], datetime.date(2024, 7, 22)) self.assertEqual(result[1][1], self.child_2.attendance_ids[0]) diff --git a/test-requirements.txt b/test-requirements.txt index 85c977787..33ebd56d8 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,3 +1,4 @@ +git+https://github.com/coopiteasy/hr@12.0-mig-resource_multi_week_calendar#subdirectory=setup/resource_multi_week_calendar git+https://github.com/beescoop/obeesdoo@12.0#subdirectory=setup/beesdoo_base git+https://github.com/beescoop/obeesdoo@12.0#subdirectory=setup/beesdoo_product git+https://github.com/beescoop/obeesdoo@12.0#subdirectory=setup/beesdoo_product_label @@ -16,3 +17,4 @@ git+https://github.com/beescoop/obeesdoo@12.0#subdirectory=setup/product_main_su git+https://github.com/beescoop/obeesdoo@12.0#subdirectory=setup/sale_adapt_price_wizard git+https://github.com/beescoop/obeesdoo@12.0#subdirectory=setup/sale_suggested_price git+https://github.com/beescoop/obeesdoo@12.0#subdirectory=setup/purchase_order_responsible +freezegun