api: add primary_event in event details (#88559)
gitea/chrono/pipeline/head This commit looks good Details

This commit is contained in:
Lauréline Guérin 2024-03-22 17:40:51 +01:00
parent f7e224ba9b
commit dad572a914
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
10 changed files with 62 additions and 16 deletions

View File

@ -1171,6 +1171,9 @@ class Agenda(WithSnapshotMixin, WithApplicationMixin, WithInspectMixin, models.M
event_queryset = Agenda.filter_for_guardian(
event_queryset, guardian_external_id, user_external_id
)
event_queryset = event_queryset.prefetch_related(
Prefetch('primary_event', queryset=Event.objects.all().order_by())
)
return qs.filter(kind='events').prefetch_related(
Prefetch(

View File

@ -331,6 +331,7 @@ def get_short_event_detail(
details = {
'id': '%s@%s' % (agenda.slug, event.slug) if multiple_agendas else event.slug,
'slug': event.slug, # kept for compatibility
'primary_event': None,
'text': get_event_text(event, agenda),
'label': event.label or '',
'agenda_label': agenda.label,
@ -345,6 +346,12 @@ def get_short_event_detail(
'check_locked': event.check_locked,
'invoiced': event.invoiced,
}
if event.primary_event:
details['primary_event'] = (
'%s@%s' % (agenda.slug, event.primary_event.slug)
if multiple_agendas
else event.primary_event.slug
)
for key, value in event.get_custom_fields().items():
details['custom_field_%s' % key] = value
return details
@ -663,6 +670,7 @@ class Datetimes(APIView):
entries = Event.annotate_queryset_for_user(entries, user_external_id)
if lock_code:
entries = Event.annotate_queryset_for_lock_code(entries, lock_code=lock_code)
entries = entries.prefetch_related(Prefetch('primary_event', queryset=Event.objects.all().order_by()))
entries = entries.order_by('start_datetime', 'duration', 'label')
if payload['hide_disabled']:
@ -743,6 +751,9 @@ class MultipleAgendasDatetimes(APIView):
entries = Event.annotate_queryset_for_user(entries, user_external_id, with_status=with_status)
if lock_code:
Event.annotate_queryset_for_lock_code(entries, lock_code)
entries = entries.prefetch_related(
Prefetch('primary_event', queryset=Event.objects.all().order_by())
)
if check_overlaps:
entries = Event.annotate_queryset_with_overlaps(entries)
@ -1845,6 +1856,7 @@ class RecurringFillslots(APIView):
min_start=start_datetime,
max_start=end_datetime,
)
events = events.prefetch_related(Prefetch('primary_event', queryset=Event.objects.all().order_by()))
return events
@ -2003,6 +2015,7 @@ class EventsFillslots(APIView):
output_field=BooleanField(),
)
)
events = events.prefetch_related(Prefetch('primary_event', queryset=Event.objects.all().order_by()))
waiting_list_event_ids = [event.pk for event in events if event.in_waiting_list]
extra_data = get_extra_data(request, payload)
@ -2227,9 +2240,13 @@ class MultipleAgendasEventsFillslotsRevert(APIView):
if booking.previous_state == 'cancelled':
bookings_to_cancel.append(booking)
events = Event.objects.filter(
pk__in=[b.event_id for b in bookings_to_cancel + bookings_to_book + bookings_to_delete]
).prefetch_related('agenda')
events = (
Event.objects.filter(
pk__in=[b.event_id for b in bookings_to_cancel + bookings_to_book + bookings_to_delete]
)
.prefetch_related('agenda')
.prefetch_related(Prefetch('primary_event', queryset=Event.objects.all().order_by()))
)
events_by_id = {x.id: x for x in events}
with transaction.atomic():
cancellation_datetime = now()
@ -2753,10 +2770,12 @@ class BookingsAPI(ListAPIView):
return Response({'err': 0, 'data': data})
def get_queryset(self):
event_queryset = Event.objects.all().prefetch_related(
'agenda', 'desk', Prefetch('primary_event', queryset=Event.objects.all().order_by())
)
return (
Booking.objects.filter(primary_booking__isnull=True, cancellation_datetime__isnull=True)
.select_related('event', 'event__agenda', 'event__desk')
.prefetch_related('user_checks')
.prefetch_related('user_checks', Prefetch('event', queryset=event_queryset))
.order_by('event__start_datetime', 'event__slug', 'event__agenda__slug', 'pk')
)

View File

@ -129,6 +129,7 @@ def test_datetime_api_label(app):
agenda=agenda,
)
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert resp.json['data'][0]['primary_event'] is None
assert resp.json['data'][0]['text'] == 'Hello world'
assert resp.json['data'][0]['label'] == 'Hello world'
@ -692,6 +693,8 @@ def test_recurring_events_api(app, user, freezer):
assert data[0]['id'] == 'abc--2021-01-19-1305'
assert data[0]['datetime'] == '2021-01-19 13:05:00'
assert data[0]['text'] == "Rock'n roll (Jan. 19, 2021, 1:05 p.m.)"
assert data[0]['label'] == "Rock'n roll"
assert data[0]['primary_event'] == 'abc'
assert data[3]['id'] == 'abc--2021-02-09-1305'
assert Event.objects.count() == 6
@ -713,7 +716,7 @@ def test_recurring_events_api(app, user, freezer):
# check querysets
with CaptureQueriesContext(connection) as ctx:
app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(ctx.captured_queries) == 3
assert len(ctx.captured_queries) == 4
# events follow agenda display template
agenda.event_display_template = '{{ event.label }} - {{ event.start_datetime }}'

View File

@ -34,12 +34,14 @@ def test_datetimes_multiple_agendas(app):
Desk.objects.create(agenda=first_agenda, slug='_exceptions_holder')
Event.objects.create(
slug='event',
label='Event',
start_datetime=now() + datetime.timedelta(days=5),
places=5,
agenda=first_agenda,
)
event = Event.objects.create( # base recurring event not visible in datetimes api
slug='recurring',
label='Recurring',
start_datetime=now() + datetime.timedelta(hours=1),
recurrence_days=[localtime().isoweekday()],
recurrence_end_date=now() + datetime.timedelta(days=15),
@ -60,11 +62,18 @@ def test_datetimes_multiple_agendas(app):
Booking.objects.create(event=event)
agenda_slugs = '%s,%s' % (first_agenda.slug, second_agenda.slug)
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs})
with CaptureQueriesContext(connection) as ctx:
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs})
assert len(ctx.captured_queries) == 3
assert len(resp.json['data']) == 5
assert resp.json['data'][0]['id'] == 'first-agenda@recurring--2021-05-06-1700'
assert resp.json['data'][0]['text'] == 'Recurring (May 6, 2021, 5 p.m.)'
assert resp.json['data'][0]['label'] == 'Recurring'
assert resp.json['data'][0]['primary_event'] == 'first-agenda@recurring'
assert resp.json['data'][1]['id'] == 'first-agenda@event'
assert resp.json['data'][1]['text'] == 'May 11, 2021, 4 p.m.'
assert resp.json['data'][1]['text'] == 'Event'
assert resp.json['data'][1]['label'] == 'Event'
assert resp.json['data'][1]['primary_event'] is None
assert resp.json['data'][1]['places']['available'] == 5
assert resp.json['data'][2]['id'] == 'second-agenda@event'

View File

@ -434,7 +434,7 @@ def test_recurring_events_api_list_multiple_agendas_queries(app):
'/api/agendas/recurring-events/?subscribed=category-a&user_external_id=xxx&guardian_external_id=father_id'
)
assert len(resp.json['data']) == 40
assert len(ctx.captured_queries) == 5
assert len(ctx.captured_queries) == 6
@pytest.mark.freeze_time('2021-09-06 12:00')

View File

@ -950,6 +950,7 @@ def test_api_events_fillslots_multiple_agendas_revert(app, user):
'slug': 'event',
'text': 'Event',
'url': None,
'primary_event': None,
}
],
'deleted_booking_count': 0,
@ -986,6 +987,7 @@ def test_api_events_fillslots_multiple_agendas_revert(app, user):
'slug': 'event',
'text': 'Event',
'url': None,
'primary_event': None,
}
],
'deleted_booking_count': 0,
@ -1028,6 +1030,7 @@ def test_api_events_fillslots_multiple_agendas_revert(app, user):
'slug': 'event',
'text': 'Event',
'url': None,
'primary_event': None,
}
],
}
@ -1064,6 +1067,7 @@ def test_api_events_fillslots_multiple_agendas_revert(app, user):
'slug': 'event',
'text': 'Event',
'url': None,
'primary_event': None,
}
],
}
@ -1100,6 +1104,7 @@ def test_api_events_fillslots_multiple_agendas_revert(app, user):
'slug': 'event',
'text': 'Event',
'url': None,
'primary_event': None,
}
],
'booked_booking_count': 0,
@ -1138,6 +1143,7 @@ def test_api_events_fillslots_multiple_agendas_revert(app, user):
'slug': 'event',
'text': 'Event',
'url': None,
'primary_event': None,
}
],
'booked_booking_count': 0,
@ -1169,10 +1175,14 @@ def test_api_events_fillslots_multiple_agendas_revert(app, user):
duration=120,
places=1,
agenda=agenda,
recurrence_days=[7],
recurrence_end_date=now() + datetime.timedelta(days=14), # 2 weeks
)
event.create_all_recurrences()
event = event.recurrences.first()
Booking.objects.create(
event=event, request_uuid=request_uuid, previous_state='unbooked', cancellation_datetime=now()
)
with CaptureQueriesContext(connection) as ctx:
resp = app.post(revert_url)
assert len(ctx.captured_queries) == 14
assert len(ctx.captured_queries) == 15

View File

@ -107,7 +107,7 @@ def test_recurring_events_api_fillslots(app, user, freezer, action):
params['user_external_id'] = 'user_id_3'
with CaptureQueriesContext(connection) as ctx:
resp = app.post_json(fillslots_url, params=params)
assert len(ctx.captured_queries) in [12, 13]
assert len(ctx.captured_queries) in [15, 16]
# everything goes in waiting list
assert events.filter(booked_waiting_list_places=1).count() == 6
# but an event was full
@ -1368,7 +1368,7 @@ def test_recurring_events_api_fillslots_multiple_agendas_queries(app, user):
)
assert resp.json['booking_count'] == 180
assert resp.json['cancelled_booking_count'] == 0
assert len(ctx.captured_queries) == 15
assert len(ctx.captured_queries) == 17
with CaptureQueriesContext(connection) as ctx:
resp = app.post_json(
@ -1382,7 +1382,7 @@ def test_recurring_events_api_fillslots_multiple_agendas_queries(app, user):
)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 5
assert len(ctx.captured_queries) == 17
assert len(ctx.captured_queries) == 18
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')
@ -1401,7 +1401,7 @@ def test_recurring_events_api_fillslots_multiple_agendas_queries(app, user):
params={'slots': events_to_book, 'user_external_id': 'xxx'},
)
assert resp.json['booking_count'] == 100
assert len(ctx.captured_queries) == 14
assert len(ctx.captured_queries) == 16
@pytest.mark.freeze_time('2022-03-07 14:00') # Monday of 10th week

View File

@ -320,7 +320,7 @@ def test_agendas_api(settings, app):
with CaptureQueriesContext(connection) as ctx:
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
assert len(ctx.captured_queries) == 3
assert len(ctx.captured_queries) == 4
def test_agenda_detail_api(app):

View File

@ -188,7 +188,7 @@ def test_bookings_api(app, user):
with CaptureQueriesContext(connection) as ctx:
resp = app.get('/api/bookings/', params={'user_external_id': 'enfant-1234'})
assert len(ctx.captured_queries) == 3
assert len(ctx.captured_queries) == 6
assert resp.json['err'] == 0
assert resp.json['data'] == [

View File

@ -44,6 +44,7 @@ def test_status(app, user):
'err': 0,
'id': 'event-slug',
'slug': 'event-slug',
'primary_event': None,
'text': str(event),
'label': '',
'agenda_label': 'Foo bar',
@ -84,6 +85,7 @@ def test_status(app, user):
'err': 0,
'id': 'event-slug',
'slug': 'event-slug',
'primary_event': None,
'text': str(event),
'label': '',
'agenda_label': 'Foo bar',