api: use APIError in fillslots view (#43077)

This commit is contained in:
Lauréline Guérin 2020-05-19 17:53:34 +02:00
parent 79f6f158c8
commit 2e091220f5
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
1 changed files with 64 additions and 89 deletions

View File

@ -692,7 +692,10 @@ class Fillslots(APIView):
serializer_class = SlotsSerializer
def post(self, request, agenda_identifier=None, event_identifier=None, format=None):
return self.fillslot(request=request, agenda_identifier=agenda_identifier, format=format)
try:
return self.fillslot(request=request, agenda_identifier=agenda_identifier, format=format)
except APIError as e:
return e.to_response()
def fillslot(self, request, agenda_identifier=None, slots=[], format=None):
multiple_booking = bool(not slots)
@ -707,27 +710,21 @@ class Fillslots(APIView):
serializer = self.serializer_class(data=request.data, partial=True)
if not serializer.is_valid():
return Response(
{
'err': 1,
'err_class': 'invalid payload',
'err_desc': _('invalid payload'),
'errors': serializer.errors,
},
status=status.HTTP_400_BAD_REQUEST,
raise APIError(
_('invalid payload'),
err_class='invalid payload',
errors=serializer.errors,
http_status=status.HTTP_400_BAD_REQUEST,
)
payload = serializer.validated_data
if 'slots' in payload:
slots = payload['slots']
if not slots:
return Response(
{
'err': 1,
'err_class': 'slots list cannot be empty',
'err_desc': _('slots list cannot be empty'),
},
status=status.HTTP_400_BAD_REQUEST,
raise APIError(
_('slots list cannot be empty'),
err_class='slots list cannot be empty',
http_status=status.HTTP_400_BAD_REQUEST,
)
if 'count' in payload:
@ -737,25 +734,19 @@ class Fillslots(APIView):
try:
places_count = int(request.query_params['count'])
except ValueError:
return Response(
{
'err': 1,
'err_class': 'invalid value for count (%s)' % request.query_params['count'],
'err_desc': _('invalid value for count (%s)') % request.query_params['count'],
},
status=status.HTTP_400_BAD_REQUEST,
raise APIError(
_('invalid value for count (%s)') % request.query_params['count'],
err_class='invalid value for count (%s)' % request.query_params['count'],
http_status=status.HTTP_400_BAD_REQUEST,
)
else:
places_count = 1
if places_count <= 0:
return Response(
{
'err': 1,
'err_class': 'count cannot be less than or equal to zero',
'err_desc': _('count cannot be less than or equal to zero'),
},
status=status.HTTP_400_BAD_REQUEST,
raise APIError(
_('count cannot be less than or equal to zero'),
err_class='count cannot be less than or equal to zero',
http_status=status.HTTP_400_BAD_REQUEST,
)
to_cancel_booking = None
@ -764,13 +755,10 @@ class Fillslots(APIView):
try:
cancel_booking_id = int(payload.get('cancel_booking_id'))
except (ValueError, TypeError):
return Response(
{
'err': 1,
'err_class': 'cancel_booking_id is not an integer',
'err_desc': _('cancel_booking_id is not an integer'),
},
status=status.HTTP_400_BAD_REQUEST,
raise APIError(
_('cancel_booking_id is not an integer'),
err_class='cancel_booking_id is not an integer',
http_status=status.HTTP_400_BAD_REQUEST,
)
if cancel_booking_id is not None:
@ -790,7 +778,7 @@ class Fillslots(APIView):
cancel_error = gettext_noop('cancel booking: booking does no exist')
if cancel_error:
return Response({'err': 1, 'err_class': cancel_error, 'err_desc': _(cancel_error)})
raise APIError(_(cancel_error), err_class=cancel_error)
extra_data = {}
for k, v in request.data.items():
@ -808,24 +796,16 @@ class Fillslots(APIView):
try:
meeting_type_id_, datetime_str = slot.split(':')
except ValueError:
return Response(
{
'err': 1,
'err_class': 'invalid slot: %s' % slot,
'err_desc': _('invalid slot: %s') % slot,
},
status=status.HTTP_400_BAD_REQUEST,
raise APIError(
_('invalid slot: %s') % slot,
err_class='invalid slot: %s' % slot,
http_status=status.HTTP_400_BAD_REQUEST,
)
if meeting_type_id_ != meeting_type_id:
return Response(
{
'err': 1,
'err_class': 'all slots must have the same meeting type id (%s)'
% meeting_type_id,
'err_desc': _('all slots must have the same meeting type id (%s)')
% meeting_type_id,
},
status=status.HTTP_400_BAD_REQUEST,
raise APIError(
_('all slots must have the same meeting type id (%s)') % meeting_type_id,
err_class='all slots must have the same meeting type id (%s)' % meeting_type_id,
http_status=status.HTTP_400_BAD_REQUEST,
)
datetimes.add(make_aware(datetime.datetime.strptime(datetime_str, '%Y-%m-%d-%H%M')))
@ -842,13 +822,10 @@ class Fillslots(APIView):
# legacy access by id
meeting_type = agenda.get_meetingtype(id_=meeting_type_id)
except (MeetingType.DoesNotExist, ValueError):
return Response(
{
'err': 1,
'err_class': 'invalid meeting type id: %s' % meeting_type_id,
'err_desc': _('invalid meeting type id: %s') % meeting_type_id,
},
status=status.HTTP_400_BAD_REQUEST,
raise APIError(
_('invalid meeting type id: %s') % meeting_type_id,
err_class='invalid meeting type id: %s' % meeting_type_id,
http_status=status.HTTP_400_BAD_REQUEST,
)
all_slots = sorted(
get_all_slots(agenda, meeting_type, resources=resources),
@ -908,12 +885,8 @@ class Fillslots(APIView):
break
if available_desk is None:
return Response(
{
'err': 1,
'err_class': 'no more desk available',
'err_desc': _('no more desk available'),
}
raise APIError(
_('no more desk available'), err_class='no more desk available',
)
# all datetimes are free, book them in order
@ -948,29 +921,24 @@ class Fillslots(APIView):
for event in events:
if not event.in_bookable_period():
return Response(
{'err': 1, 'err_class': 'event not bookable', 'err_desc': _('event not bookable')}
)
raise APIError(_('event not bookable'), err_class='event not bookable')
if event.cancelled:
return Response(
{'err': 1, 'err_class': 'event is cancelled', 'err_desc': _('event is cancelled')}
)
raise APIError(_('event is cancelled'), err_class='event is cancelled')
if not events.count():
return Response(
{
'err': 1,
'err_class': 'unknown event identifiers or slugs',
'err_desc': _('unknown event identifiers or slugs'),
},
status=status.HTTP_400_BAD_REQUEST,
raise APIError(
_('unknown event identifiers or slugs'),
err_class='unknown event identifiers or slugs',
http_status=status.HTTP_400_BAD_REQUEST,
)
# search free places. Switch to waiting list if necessary.
in_waiting_list = False
for event in events:
if payload.get('force_waiting_list') and not event.waiting_list_places:
return Response({'err': 1, 'err_class': 'no waiting list', 'err_desc': _('no waiting list')})
raise APIError(
_('no waiting list'), err_class='no waiting list',
)
if event.waiting_list_places:
if (
@ -982,10 +950,14 @@ class Fillslots(APIView):
# in the waiting list.
in_waiting_list = True
if (event.waiting_list + places_count) > event.waiting_list_places:
return Response({'err': 1, 'err_class': 'sold out', 'err_desc': _('sold out')})
raise APIError(
_('sold out'), err_class='sold out',
)
else:
if (event.booked_places + places_count) > event.places:
return Response({'err': 1, 'err_class': 'sold out', 'err_desc': _('sold out')})
raise APIError(
_('sold out'), err_class='sold out',
)
with transaction.atomic():
if to_cancel_booking:
@ -1081,12 +1053,15 @@ class Fillslot(Fillslots):
serializer_class = SlotSerializer
def post(self, request, agenda_identifier=None, event_identifier=None, format=None):
return self.fillslot(
request=request,
agenda_identifier=agenda_identifier,
slots=[event_identifier], # fill a "list on one slot"
format=format,
)
try:
return self.fillslot(
request=request,
agenda_identifier=agenda_identifier,
slots=[event_identifier], # fill a "list on one slot"
format=format,
)
except APIError as e:
return e.to_response()
fillslot = Fillslot.as_view()