From 3936f9450a03558a03ae264087fe867f0ac47898 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Thu, 29 Jul 2021 11:20:38 +0200 Subject: [PATCH 2/3] api: move event selection code to function (#55367) --- chrono/api/views.py | 82 +++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/chrono/api/views.py b/chrono/api/views.py index 08c87d2..37dc22c 100644 --- a/chrono/api/views.py +++ b/chrono/api/views.py @@ -551,6 +551,49 @@ def get_event_recurrence(agenda, event_identifier): ) +def get_events_from_slots(slots, request, agenda, payload): + user_external_id = payload.get('user_external_id') or None + exclude_user = payload.get('exclude_user') + book_events = payload.get('events') or request.query_params.get('events') or 'future' + book_past = book_events in ['all', 'past'] + book_future = book_events in ['all', 'future'] + + # convert event recurrence identifiers to real event slugs + for i, slot in enumerate(slots.copy()): + if ':' not in slot: + continue + event = get_event_recurrence(agenda, slot) + slots[i] = event.slug + + try: + events = agenda.event_set.filter(id__in=[int(s) for s in slots]).order_by('start_datetime') + except ValueError: + events = agenda.event_set.filter(slug__in=slots).order_by('start_datetime') + + for event in events: + if event.start_datetime >= now(): + if not book_future or not event.in_bookable_period(): + raise APIError(_('event not bookable'), err_class='event not bookable') + else: + if not book_past: + raise APIError(_('event not bookable'), err_class='event not bookable') + if event.cancelled: + raise APIError(_('event is cancelled'), err_class='event is cancelled') + if exclude_user and user_external_id: + if event.booking_set.filter(user_external_id=user_external_id).exists(): + raise APIError( + _('event is already booked by user'), err_class='event is already booked by user' + ) + + if not events.exists(): + raise APIError( + _('unknown event identifiers or slugs'), + err_class='unknown event identifiers or slugs', + http_status=status.HTTP_400_BAD_REQUEST, + ) + return events + + def get_resources_from_request(request, agenda): if agenda.kind != 'meetings' or 'resources' not in request.GET: return [] @@ -1233,9 +1276,6 @@ class Fillslots(APIView): color = None user_external_id = payload.get('user_external_id') or None exclude_user = payload.get('exclude_user') - book_events = payload.get('events') or request.query_params.get('events') or 'future' - book_past = book_events in ['all', 'past'] - book_future = book_events in ['all', 'future'] if agenda.accept_meetings(): # slots are actually timeslot ids (meeting_type:start_datetime), not events ids. @@ -1378,39 +1418,7 @@ class Fillslots(APIView): event.resources.add(*resources) events.append(event) else: - # convert event recurrence identifiers to real event slugs - for i, slot in enumerate(slots.copy()): - if ':' not in slot: - continue - event = get_event_recurrence(agenda, slot) - slots[i] = event.slug - - try: - events = agenda.event_set.filter(id__in=[int(s) for s in slots]).order_by('start_datetime') - except ValueError: - events = agenda.event_set.filter(slug__in=slots).order_by('start_datetime') - - for event in events: - if event.start_datetime >= now(): - if not book_future or not event.in_bookable_period(): - raise APIError(_('event not bookable'), err_class='event not bookable') - else: - if not book_past: - raise APIError(_('event not bookable'), err_class='event not bookable') - if event.cancelled: - raise APIError(_('event is cancelled'), err_class='event is cancelled') - if exclude_user and user_external_id: - if event.booking_set.filter(user_external_id=user_external_id).exists(): - raise APIError( - _('event is already booked by user'), err_class='event is already booked by user' - ) - - if not events.count(): - raise APIError( - _('unknown event identifiers or slugs'), - err_class='unknown event identifiers or slugs', - http_status=status.HTTP_400_BAD_REQUEST, - ) + events = get_events_from_slots(slots, request, agenda, payload) # search free places. Switch to waiting list if necessary. in_waiting_list = False @@ -1451,7 +1459,7 @@ class Fillslots(APIView): # now we have a list of events, book them. primary_booking = None for event in events: - for i in range(places_count): + for dummy in range(places_count): new_booking = make_booking( event, payload, extra_data, primary_booking, in_waiting_list, color ) -- 2.20.1