Skip to content

Commit 03d2d35

Browse files
committed
feat: event with ongoing occurrences can have space for enrolment
An event with ongoing occurrences can have space for enrolment if the enrolement hasn't been set to end before an occurence starts. Refs: PT-1952
1 parent d5e48b4 commit 03d2d35

2 files changed

Lines changed: 88 additions & 6 deletions

File tree

occurrences/models.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,23 +303,35 @@ def has_space_for_enrolments(self) -> Optional[bool]:
303303
if not self.has_enrolments_system() or self.has_external_enrolments_system():
304304
return None
305305

306-
return any(
306+
has_upcoming_space = any(
307307
occurrence.has_space_left()
308308
for occurrence in self.occurrences.filter_upcoming()
309309
)
310310

311+
if self.enrolment_end_days is None:
312+
# No limit to when enrolments can be made before the occurrence start.
313+
return has_upcoming_space or any(
314+
occurrence.has_space_left()
315+
for occurrence in self.occurrences.filter_ongoing()
316+
)
317+
318+
return has_upcoming_space
319+
311320

312321
class OccurrenceQueryset(models.QuerySet):
313322
def delete(self, *args, **kwargs):
314323
for obj in self:
315324
obj.delete()
316325

317326
def filter_upcoming(self, *args, **kwargs):
318-
"""Filter occurrences that are not not cancelled and
319-
are held in the future.
320-
"""
327+
"""Filter occurrences that are not cancelled and are held in the future."""
321328
return self.filter(cancelled=False, start_time__gte=timezone.now())
322329

330+
def filter_ongoing(self, *args, **kwargs):
331+
"""Filter occurrences that are not cancelled and are ongoing at the moment."""
332+
now = timezone.now()
333+
return self.filter(cancelled=False, start_time__lte=now, end_time__gte=now)
334+
323335

324336
class Occurrence(GDPRModel, SerializableMixin, TimestampedModel):
325337
OCCURRENCE_SEAT_TYPE_CHILDREN_COUNT = "children_count"

occurrences/tests/test_models.py

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -980,20 +980,90 @@ def test_palvelutarjotin_event_has_space_for_enrolments_returning_boolean(
980980
mock_get_event_data,
981981
):
982982
p_event = PalvelutarjotinEventFactory()
983+
# Past occurrences
984+
OccurrenceFactory.create_batch(
985+
4,
986+
p_event=p_event,
987+
cancelled=False,
988+
start_time=timezone.now() - timedelta(days=2),
989+
end_time=timezone.now() - timedelta(days=1),
990+
)
991+
# Ongoing occurrences
992+
OccurrenceFactory.create_batch(
993+
2,
994+
p_event=p_event,
995+
cancelled=False,
996+
start_time=timezone.now() - timedelta(days=1),
997+
end_time=timezone.now() + timedelta(days=1),
998+
)
999+
# Future occurrences
9831000
OccurrenceFactory.create_batch(
9841001
3,
9851002
p_event=p_event,
9861003
cancelled=False,
9871004
start_time=timezone.now() + timedelta(days=1),
1005+
end_time=timezone.now() + timedelta(days=2),
1006+
)
1007+
assert p_event.occurrences.count() == 9
1008+
assert p_event.occurrences.filter_upcoming().count() == 3
1009+
assert p_event.occurrences.filter_ongoing().count() == 2
1010+
with patch(
1011+
"occurrences.models.PalvelutarjotinEvent.has_external_enrolments_system",
1012+
return_value=False,
1013+
):
1014+
with patch(
1015+
"occurrences.models.PalvelutarjotinEvent.has_internal_enrolments_system",
1016+
return_value=True,
1017+
):
1018+
with patch(
1019+
"occurrences.models.Occurrence.has_space_left"
1020+
) as mock_has_space_left:
1021+
mock_has_space_left.return_value = False
1022+
assert p_event.has_space_for_enrolments() is False
1023+
assert mock_has_space_left.call_count == 3
1024+
with patch(
1025+
"occurrences.models.PalvelutarjotinEvent.has_external_enrolments_system",
1026+
return_value=False,
1027+
):
1028+
with patch(
1029+
"occurrences.models.PalvelutarjotinEvent.has_internal_enrolments_system",
1030+
return_value=True,
1031+
):
1032+
with patch(
1033+
"occurrences.models.Occurrence.has_space_left"
1034+
) as mock_has_space_left:
1035+
# 2nd occurrence returns True, so result is True
1036+
# and any-call returns after 2nd round.
1037+
mock_has_space_left.side_effect = [False, True, False]
1038+
assert p_event.has_space_for_enrolments() is True
1039+
assert mock_has_space_left.call_count == 2
1040+
1041+
1042+
@pytest.mark.django_db
1043+
def test_palvelutarjotin_event_has_space_for_enrolments_ongoing_events(
1044+
mock_get_event_data,
1045+
):
1046+
"""Ongoing events are not considered"""
1047+
p_event = PalvelutarjotinEventFactory(enrolment_end_days=None)
1048+
# Past occurrences
1049+
OccurrenceFactory.create_batch(
1050+
2,
1051+
p_event=p_event,
1052+
cancelled=False,
1053+
start_time=timezone.now() - timedelta(days=2),
1054+
end_time=timezone.now() - timedelta(days=1),
9881055
)
1056+
# Ongoing occurrences
9891057
OccurrenceFactory.create_batch(
9901058
3,
9911059
p_event=p_event,
9921060
cancelled=False,
9931061
start_time=timezone.now() - timedelta(days=1),
1062+
end_time=timezone.now() + timedelta(days=1),
9941063
)
995-
assert p_event.occurrences.count() == 6
996-
assert p_event.occurrences.filter_upcoming().count() == 3
1064+
assert p_event.occurrences.count() == 5
1065+
assert p_event.occurrences.filter_upcoming().count() == 0
1066+
assert p_event.occurrences.filter_ongoing().count() == 3
9971067
with patch(
9981068
"occurrences.models.PalvelutarjotinEvent.has_external_enrolments_system",
9991069
return_value=False,

0 commit comments

Comments
 (0)