api: target shared custody agendas by date when filtering (#66933)

This commit is contained in:
Valentin Deniaud 2022-07-26 11:20:47 +02:00
parent cb409ebb5b
commit ded732b15a
5 changed files with 79 additions and 7 deletions

View File

@ -823,10 +823,13 @@ class Agenda(models.Model):
]
@staticmethod
def filter_for_guardian(qs, guardian_external_id, child_external_id):
def filter_for_guardian(qs, guardian_external_id, child_external_id, min_start=None, max_start=None):
agendas = SharedCustodyAgenda.objects.filter(children__user_external_id=child_external_id).order_by(
'-date_start'
)
if max_start:
agendas = agendas.filter(date_start__lte=max_start)
if not agendas:
return qs
@ -839,6 +842,8 @@ class Agenda(models.Model):
previous_date_start = 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
)

View File

@ -929,7 +929,13 @@ class MultipleAgendasDatetimes(APIView):
agenda__subscriptions__date_end__gt=F('start_datetime'),
)
if guardian_external_id:
entries = Agenda.filter_for_guardian(entries, guardian_external_id, user_external_id)
entries = Agenda.filter_for_guardian(
entries,
guardian_external_id,
user_external_id,
min_start=payload.get('date_start'),
max_start=payload.get('date_end'),
)
entries = list(entries)
if 'agendas' in request.query_params:
@ -1830,7 +1836,13 @@ class RecurringFillslots(APIView):
if end_datetime:
events = events.filter(start_datetime__lte=end_datetime)
if guardian_external_id:
events = Agenda.filter_for_guardian(events, guardian_external_id, user_external_id)
events = Agenda.filter_for_guardian(
events,
guardian_external_id,
user_external_id,
min_start=start_datetime,
max_start=end_datetime,
)
return events
@ -1901,7 +1913,7 @@ class EventsFillslots(APIView):
bypass_delays = payload.get('bypass_delays')
check_overlaps = payload.get('check_overlaps')
events = self.get_events(request, payload)
events = self.get_events(request, payload, start_datetime, end_datetime)
if check_overlaps:
overlapping_events = Event.annotate_queryset_with_overlaps(events).filter(has_overlap=True)
@ -2024,7 +2036,7 @@ class EventsFillslots(APIView):
}
return Response(response)
def get_events(self, request, payload):
def get_events(self, request, payload, start_datetime, end_datetime):
return get_events_from_slots(payload['slots'], request, self.agenda, payload)
def get_already_booked_events(self, user_external_id):
@ -2057,7 +2069,7 @@ class MultipleAgendasEventsFillslots(EventsFillslots):
return self.fillslots(request)
def get_events(self, request, payload):
def get_events(self, request, payload, start_datetime, end_datetime):
events_by_agenda = collections.defaultdict(list)
for slot in payload['slots']:
agenda, event = slot.split('@')
@ -2087,7 +2099,11 @@ class MultipleAgendasEventsFillslots(EventsFillslots):
if self.guardian_external_id:
events_outside_custody = events.exclude(
pk__in=Agenda.filter_for_guardian(
events, self.guardian_external_id, payload['user_external_id']
events,
self.guardian_external_id,
payload['user_external_id'],
min_start=start_datetime,
max_start=end_datetime,
).values('pk')
)
if events_outside_custody.exists():

View File

@ -755,6 +755,20 @@ def test_datetimes_multiple_agendas_shared_custody(app):
assert len(resp.json['data']) == 1
assert resp.json['data'][0]['id'] == 'first-agenda@event-odd-week'
# check date_start/date_end params
resp = app.get(
'/api/agendas/datetimes/',
params={
'subscribed': 'all',
'user_external_id': 'child_id',
'guardian_external_id': 'father_id',
'date_start': '2022-03-09',
'date_end': '2022-03-20',
},
)
assert len(resp.json['data']) == 1
assert resp.json['data'][0]['id'] == 'first-agenda@event-even-week'
# add father custody period spanning odd week event
period = SharedCustodyPeriod.objects.create(
agenda=agenda,
@ -1318,6 +1332,21 @@ def test_datetimes_multiple_agendas_shared_custody_date_start(app):
'first-agenda@event-wednesday--2022-03-23-1400',
]
# check date_start/date_end params
resp = app.get(
'/api/agendas/datetimes/',
params={
'subscribed': 'all',
'user_external_id': 'child_id',
'guardian_external_id': 'father_id',
'date_start': '2022-03-09',
'date_end': '2022-03-20',
},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday--2022-03-09-1400',
]
other_person = Person.objects.create(user_external_id='other_person', first_name='O', last_name='P')
agenda = SharedCustodyAgenda.objects.create(
first_guardian=other_person,

View File

@ -719,6 +719,14 @@ def test_api_events_fillslots_multiple_agendas_shared_custody_date_start(app, us
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'Some events are outside guardian custody: first-agenda@event-thursday'
# check date_start/date_end params
Booking.objects.all().delete()
resp = app.post_json(
'/api/agendas/events/fillslots/?subscribed=all&guardian_external_id=mother_id',
params={'date_start': '2022-03-09', 'date_end': '2022-03-20', **params},
)
assert resp.json['booking_count'] == 1
@pytest.mark.freeze_time('2021-09-06 12:00')
def test_api_events_fillslots_multiple_agendas_overlapping_events(app, user, freezer):

View File

@ -1408,6 +1408,20 @@ def test_recurring_events_api_fillslots_shared_custody(app, user, freezer):
'2022-03-13', # last date before new agenda rules apply
]
# check date_start/date_end params
Booking.objects.all().delete()
resp = app.post_json(
(fillslots_url + '&date_start=2022-03-11&date_end=2022-03-18') % 'father_id', params=params
)
assert [x['date'] for x in resp.json['booked_events']] == [
'2022-03-11',
'2022-03-12',
'2022-03-14',
'2022-03-15',
'2022-03-16',
'2022-03-17',
]
@pytest.mark.freeze_time('2021-09-06 12:00')
def test_recurring_events_api_fillslots_overlapping_events(app, user):