agendas: use date end when filtering custody agendas (#71633)

This commit is contained in:
Valentin Deniaud 2022-12-01 17:34:57 +01:00 committed by Gitea
parent d131181c4e
commit aac92703b7
6 changed files with 117 additions and 13 deletions

View File

@ -847,10 +847,12 @@ class Agenda(models.Model):
@staticmethod
def filter_for_guardian(qs, guardian_external_id, child_external_id, min_start=None, max_start=None):
agendas = SharedCustodyAgenda.objects.filter(child__user_external_id=child_external_id).order_by(
'-date_start'
'date_start'
)
if max_start:
agendas = agendas.filter(date_start__lte=max_start)
if min_start:
agendas = agendas.filter(Q(date_end__isnull=True) | Q(date_end__gte=min_start))
if not agendas:
return qs
@ -861,20 +863,29 @@ class Agenda(models.Model):
.annotate(odd_week=F('week_number') % 2)
)
previous_date_start = None
previous_date_end = None
filtered_qs = Event.objects.none()
for agenda in agendas:
if previous_date_start and min_start and previous_date_start < min_start.date():
break
filtered_qs |= Agenda.filter_for_custody_agenda(
qs, agenda, guardian_external_id, date_end=previous_date_start
)
previous_date_start = agenda.date_start
filtered_qs |= Agenda.filter_for_custody_agenda(qs, agenda, guardian_external_id)
if not previous_date_end:
# first shared custody agenda, include all events before it begins
filtered_qs |= qs.filter(start_datetime__lt=agenda.date_start)
else:
# include all events between agendas
filtered_qs |= qs.filter(
start_datetime__lt=agenda.date_start, start_datetime__date__gt=previous_date_end
)
previous_date_end = agenda.date_end
if previous_date_end:
# last agenda has end date, include all events after it
filtered_qs |= qs.filter(start_datetime__gt=previous_date_end)
return filtered_qs
@staticmethod
def filter_for_custody_agenda(qs, agenda, guardian_external_id, date_end=None):
def filter_for_custody_agenda(qs, agenda, guardian_external_id):
rules = (
SharedCustodyRule.objects.filter(
guardian__user_external_id=guardian_external_id,
@ -916,8 +927,8 @@ class Agenda(models.Model):
(rules_lookup | Q(in_exceptional_period=True)) & Q(in_excluded_exceptional_period=False),
start_datetime__gte=agenda.date_start,
)
if date_end:
qs = qs.filter(start_datetime__lt=date_end)
if agenda.date_end:
qs = qs.filter(start_datetime__date__lte=agenda.date_end)
return qs

View File

@ -1281,6 +1281,8 @@ def test_datetimes_multiple_agendas_shared_custody_date_start(app):
)
assert len(resp.json['data']) == 0
agenda.date_end = datetime.date(year=2022, month=3, day=9)
agenda.save()
agenda = SharedCustodyAgenda.objects.create(
first_guardian=father,
second_guardian=mother,
@ -1307,6 +1309,8 @@ def test_datetimes_multiple_agendas_shared_custody_date_start(app):
'first-agenda@event-wednesday--2022-03-30-1400',
]
agenda.date_end = datetime.date(year=2022, month=3, day=16)
agenda.save()
agenda = SharedCustodyAgenda.objects.create(
first_guardian=father,
second_guardian=mother,
@ -1349,6 +1353,8 @@ def test_datetimes_multiple_agendas_shared_custody_date_start(app):
'first-agenda@event-wednesday--2022-03-09-1400',
]
agenda.date_end = datetime.date(year=2022, month=3, day=21)
agenda.save()
other_person = Person.objects.create(user_external_id='other_person', first_name='O', last_name='P')
agenda = SharedCustodyAgenda.objects.create(
first_guardian=other_person,
@ -1385,6 +1391,78 @@ def test_datetimes_multiple_agendas_shared_custody_date_start(app):
]
@pytest.mark.freeze_time('2022-03-01 14:00')
def test_datetimes_multiple_agendas_shared_custody_date_boundaries(app):
agenda = Agenda.objects.create(label='First agenda', kind='events', maximal_booking_delay=0)
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
start_datetime = make_aware(datetime.datetime(year=2022, month=3, day=2, hour=14, minute=0))
wednesday_event = Event.objects.create(
slug='event-wednesday',
start_datetime=start_datetime,
recurrence_days=[2],
recurrence_end_date=datetime.datetime(year=2022, month=5, day=15),
places=5,
agenda=agenda,
)
wednesday_event.create_all_recurrences()
Subscription.objects.create(
agenda=agenda,
user_external_id='child_id',
date_start=wednesday_event.start_datetime,
date_end=wednesday_event.recurrence_end_date,
)
father = Person.objects.create(user_external_id='father_id', first_name='John', last_name='Doe')
mother = Person.objects.create(user_external_id='mother_id', first_name='Jane', last_name='Doe')
child = Person.objects.create(user_external_id='child_id', first_name='James', last_name='Doe')
agenda = SharedCustodyAgenda.objects.create(
first_guardian=father,
second_guardian=mother,
child=child,
date_start=datetime.datetime(year=2022, month=3, day=15), # 15 days after recurring event start
date_end=datetime.datetime(year=2022, month=3, day=30), # 30 days after recurring event start
)
SharedCustodyRule.objects.create(agenda=agenda, guardian=father, days=list(range(7)))
agenda = SharedCustodyAgenda.objects.create(
first_guardian=father,
second_guardian=mother,
child=child,
date_start=datetime.datetime(year=2022, month=4, day=13), # 45 days after recurring event start
date_end=datetime.datetime(year=2022, month=4, day=28), # 60 days after recurring event start
)
SharedCustodyRule.objects.create(agenda=agenda, guardian=mother, days=list(range(7)))
resp = app.get(
'/api/agendas/datetimes/',
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'father_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday--2022-03-02-1400', # no custody agenda
'first-agenda@event-wednesday--2022-03-09-1400', # no custody agenda
'first-agenda@event-wednesday--2022-03-16-1400', # has custody
'first-agenda@event-wednesday--2022-03-23-1400', # has custody
'first-agenda@event-wednesday--2022-03-30-1400', # has custody
'first-agenda@event-wednesday--2022-04-06-1400', # no custody agenda
'first-agenda@event-wednesday--2022-05-04-1400', # no custody agenda
'first-agenda@event-wednesday--2022-05-11-1400', # no custody agenda
]
resp = app.get(
'/api/agendas/datetimes/',
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'mother_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday--2022-03-02-1400', # no custody agenda
'first-agenda@event-wednesday--2022-03-09-1400', # no custody agenda
'first-agenda@event-wednesday--2022-04-06-1400', # no custody agenda
'first-agenda@event-wednesday--2022-04-13-1400', # has custody
'first-agenda@event-wednesday--2022-04-20-1400', # has custody
'first-agenda@event-wednesday--2022-04-27-1400', # has custody
'first-agenda@event-wednesday--2022-05-04-1400', # no custody agenda
'first-agenda@event-wednesday--2022-05-11-1400', # no custody agenda
]
def test_datetimes_multiple_agendas_with_status(app):
agenda = Agenda.objects.create(label='agenda', kind='events')
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')

View File

@ -277,7 +277,11 @@ def test_recurring_events_api_list_shared_custody_start_date(app):
child = Person.objects.create(user_external_id='child_id', first_name='James', last_name='Doe')
custody_agenda = SharedCustodyAgenda.objects.create(
first_guardian=father, second_guardian=mother, child=child, date_start=now()
first_guardian=father,
second_guardian=mother,
child=child,
date_start=now(),
date_end=now() + datetime.timedelta(days=14),
)
SharedCustodyRule.objects.create(agenda=custody_agenda, guardian=father, days=[0], weeks='even')
SharedCustodyRule.objects.create(agenda=custody_agenda, guardian=mother, days=[1, 2], weeks='odd')

View File

@ -677,7 +677,11 @@ def test_api_events_fillslots_multiple_agendas_shared_custody_date_start(app, us
child = Person.objects.create(user_external_id='child_id', first_name='James', last_name='Doe')
agenda = SharedCustodyAgenda.objects.create(
first_guardian=father, second_guardian=mother, child=child, date_start=now()
first_guardian=father,
second_guardian=mother,
child=child,
date_start=now(),
date_end=datetime.date(year=2022, month=3, day=9),
)
SharedCustodyRule.objects.create(agenda=agenda, guardian=father, days=list(range(7)))

View File

@ -1376,6 +1376,8 @@ def test_recurring_events_api_fillslots_shared_custody(app, user, freezer):
]
# give father full custody from 14/03/2022
agenda.date_end = datetime.date(year=2022, month=3, day=13)
agenda.save()
agenda2 = SharedCustodyAgenda.objects.create(
first_guardian=father,
second_guardian=mother,

View File

@ -90,18 +90,21 @@ def test_add_shared_custody_agenda_with_rules(app, user, settings):
agenda = SharedCustodyAgenda.objects.get(pk=resp.json['data']['id'])
assert not agenda.is_complete()
assert not agenda.rules.exists()
agenda.delete()
resp = app.post_json('/api/shared-custody/', params={'weeks': 'even', **params})
agenda = SharedCustodyAgenda.objects.get(pk=resp.json['data']['id'])
assert agenda.is_complete()
assert agenda.rules.filter(guardian__first_name='John', weeks='even').exists()
assert agenda.rules.filter(guardian__first_name='Jane', weeks='odd').exists()
agenda.delete()
resp = app.post_json('/api/shared-custody/', params={'weeks': 'odd', **params})
agenda = SharedCustodyAgenda.objects.get(pk=resp.json['data']['id'])
assert agenda.is_complete()
assert agenda.rules.filter(guardian__first_name='John', weeks='odd').exists()
assert agenda.rules.filter(guardian__first_name='Jane', weeks='even').exists()
agenda.delete()
resp = app.post_json(
'/api/shared-custody/', params={'christmas_holidays:periodicity': 'first-half', **params}
@ -114,6 +117,7 @@ def test_add_shared_custody_agenda_with_rules(app, user, settings):
guardian__first_name='Jane', holiday__slug='christmas_holidays', periodicity='second-half', years=''
).exists()
assert agenda.periods.count() == 12
agenda.delete()
resp = app.post_json(
'/api/shared-custody/',
@ -149,6 +153,7 @@ def test_add_shared_custody_agenda_with_rules(app, user, settings):
years='odd',
).exists()
assert agenda.periods.count() == 20
agenda.delete()
# unknown holiday
resp = app.post_json(