api: fillslots, create events in the transaction (#67053)

This commit is contained in:
Lauréline Guérin 2022-07-21 09:07:34 +02:00
parent a6ca69a481
commit b17a2ee543
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
1 changed files with 35 additions and 31 deletions

View File

@ -21,7 +21,7 @@ import itertools
import json
import uuid
from django.db import transaction
from django.db import IntegrityError, transaction
from django.db.models import BooleanField, Count, ExpressionWrapper, F, Prefetch, Q
from django.db.models.expressions import RawSQL
from django.db.models.functions import TruncDay
@ -1513,42 +1513,42 @@ class Fillslots(APIView):
# create them now, with data from the slots and the desk we found.
events = []
for start_datetime in datetimes:
event = Event.objects.create(
agenda=available_desk.agenda,
slug=str(uuid.uuid4()), # set slug to avoid queries during slug generation
meeting_type=meeting_type,
start_datetime=start_datetime,
full=False,
places=1,
desk=available_desk,
events.append(
Event(
agenda=available_desk.agenda,
slug=str(uuid.uuid4()), # set slug to avoid queries during slug generation
meeting_type=meeting_type,
start_datetime=start_datetime,
full=False,
places=1,
desk=available_desk,
)
)
if resources:
event.resources.add(*resources)
events.append(event)
in_waiting_list = False
else:
events = get_events_from_slots(slots, request, agenda, payload)
# search free places. Switch to waiting list if necessary.
in_waiting_list = False
for event in events:
if event.start_datetime > now():
if payload.get('force_waiting_list') and not event.waiting_list_places:
raise APIError(N_('no waiting list'))
# search free places. Switch to waiting list if necessary.
in_waiting_list = False
for event in events:
if event.start_datetime > now():
if payload.get('force_waiting_list') and not event.waiting_list_places:
raise APIError(N_('no waiting list'))
if event.waiting_list_places:
if (
payload.get('force_waiting_list')
or (event.booked_places + places_count) > event.places
or event.booked_waiting_list_places
):
# if this is full or there are people waiting, put new bookings
# in the waiting list.
in_waiting_list = True
if (event.booked_waiting_list_places + places_count) > event.waiting_list_places:
if event.waiting_list_places:
if (
payload.get('force_waiting_list')
or (event.booked_places + places_count) > event.places
or event.booked_waiting_list_places
):
# if this is full or there are people waiting, put new bookings
# in the waiting list.
in_waiting_list = True
if (event.booked_waiting_list_places + places_count) > event.waiting_list_places:
raise APIError(N_('sold out'))
else:
if (event.booked_places + places_count) > event.places:
raise APIError(N_('sold out'))
else:
if (event.booked_places + places_count) > event.places:
raise APIError(N_('sold out'))
with transaction.atomic():
if to_cancel_booking:
@ -1558,6 +1558,10 @@ class Fillslots(APIView):
# now we have a list of events, book them.
primary_booking = None
for event in events:
if agenda.accept_meetings():
event.save()
if resources:
event.resources.add(*resources)
for dummy in range(places_count):
new_booking = make_booking(
event, payload, extra_data, primary_booking, in_waiting_list, color