Move calculation of event start and end dates to separate method

This commit is contained in:
Julia 2022-08-18 13:55:07 +03:00
parent 736bc3b348
commit bcf6ccb865
2 changed files with 31 additions and 45 deletions

View file

@ -2,22 +2,12 @@ from collections import defaultdict
from datetime import datetime
from typing import List
from django.apps import apps
from django.utils import timezone
from icalendar import Calendar, Event
from recurring_ical_events import UnfoldableCalendar, compare_greater, is_event, time_span_contains_event
from apps.schedules.constants import (
ICAL_DATETIME_END,
ICAL_DATETIME_STAMP,
ICAL_DATETIME_START,
ICAL_RRULE,
ICAL_UID,
ICAL_UNTIL,
RE_EVENT_UID_V1,
RE_EVENT_UID_V2,
)
from apps.schedules.ical_events.proxy.ical_proxy import IcalService
from apps.schedules.ical_utils import get_start_and_end_with_respect_to_event_type
EXTRA_LOOKUP_DAYS = 16
@ -105,17 +95,7 @@ class AmixrRecurringIcalEventsAdapter(IcalService):
)
def filter_extra_days(event):
CustomOnCallShift = apps.get_model("schedules", "CustomOnCallShift")
match = RE_EVENT_UID_V2.match(event[ICAL_UID]) or RE_EVENT_UID_V1.match(event[ICAL_UID])
# use different calculation rule for events from custom shifts generated at web
if match and int(match.groups()[-1]) == CustomOnCallShift.SOURCE_WEB:
event_start = max(event[ICAL_DATETIME_START].dt, event[ICAL_DATETIME_STAMP].dt)
event_end = event[ICAL_DATETIME_END].dt
if event.get(ICAL_RRULE, {}).get(ICAL_UNTIL):
event_end = min(event[ICAL_RRULE][ICAL_UNTIL][0], event[ICAL_DATETIME_END].dt)
else:
event_start = event[ICAL_DATETIME_START].dt
event_end = event[ICAL_DATETIME_END].dt
event_start, event_end = get_start_and_end_with_respect_to_event_type(event)
return time_span_contains_event(start_date, end_date, event_start, event_end)
return list(filter(filter_extra_days, events))

View file

@ -165,7 +165,6 @@ def list_of_oncall_shifts_from_ical(
def get_shifts_dict(calendar, calendar_type, schedule, datetime_start, datetime_end, date, with_empty_shifts=False):
OnCallScheduleWeb = apps.get_model("schedules", "OnCallScheduleWeb")
events = ical_events.get_events_from_ical_between(calendar, datetime_start, datetime_end)
result_datetime = []
result_date = []
@ -177,14 +176,7 @@ def get_shifts_dict(calendar, calendar_type, schedule, datetime_start, datetime_
# Define on-call shift out of ical event that has the actual user
if len(users) > 0 or with_empty_shifts:
if type(event[ICAL_DATETIME_START].dt) == datetime.date:
if isinstance(schedule, OnCallScheduleWeb):
start = max(event[ICAL_DATETIME_START].dt, event[ICAL_DATETIME_STAMP].dt.date())
end = event[ICAL_DATETIME_END].dt
if event.get(ICAL_RRULE, {}).get(ICAL_UNTIL):
end = min(event[ICAL_DATETIME_END].dt, event[ICAL_RRULE][ICAL_UNTIL][0].date())
else:
start = event[ICAL_DATETIME_START].dt
end = event[ICAL_DATETIME_END].dt
start, end = get_start_and_end_with_respect_to_event_type(event, full_day_event=True)
if start <= date < end:
result_date.append(
{
@ -199,22 +191,11 @@ def get_shifts_dict(calendar, calendar_type, schedule, datetime_start, datetime_
}
)
else:
if isinstance(schedule, OnCallScheduleWeb):
start = max(
event[ICAL_DATETIME_START].dt.astimezone(pytz.UTC),
event[ICAL_DATETIME_STAMP].dt.astimezone(pytz.UTC),
)
end = event[ICAL_DATETIME_END].dt.astimezone(pytz.UTC)
if event.get(ICAL_RRULE, {}).get(ICAL_UNTIL):
end = min(event[ICAL_DATETIME_END].dt.astimezone(pytz.UTC), event[ICAL_RRULE][ICAL_UNTIL][0])
else:
start = event[ICAL_DATETIME_START].dt.astimezone(pytz.UTC)
end = event[ICAL_DATETIME_END].dt.astimezone(pytz.UTC)
start, end = get_start_and_end_with_respect_to_event_type(event)
result_datetime.append(
{
"start": start,
"end": end,
"start": start.astimezone(pytz.UTC),
"end": end.astimezone(pytz.UTC),
"users": users,
"missing_users": missing_users,
"priority": priority,
@ -762,3 +743,28 @@ def convert_windows_timezone_to_iana(tz_name):
logger.debug("Converting the timezone from Windows to IANA. '{}' -> '{}'".format(tz_name, result))
return result
def get_start_and_end_with_respect_to_event_type(event, full_day_event=False):
"""
Calculate start and end datetime (or dates for full_day_event)
"""
CustomOnCallShift = apps.get_model("schedules", "CustomOnCallShift")
start = event[ICAL_DATETIME_START].dt
end = event[ICAL_DATETIME_END].dt
match = RE_EVENT_UID_V2.match(event[ICAL_UID]) or RE_EVENT_UID_V1.match(event[ICAL_UID])
# use different calculation rule for events from custom shifts generated at web
if match and int(match.groups()[-1]) == CustomOnCallShift.SOURCE_WEB:
rotation_start = event[ICAL_DATETIME_STAMP]
until = event.get(ICAL_RRULE, {}).get(ICAL_UNTIL)
if full_day_event:
rotation_start = rotation_start.date()
until = until.date() if until else None
start = max(start, rotation_start)
end = min(end, until) if until else end
return start, end