api: show events out of minimal delay (#58286)

This commit is contained in:
Lauréline Guérin 2021-10-29 15:22:04 +02:00
parent b8c611e3df
commit 629b512836
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
5 changed files with 63 additions and 7 deletions

View File

@ -600,7 +600,7 @@ class Agenda(models.Model):
for weektime_interval in IntervalSet.simple(*time_period_interval) - closed_hours_by_days:
yield SharedTimePeriod.from_weektime_interval(weektime_interval, desks=desks)
@property
@functional.cached_property
def max_booking_datetime(self):
if self.maximal_booking_delay is None:
return None
@ -618,7 +618,7 @@ class Agenda(models.Model):
t = t.replace(hour=0, minute=0, second=0, microsecond=0)
return localtime(t)
@property
@functional.cached_property
def min_booking_datetime(self):
if self.minimal_booking_delay is None:
return None
@ -651,6 +651,7 @@ class Agenda(models.Model):
max_start=None,
user_external_id=None,
bypass_delays=False,
show_out_of_minimal_delay=False,
):
assert self.kind == 'events'
@ -672,7 +673,7 @@ class Agenda(models.Model):
if not include_full:
entries = entries.filter(Q(full=False) | Q(primary_event__isnull=False))
if not bypass_delays and self.minimal_booking_delay:
if not bypass_delays and not show_out_of_minimal_delay and self.minimal_booking_delay:
min_start = max(self.min_booking_datetime, min_start) if min_start else self.min_booking_datetime
if min_start:

View File

@ -421,7 +421,7 @@ def get_event_places(event):
return places
def is_event_disabled(event, min_places=1, disable_booked=True, bookable_events=None):
def is_event_disabled(event, min_places=1, disable_booked=True, bookable_events=None, bypass_delays=False):
if disable_booked and getattr(event, 'user_places_count', 0) > 0:
return True
if event.start_datetime < now():
@ -431,6 +431,13 @@ def is_event_disabled(event, min_places=1, disable_booked=True, bookable_events=
return False
# we just want to show past events, but they are not bookable
return True
elif (
not bypass_delays
and event.agenda.min_booking_datetime
and event.start_datetime < event.agenda.min_booking_datetime
):
# 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:
return True
return False
@ -467,6 +474,7 @@ def get_event_detail(
bookable_events=None,
multiple_agendas=False,
disable_booked=True,
bypass_delays=False,
):
agenda = agenda or event.agenda
details = {
@ -497,6 +505,7 @@ def get_event_detail(
min_places=min_places,
disable_booked=disable_booked,
bookable_events=bookable_events,
bypass_delays=bypass_delays,
),
'api': {
'bookings_url': request.build_absolute_uri(
@ -539,14 +548,22 @@ def get_event_detail(
def get_events_meta_detail(
request, events, agenda=None, min_places=1, bookable_events=None, multiple_agendas=False
request,
events,
agenda=None,
min_places=1,
bookable_events=None,
multiple_agendas=False,
bypass_delays=False,
):
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 is_event_disabled(event, min_places=min_places, bookable_events=bookable_events):
if not is_event_disabled(
event, min_places=min_places, bookable_events=bookable_events, bypass_delays=bypass_delays
):
bookable_datetimes_number_available += 1
if not first_bookable_slot:
first_bookable_slot = get_event_detail(
@ -556,6 +573,7 @@ def get_events_meta_detail(
min_places=min_places,
bookable_events=bookable_events,
multiple_agendas=multiple_agendas,
bypass_delays=bypass_delays,
)
return {
'no_bookable_datetimes': bool(bookable_datetimes_number_available == 0),
@ -838,7 +856,11 @@ class Datetimes(APIView):
e
for e in entries
if not is_event_disabled(
e, payload['min_places'], disable_booked=disable_booked, bookable_events=bookable_events
e,
payload['min_places'],
disable_booked=disable_booked,
bookable_events=bookable_events,
bypass_delays=payload.get('bypass_delays'),
)
]
@ -852,6 +874,7 @@ class Datetimes(APIView):
booked_user_external_id=payload.get('user_external_id'),
bookable_events=bookable_events_raw,
disable_booked=disable_booked,
bypass_delays=payload.get('bypass_delays'),
)
for x in entries
],
@ -914,6 +937,7 @@ class MultipleAgendasDatetimes(APIView):
min_start=payload.get('date_start'),
max_start=payload.get('date_end'),
bypass_delays=payload.get('bypass_delays'),
show_out_of_minimal_delay=show_past_events,
)
)
@ -929,6 +953,7 @@ class MultipleAgendasDatetimes(APIView):
booked_user_external_id=payload.get('user_external_id'),
multiple_agendas=True,
disable_booked=disable_booked,
bypass_delays=payload.get('bypass_delays'),
)
for x in entries
],

View File

@ -253,6 +253,7 @@ def test_agendas_api(app):
assert event3.full is False
event_agenda.maximal_booking_delay = 12
event_agenda.save()
del event_agenda.max_booking_datetime
assert list(event_agenda.get_open_events()) == [event2]
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
assert len(resp.json['data']) == 0
@ -468,6 +469,7 @@ def test_agenda_detail_api(app):
assert event3.full is False
agenda.maximal_booking_delay = 12
agenda.save()
del agenda.max_booking_datetime
resp = app.get('/api/agenda/%s/' % agenda.slug)
assert list(agenda.get_open_events()) == [event2]
assert resp.json['data']['opened_events_available'] is False

View File

@ -694,15 +694,19 @@ def test_recurring_events_api(app, user, freezer):
# check delays
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(resp.json['data']) == 4
assert [e['disabled'] for e in resp.json['data']] == [False] * 4
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'bypass_delays': True})
assert len(resp.json['data']) == 53
assert [e['disabled'] for e in resp.json['data']] == [False] * 53
agenda.minimal_booking_delay = 10
agenda.mmaximal_booking_delay = 20
agenda.save()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(resp.json['data']) == 3
assert [e['disabled'] for e in resp.json['data']] == [False] * 3
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'bypass_delays': True})
assert len(resp.json['data']) == 53
assert [e['disabled'] for e in resp.json['data']] == [False] * 53
def test_recurring_events_api_various_times(app, user, mock_now):
@ -1562,11 +1566,20 @@ def test_datetimes_multiple_agendas(app):
date_end = localtime() + datetime.timedelta(days=60) # with a date end to have recurring events
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'date_end': date_end})
assert len(resp.json['data']) == 2
assert [d['disabled'] for d in resp.json['data']] == [False, False]
assert resp.json['data'][0]['id'] == 'second-agenda@event'
assert resp.json['data'][1]['id'] == 'first-agenda@recurring:2021-05-13-1700'
resp = app.get(
'/api/agendas/datetimes/',
params={'agendas': agenda_slugs, 'date_end': date_end, 'bypass_delays': True},
)
assert len(resp.json['data']) == 5
assert resp.json['data'][0]['id'] == 'first-agenda@recurring:2021-05-06-1700'
assert resp.json['data'][1]['id'] == 'first-agenda@event'
assert resp.json['data'][2]['id'] == 'second-agenda@event'
assert resp.json['data'][3]['id'] == 'first-agenda@recurring:2021-05-13-1700'
assert resp.json['data'][4]['id'] == 'first-agenda@recurring:2021-05-20-1700'
assert [d['disabled'] for d in resp.json['data']] == [False, False, False, False, False]
Agenda.objects.update(minimal_booking_delay=0, maximal_booking_delay=45)
# invalid slugs
@ -1584,6 +1597,18 @@ def test_datetimes_multiple_agendas(app):
assert resp.json['data'][2]['id'] == 'second-agenda@event'
assert resp.json['data'][3]['id'] == 'first-agenda@recurring:2021-05-13-1700'
assert resp.json['data'][4]['id'] == 'first-agenda@recurring:2021-05-20-1700'
assert [d['disabled'] for d in resp.json['data']] == [False, False, False, False, False]
# and events out of minimal_booking_delay
Agenda.objects.update(minimal_booking_delay=6, maximal_booking_delay=14)
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'show_past_events': True})
assert len(resp.json['data']) == 4
assert resp.json['data'][0]['id'] == 'first-agenda@recurring:2021-05-06-1700'
assert resp.json['data'][1]['id'] == 'first-agenda@event'
assert resp.json['data'][2]['id'] == 'second-agenda@event'
assert resp.json['data'][3]['id'] == 'first-agenda@recurring:2021-05-13-1700'
assert [d['disabled'] for d in resp.json['data']] == [True, True, False, False]
Agenda.objects.update(minimal_booking_delay=0, maximal_booking_delay=45)
Event.objects.create(
slug='event-in-past',

View File

@ -206,14 +206,17 @@ def test_agenda_minimal_booking_delay_in_working_days(settings):
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10)
agenda.minimal_booking_delay_in_working_days = False
agenda.save()
del agenda.min_booking_datetime
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10)
settings.WORKING_DAY_CALENDAR = 'workalendar.europe.France'
agenda.minimal_booking_delay_in_working_days = True
agenda.save()
del agenda.min_booking_datetime
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 12)
agenda.minimal_booking_delay_in_working_days = False
agenda.save()
del agenda.min_booking_datetime
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10)