Fix higher priority overlapping multiple same-start events

This commit is contained in:
Matias Bordese 2022-08-17 10:20:33 -03:00
parent 5d9ce99631
commit bfe0ab2d1e
2 changed files with 69 additions and 5 deletions

View file

@ -329,9 +329,7 @@ class OnCallSchedule(PolymorphicModel):
# (ie. insert the event where it should be to keep the order criteria)
# TODO: switch to bisect insert on python 3.10 (or consider heapq)
insort_event(pending, ev)
else:
# done, go to next event
continue
# done, go to next event
elif ev["start"] >= intervals[current_interval_idx][0] and ev["end"] <= intervals[current_interval_idx][1]:
# event inside an already scheduled interval, ignore (go to next)
@ -348,8 +346,6 @@ class OnCallSchedule(PolymorphicModel):
# unresolved, re-add to pending
# TODO: switch to bisect insert on python 3.10 (or consider heapq)
insort_event(pending, ev)
# move to next interval and process the updated event as any other event
current_interval_idx += 1
elif ev["start"] >= intervals[current_interval_idx][1]:
# event starts after the current interval, move to next interval and go through it

View file

@ -389,6 +389,74 @@ def test_final_schedule_splitting_events(
assert returned_events == expected_events
@pytest.mark.django_db
def test_final_schedule_splitting_same_time_events(
make_organization, make_user_for_organization, make_on_call_shift, make_schedule
):
organization = make_organization()
schedule = make_schedule(
organization,
schedule_class=OnCallScheduleWeb,
name="test_web_schedule",
)
now = timezone.now().replace(hour=0, minute=0, second=0, microsecond=0)
start_date = now - timezone.timedelta(days=7)
user_a, user_b, user_c = (make_user_for_organization(organization, username=i) for i in "ABC")
shifts = (
# user, priority, start time (h), duration (hs)
(user_a, 1, 10, 10), # r1-1: 10-20 / A
(user_b, 1, 10, 10), # r1-2: 10-20 / B
(user_c, 2, 10, 3), # r2-1: 10-13 / C
)
for user, priority, start_h, duration in shifts:
data = {
"start": start_date + timezone.timedelta(hours=start_h),
"rotation_start": start_date + timezone.timedelta(hours=start_h),
"duration": timezone.timedelta(hours=duration),
"priority_level": priority,
"frequency": CustomOnCallShift.FREQUENCY_DAILY,
"schedule": schedule,
}
on_call_shift = make_on_call_shift(
organization=organization, shift_type=CustomOnCallShift.TYPE_ROLLING_USERS_EVENT, **data
)
on_call_shift.add_rolling_users([[user]])
returned_events = schedule.final_events("UTC", start_date, days=1)
expected = (
# start (h), duration (H), user, priority
(10, 3, "C", 2), # 10-13 C
(13, 7, "A", 1), # 13-20 A
(13, 7, "B", 1), # 13-20 B
)
expected_events = [
{
"end": start_date + timezone.timedelta(hours=start + duration),
"priority_level": priority,
"start": start_date + timezone.timedelta(hours=start),
"user": user,
}
for start, duration, user, priority in expected
]
returned_events = [
{
"end": e["end"],
"priority_level": e["priority_level"],
"start": e["start"],
"user": e["users"][0]["display_name"] if e["users"] else None,
}
for e in sorted(
returned_events, key=lambda e: (e["start"], e["users"][0]["display_name"] if e["users"] else None)
)
if not e["is_gap"]
]
assert returned_events == expected_events
@pytest.mark.django_db
def test_preview_shift(make_organization, make_user_for_organization, make_schedule, make_on_call_shift):
organization = make_organization()