diff --git a/aleksis/core/models.py b/aleksis/core/models.py index e3276ad57f3f80b16c6cab415e7f6e0e55360358..56988152520cbdb656052511113bc8e11644c313 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -1,6 +1,7 @@ # flake8: noqa: DJ01 import base64 from datetime import date, datetime, timedelta +from itertools import chain from typing import TYPE_CHECKING, Any, Iterable, Iterator, List, Optional, Sequence, Union from urllib.parse import urljoin @@ -50,6 +51,7 @@ from oauth2_provider.models import ( ) from phonenumber_field.modelfields import PhoneNumberField from polymorphic.models import PolymorphicModel +from recurrence import Recurrence from recurrence.fields import RecurrenceField from timezone_field import TimeZoneField @@ -1709,18 +1711,21 @@ class Holiday(CalendarEvent): return per_weekday @classmethod - def get_ex_dates(cls, datetime_start, datetime_end, recurrence): + def get_ex_dates( + cls, datetime_start: datetime, datetime_end: datetime, recurrence: Recurrence + ) -> list[datetime]: """Get the dates to exclude for holidays.""" - recurrence.dtstart = recurrence.dtstart.astimezone(timezone.get_current_timezone()) - holiday_dates = [ - h["DTSTART"].dt - for h in Holiday.get_single_events(start=datetime_start, end=datetime_end) - ] - exdates = [ - h.astimezone(timezone.utc) - for h in recurrence.occurrences() - if h.date() in holiday_dates - ] + holiday_dates = list( + chain( + *[ + h["REFERENCE_OBJECT"].get_days() + for h in Holiday.get_single_events( + start=datetime_start, end=datetime_end, with_reference_object=True + ) + ] + ) + ) + exdates = [h for h in recurrence.occurrences() if h.date() in holiday_dates] return exdates def __str__(self) -> str: diff --git a/aleksis/core/tests/models/test_holiday.py b/aleksis/core/tests/models/test_holiday.py new file mode 100644 index 0000000000000000000000000000000000000000..cacc860921c742351ed00d02da39607ad73e1695 --- /dev/null +++ b/aleksis/core/tests/models/test_holiday.py @@ -0,0 +1,32 @@ +import pytest + +pytestmark = pytest.mark.django_db +from aleksis.core.models import Holiday + +from datetime import date, datetime +from recurrence import Recurrence, Rule, WEEKLY + + +def test_holiday_get_days(): + holiday = Holiday.objects.create(date_start=date(2024, 2, 1), date_end=date(2024, 2, 4), holiday_name="Test Holiday") + assert set(holiday.get_days()) == { + date(2024, 2, 1), + date(2024, 2, 2), + date(2024, 2, 3), + date(2024, 2, 4) + } + +def test_holiday_exdates(): + + holiday = Holiday.objects.create(date_start=date(2024, 2, 1), date_end=date(2024, 2, 28), holiday_name="Test Holiday") + + pattern = Recurrence(datetime(2024, 2, 3)) + pattern.rrules.append(Rule(WEEKLY, until=datetime(2024, 6, 1))) + + exdates = holiday.get_ex_dates(datetime(2024, 2,3), datetime(2024, 4, 1), pattern) + assert set(exdates) == { + datetime(2024, 2, 3), + datetime(2024, 2, 10), + datetime(2024, 2, 17), + datetime(2024, 2, 24) + }