api: return opened_events_available in events agenda detail payload

(#43937)
This commit is contained in:
Lauréline Guérin 2020-06-12 16:12:58 +02:00
parent 1a25cb6ac9
commit c77edebd62
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 82 additions and 27 deletions

View File

@ -363,6 +363,30 @@ 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)
def get_opened_events(self):
assert self.kind == 'events'
entries = self.event_set.all()
# we never want to allow booking for past events.
entries = entries.filter(start_datetime__gte=localtime(now()))
# exclude non published events
entries = entries.filter(
Q(publication_date__isnull=True) | Q(publication_date__lte=localtime(now()).date())
)
if self.minimal_booking_delay:
entries = entries.filter(
start_datetime__gte=localtime(
now() + datetime.timedelta(days=self.minimal_booking_delay)
).replace(hour=0, minute=0)
)
if self.maximal_booking_delay:
entries = entries.filter(
start_datetime__lt=localtime(
now() + datetime.timedelta(days=self.maximal_booking_delay)
).replace(hour=0, minute=0)
)
return entries
class VirtualMember(models.Model):
'''Trough model to link virtual agendas to their real agendas.

View File

@ -273,7 +273,7 @@ def get_all_slots(base_agenda, meeting_type, resources=None, unique=False):
break
def get_agenda_detail(request, agenda):
def get_agenda_detail(request, agenda, check_events=False):
agenda_detail = {
'id': agenda.slug,
'slug': agenda.slug, # kept for compatibility
@ -293,6 +293,8 @@ def get_agenda_detail(request, agenda):
reverse('api-agenda-datetimes', kwargs={'agenda_identifier': agenda.slug})
)
}
if check_events:
agenda_detail['opened_events_available'] = agenda.get_opened_events().filter(full=False).exists()
elif agenda.accept_meetings():
agenda_detail['api'] = {
'meetings_url': request.build_absolute_uri(
@ -370,7 +372,7 @@ class AgendaDetail(APIView):
def get(self, request, agenda_identifier):
agenda = get_object_or_404(Agenda, slug=agenda_identifier)
return Response({'data': get_agenda_detail(request, agenda)})
return Response({'data': get_agenda_detail(request, agenda, check_events=True)})
agenda_detail = AgendaDetail.as_view()
@ -391,29 +393,7 @@ class Datetimes(APIView):
if agenda.kind != 'events':
raise Http404('agenda found, but it was not an events agenda')
entries = Event.objects.filter(agenda=agenda)
# we never want to allow booking for past events.
entries = entries.filter(start_datetime__gte=localtime(now()))
# exclude non published events
entries = entries.filter(
Q(publication_date__isnull=True) | Q(publication_date__lte=localtime(now()).date())
)
if agenda.minimal_booking_delay:
entries = entries.filter(
start_datetime__gte=localtime(
now() + datetime.timedelta(days=agenda.minimal_booking_delay)
).replace(hour=0, minute=0)
)
if agenda.maximal_booking_delay:
entries = entries.filter(
start_datetime__lt=localtime(
now() + datetime.timedelta(days=agenda.maximal_booking_delay)
).replace(hour=0, minute=0)
)
entries = agenda.get_opened_events()
if 'date_start' in request.GET:
entries = entries.filter(

View File

@ -2311,16 +2311,67 @@ def test_multiple_booking_move_booking(app, user):
assert Event.objects.get(id=event.id).booked_places == 1
def test_agenda_detail_api(app, some_data):
agenda = Agenda.objects.get(slug='foo-bar')
def test_agenda_detail_api(app):
agenda = Agenda.objects.create(label='Foo bar', kind='events', minimal_booking_delay=0)
first_date = localtime(now()).replace(hour=17, minute=0, second=0, microsecond=0)
first_date += datetime.timedelta(days=1)
event1 = Event.objects.create(
start_datetime=(now() + datetime.timedelta(days=5)).replace(hour=10, minute=0),
places=20,
agenda=agenda,
)
event2 = Event.objects.create(
start_datetime=(now() + datetime.timedelta(days=10)).replace(hour=10, minute=0),
places=20,
agenda=agenda,
)
event3 = Event.objects.create(
start_datetime=(now() + datetime.timedelta(days=15)).replace(hour=10, minute=0),
places=20,
agenda=agenda,
)
resp = app.get('/api/agenda/%s/' % agenda.slug)
data = resp.json['data']
assert data['id'] == 'foo-bar'
assert data['slug'] == 'foo-bar'
assert data['text'] == 'Foo bar'
assert data['kind'] == 'events'
assert data['opened_events_available'] is True
assert data['api']['datetimes_url'] == 'http://testserver/api/agenda/foo-bar/datetimes/'
# one event is full
Event.objects.filter(pk=event1.pk).update(full=True)
resp = app.get('/api/agenda/%s/' % agenda.slug)
assert resp.json['data']['opened_events_available'] is True
# all events are full
Event.objects.update(full=True)
resp = app.get('/api/agenda/%s/' % agenda.slug)
assert resp.json['data']['opened_events_available'] is False
# event1 is not full but too soon
Event.objects.filter(pk=event1.pk).update(full=False)
agenda.minimal_booking_delay = 10
agenda.save()
resp = app.get('/api/agenda/%s/' % agenda.slug)
assert list(agenda.get_opened_events()) == [event2, event3]
assert resp.json['data']['opened_events_available'] is False
# event3 is not full but too late
Event.objects.filter(pk=event3.pk).update(full=False)
agenda.maximal_booking_delay = 12
agenda.save()
resp = app.get('/api/agenda/%s/' % agenda.slug)
assert list(agenda.get_opened_events()) == [event2]
assert resp.json['data']['opened_events_available'] is False
# events are not full but not published
Event.objects.update(full=False)
agenda.event_set.update(publication_date=now().date() + datetime.timedelta(days=20))
resp = app.get('/api/agenda/%s/' % agenda.slug)
assert list(agenda.get_opened_events()) == []
assert resp.json['data']['opened_events_available'] is False
# unknown
app.get('/api/agenda/whatever/', status=404)