api: allow passing minimum places count in /datetimes/ (#51172)
This commit is contained in:
parent
9954337197
commit
929f70d2ac
|
@ -344,7 +344,7 @@ def get_event_places(event):
|
|||
return places
|
||||
|
||||
|
||||
def get_event_detail(request, event, agenda=None):
|
||||
def get_event_detail(request, event, agenda=None, min_places=1):
|
||||
agenda = agenda or event.agenda
|
||||
if event.label and event.primary_event is not None:
|
||||
event.label = '%s (%s)' % (
|
||||
|
@ -359,7 +359,9 @@ def get_event_detail(request, event, agenda=None):
|
|||
'description': event.description,
|
||||
'pricing': event.pricing,
|
||||
'url': event.url,
|
||||
'disabled': bool(event.full),
|
||||
'disabled': bool(
|
||||
event.remaining_places < min_places and event.remaining_waiting_list_places < min_places
|
||||
),
|
||||
'api': {
|
||||
'bookings_url': request.build_absolute_uri(
|
||||
reverse(
|
||||
|
@ -384,16 +386,16 @@ def get_event_detail(request, event, agenda=None):
|
|||
}
|
||||
|
||||
|
||||
def get_events_meta_detail(request, events, agenda=None):
|
||||
def get_events_meta_detail(request, events, agenda=None, min_places=1):
|
||||
bookable_datetimes_number_total = 0
|
||||
bookable_datetimes_number_available = 0
|
||||
first_bookable_slot = None
|
||||
for event in events:
|
||||
bookable_datetimes_number_total += 1
|
||||
if not bool(event.full):
|
||||
if bool(event.remaining_places >= min_places or event.remaining_waiting_list_places >= min_places):
|
||||
bookable_datetimes_number_available += 1
|
||||
if not first_bookable_slot:
|
||||
first_bookable_slot = get_event_detail(request, event, agenda=agenda)
|
||||
first_bookable_slot = get_event_detail(request, event, agenda=agenda, min_places=min_places)
|
||||
return {
|
||||
'no_bookable_datetimes': bool(bookable_datetimes_number_available == 0),
|
||||
'bookable_datetimes_number_total': bookable_datetimes_number_total,
|
||||
|
@ -531,6 +533,15 @@ class Datetimes(APIView):
|
|||
if agenda.kind != 'events':
|
||||
raise Http404('agenda found, but it was not an events agenda')
|
||||
|
||||
try:
|
||||
min_places = int(request.GET.get('min_places', 1))
|
||||
except ValueError:
|
||||
raise APIError(
|
||||
_('min_places must be a number'),
|
||||
err_class='min_places must be a number',
|
||||
http_status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
date_start, date_end = request.GET.get('date_start'), request.GET.get('date_end')
|
||||
if date_start:
|
||||
try:
|
||||
|
@ -556,8 +567,8 @@ class Datetimes(APIView):
|
|||
entries = agenda.get_open_events(annotate_queryset=True, min_start=date_start, max_start=date_end)
|
||||
|
||||
response = {
|
||||
'data': [get_event_detail(request, x, agenda=agenda) for x in entries],
|
||||
'meta': get_events_meta_detail(request, entries, agenda=agenda),
|
||||
'data': [get_event_detail(request, x, agenda=agenda, min_places=min_places) for x in entries],
|
||||
'meta': get_events_meta_detail(request, entries, agenda=agenda, min_places=min_places),
|
||||
}
|
||||
return Response(response)
|
||||
|
||||
|
|
|
@ -491,6 +491,27 @@ def test_datetime_api_urls(app):
|
|||
)
|
||||
|
||||
|
||||
def test_datetime_api_min_places(app):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
event = Event.objects.create(start_datetime=now() + datetime.timedelta(days=7), places=5, agenda=agenda)
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
|
||||
assert not resp.json['data'][0]['disabled']
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/?min_places=5' % agenda.slug)
|
||||
assert not resp.json['data'][0]['disabled']
|
||||
|
||||
Booking.objects.create(event=event)
|
||||
resp = app.get('/api/agenda/%s/datetimes/?min_places=5' % agenda.slug)
|
||||
assert resp.json['data'][0]['disabled']
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/?min_places=wrong' % agenda.slug, status=400)
|
||||
assert resp.json['err'] == 1
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/?min_places=' % agenda.slug, status=400)
|
||||
assert resp.json['err'] == 1
|
||||
|
||||
|
||||
def test_datetimes_api_meetings_agenda(app, meetings_agenda):
|
||||
meeting_type = MeetingType.objects.get(agenda=meetings_agenda)
|
||||
api_url = '/api/agenda/%s/meetings/%s/datetimes/' % (meeting_type.agenda.slug, meeting_type.slug)
|
||||
|
@ -5151,6 +5172,15 @@ def test_datetimes_api_meta(app, freezer):
|
|||
'first_bookable_slot': resp.json['data'][0],
|
||||
}
|
||||
|
||||
resp = app.get(api_url + '?min_places=11')
|
||||
assert len(resp.json['data']) == 3
|
||||
assert resp.json['meta'] == {
|
||||
'no_bookable_datetimes': False,
|
||||
'bookable_datetimes_number_total': 3,
|
||||
'bookable_datetimes_number_available': 2,
|
||||
'first_bookable_slot': resp.json['data'][1],
|
||||
}
|
||||
|
||||
simulate_booking(events[0], 10)
|
||||
resp = app.get(api_url)
|
||||
assert len(resp.json['data']) == 3
|
||||
|
|
Loading…
Reference in New Issue