api: add 'max_places' argument to API (#89848)
gitea/chrono/pipeline/head This commit looks good
Details
gitea/chrono/pipeline/head This commit looks good
Details
This commit is contained in:
parent
88d8feacd8
commit
ece23b6d89
|
@ -467,6 +467,7 @@ class DateRangeSerializer(DateRangeMixin, serializers.Serializer):
|
|||
|
||||
class DatetimesSerializer(DateRangeSerializer):
|
||||
min_places = serializers.IntegerField(min_value=1, default=1)
|
||||
max_places = serializers.IntegerField(min_value=0, default=0)
|
||||
user_external_id = serializers.CharField(required=False, max_length=250, allow_blank=True)
|
||||
exclude_user_external_id = serializers.CharField(required=False, max_length=250, allow_blank=True)
|
||||
events = serializers.CharField(required=False, max_length=32, allow_blank=True)
|
||||
|
|
|
@ -149,6 +149,7 @@ def get_event_places(event):
|
|||
def is_event_disabled(
|
||||
event,
|
||||
min_places=1,
|
||||
max_places=0,
|
||||
disable_booked=True,
|
||||
bookable_events=None,
|
||||
bypass_delays=False,
|
||||
|
@ -170,7 +171,9 @@ def is_event_disabled(
|
|||
):
|
||||
# event is out of minimal delay and we don't want to bypass delays
|
||||
return True
|
||||
if event.remaining_places < min_places and event.remaining_waiting_list_places < min_places:
|
||||
if 0 < max_places <= event.remaining_places:
|
||||
return True
|
||||
elif event.remaining_places < min_places and event.remaining_waiting_list_places < min_places:
|
||||
if enable_full_when_booked and getattr(event, 'user_places_count', 0) > 0:
|
||||
return False
|
||||
return True
|
||||
|
@ -210,6 +213,7 @@ def get_event_detail(
|
|||
booking=None,
|
||||
agenda=None,
|
||||
min_places=1,
|
||||
max_places=0,
|
||||
booked_user_external_id=None,
|
||||
bookable_events=None,
|
||||
multiple_agendas=False,
|
||||
|
@ -264,6 +268,7 @@ def get_event_detail(
|
|||
'disabled': is_event_disabled(
|
||||
event,
|
||||
min_places=min_places,
|
||||
max_places=max_places,
|
||||
disable_booked=disable_booked,
|
||||
bookable_events=bookable_events,
|
||||
bypass_delays=bypass_delays,
|
||||
|
@ -363,6 +368,7 @@ def get_events_meta_detail(
|
|||
events,
|
||||
agenda=None,
|
||||
min_places=1,
|
||||
max_places=0,
|
||||
bookable_events=None,
|
||||
multiple_agendas=False,
|
||||
bypass_delays=False,
|
||||
|
@ -373,7 +379,11 @@ def get_events_meta_detail(
|
|||
for event in events:
|
||||
bookable_datetimes_number_total += 1
|
||||
if not is_event_disabled(
|
||||
event, min_places=min_places, bookable_events=bookable_events, bypass_delays=bypass_delays
|
||||
event,
|
||||
min_places=min_places,
|
||||
max_places=max_places,
|
||||
bookable_events=bookable_events,
|
||||
bypass_delays=bypass_delays,
|
||||
):
|
||||
bookable_datetimes_number_available += 1
|
||||
if not first_bookable_slot:
|
||||
|
@ -382,6 +392,7 @@ def get_events_meta_detail(
|
|||
event,
|
||||
agenda=agenda,
|
||||
min_places=min_places,
|
||||
max_places=max_places,
|
||||
bookable_events=bookable_events,
|
||||
multiple_agendas=multiple_agendas,
|
||||
bypass_delays=bypass_delays,
|
||||
|
@ -680,7 +691,8 @@ class Datetimes(APIView):
|
|||
for e in entries
|
||||
if not is_event_disabled(
|
||||
e,
|
||||
payload['min_places'],
|
||||
min_places=payload['min_places'],
|
||||
max_places=payload['max_places'],
|
||||
disable_booked=disable_booked,
|
||||
bookable_events=bookable_events,
|
||||
bypass_delays=payload.get('bypass_delays'),
|
||||
|
@ -694,6 +706,7 @@ class Datetimes(APIView):
|
|||
x,
|
||||
agenda=agenda,
|
||||
min_places=payload['min_places'],
|
||||
max_places=payload['max_places'],
|
||||
booked_user_external_id=payload.get('user_external_id'),
|
||||
bookable_events=bookable_events_raw,
|
||||
disable_booked=disable_booked,
|
||||
|
@ -706,6 +719,7 @@ class Datetimes(APIView):
|
|||
entries,
|
||||
agenda=agenda,
|
||||
min_places=payload['min_places'],
|
||||
max_places=payload['max_places'],
|
||||
bookable_events=bookable_events_raw,
|
||||
),
|
||||
}
|
||||
|
@ -803,6 +817,7 @@ class MultipleAgendasDatetimes(APIView):
|
|||
request,
|
||||
x,
|
||||
min_places=payload['min_places'],
|
||||
max_places=payload['max_places'],
|
||||
booked_user_external_id=payload.get('user_external_id'),
|
||||
multiple_agendas=True,
|
||||
disable_booked=disable_booked,
|
||||
|
@ -813,7 +828,11 @@ class MultipleAgendasDatetimes(APIView):
|
|||
for x in entries
|
||||
],
|
||||
'meta': get_events_meta_detail(
|
||||
request, entries, min_places=payload['min_places'], multiple_agendas=True
|
||||
request,
|
||||
entries,
|
||||
min_places=payload['min_places'],
|
||||
max_places=payload['max_places'],
|
||||
multiple_agendas=True,
|
||||
),
|
||||
}
|
||||
return Response(response)
|
||||
|
|
|
@ -198,7 +198,7 @@ def test_datetime_api_backoffice_url(app, admin_user):
|
|||
assert event.label in app.get(url).text
|
||||
|
||||
|
||||
def test_datetimes_api_min_places(app):
|
||||
def test_datetimes_api_min_max_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)
|
||||
|
||||
|
@ -212,12 +212,30 @@ def test_datetimes_api_min_places(app):
|
|||
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/?max_places=4' % agenda.slug)
|
||||
assert resp.json['data'][0]['disabled']
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/?max_places=5' % agenda.slug)
|
||||
assert not resp.json['data'][0]['disabled']
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/?max_places=10&min_places=2' % agenda.slug)
|
||||
assert not resp.json['data'][0]['disabled']
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/?min_places=' % agenda.slug)
|
||||
assert not resp.json['data'][0]['disabled']
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/?max_places=' % agenda.slug)
|
||||
assert not resp.json['data'][0]['disabled']
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/?max_places=&min_places=' % agenda.slug)
|
||||
assert not 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/?max_places=wrong' % agenda.slug, status=400)
|
||||
assert resp.json['err'] == 1
|
||||
|
||||
|
||||
def test_datetimes_api_(app):
|
||||
events_type = EventsType.objects.create(
|
||||
|
@ -634,6 +652,15 @@ def test_datetimes_api_meta(app, freezer):
|
|||
'first_bookable_slot': resp.json['data'][1],
|
||||
}
|
||||
|
||||
resp = app.get(api_url + '?max_places=15')
|
||||
assert len(resp.json['data']) == 3
|
||||
assert resp.json['meta'] == {
|
||||
'no_bookable_datetimes': False,
|
||||
'bookable_datetimes_number_total': 3,
|
||||
'bookable_datetimes_number_available': 1,
|
||||
'first_bookable_slot': resp.json['data'][0],
|
||||
}
|
||||
|
||||
simulate_booking(events[0], 10)
|
||||
resp = app.get(api_url)
|
||||
assert len(resp.json['data']) == 3
|
||||
|
@ -1161,30 +1188,43 @@ def test_past_datetimes_places(app, user):
|
|||
assert resp.json['meta']['first_bookable_slot']['id'] == 'today-before-now'
|
||||
|
||||
|
||||
def test_past_datetimes_min_places(app, user):
|
||||
def test_past_datetimes_min_max_places(app, user):
|
||||
agenda = Agenda.objects.create(
|
||||
label='Foo bar', kind='events', minimal_booking_delay=0, maximal_booking_delay=30
|
||||
)
|
||||
Event.objects.create(
|
||||
label='Today before now',
|
||||
start_datetime=localtime(now() - datetime.timedelta(hours=1)),
|
||||
places=1,
|
||||
places=10,
|
||||
agenda=agenda,
|
||||
)
|
||||
Event.objects.create(
|
||||
label='Today after now',
|
||||
start_datetime=localtime(now() + datetime.timedelta(hours=1)),
|
||||
places=1,
|
||||
places=10,
|
||||
agenda=agenda,
|
||||
)
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'events': 'future', 'min_places': 2})
|
||||
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'events': 'future', 'min_places': 20})
|
||||
data = resp.json['data']
|
||||
assert len(data) == 1
|
||||
assert data[0]['id'] == 'today-after-now'
|
||||
assert data[0]['disabled'] is True
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'events': 'past', 'min_places': 2})
|
||||
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'events': 'past', 'min_places': 20})
|
||||
data = resp.json['data']
|
||||
assert len(data) == 1
|
||||
assert data[0]['id'] == 'today-before-now'
|
||||
assert data[0]['disabled'] is False # always available if past
|
||||
assert resp.json['meta']['first_bookable_slot']['id'] == 'today-before-now'
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'events': 'future', 'max_places': 5})
|
||||
data = resp.json['data']
|
||||
assert len(data) == 1
|
||||
assert data[0]['id'] == 'today-after-now'
|
||||
assert data[0]['disabled'] is True
|
||||
|
||||
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'events': 'past', 'max_places': 5})
|
||||
data = resp.json['data']
|
||||
assert len(data) == 1
|
||||
assert data[0]['id'] == 'today-before-now'
|
||||
|
|
|
@ -104,13 +104,27 @@ def test_datetimes_multiple_agendas(app):
|
|||
assert 'booked_for_external_user' not in resp.json['data'][2]
|
||||
assert resp.json['data'][2]['disabled'] is True
|
||||
|
||||
# check min_places
|
||||
# check min_places & max_places
|
||||
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'min_places': 4})
|
||||
assert resp.json['data'][1]['disabled'] is False
|
||||
assert resp.json['data'][2]['disabled'] is True
|
||||
|
||||
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'max_places': 3})
|
||||
assert resp.json['data'][1]['disabled'] is True
|
||||
assert resp.json['data'][2]['disabled'] is True
|
||||
|
||||
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'max_places': 4})
|
||||
assert resp.json['data'][1]['disabled'] is True
|
||||
assert resp.json['data'][2]['disabled'] is False
|
||||
|
||||
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'max_places': 10})
|
||||
assert resp.json['data'][1]['disabled'] is False
|
||||
assert resp.json['data'][2]['disabled'] is False
|
||||
|
||||
# check meta
|
||||
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'min_places': 4})
|
||||
resp = app.get(
|
||||
'/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'min_places': 4, 'max_places': 10}
|
||||
)
|
||||
assert resp.json['meta']['bookable_datetimes_number_total'] == 5
|
||||
assert resp.json['meta']['bookable_datetimes_number_available'] == 4
|
||||
assert resp.json['meta']['first_bookable_slot'] == resp.json['data'][0]
|
||||
|
|
Loading…
Reference in New Issue