api: return only agenda with open events (#44294)
This commit is contained in:
parent
6fdb1bf4c5
commit
eb8026c790
|
@ -462,29 +462,36 @@ 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_open_events(self):
|
||||
def get_open_events(self, prefetched_queryset=False):
|
||||
assert self.kind == 'events'
|
||||
|
||||
entries = self.event_set.all()
|
||||
entries = self.event_set.filter(cancelled=False)
|
||||
# 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 prefetched_queryset:
|
||||
entries = self.prefetched_events
|
||||
else:
|
||||
entries = self.event_set.filter(cancelled=False)
|
||||
# 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)
|
||||
min_start = localtime(now() + datetime.timedelta(days=self.minimal_booking_delay)).replace(
|
||||
hour=0, minute=0
|
||||
)
|
||||
if prefetched_queryset:
|
||||
entries = [e for e in entries if e.start_datetime >= min_start]
|
||||
else:
|
||||
entries = entries.filter(start_datetime__gte=min_start)
|
||||
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)
|
||||
max_start = localtime(now() + datetime.timedelta(days=self.maximal_booking_delay)).replace(
|
||||
hour=0, minute=0
|
||||
)
|
||||
if prefetched_queryset:
|
||||
entries = [e for e in entries if e.start_datetime < max_start]
|
||||
else:
|
||||
entries = entries.filter(start_datetime__lt=max_start)
|
||||
return entries
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import uuid
|
|||
|
||||
|
||||
from django.db import transaction
|
||||
from django.db.models import Prefetch, Q
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.urls import reverse
|
||||
|
@ -349,11 +350,33 @@ class Agendas(APIView):
|
|||
|
||||
def get(self, request, format=None):
|
||||
agendas_queryset = Agenda.objects.all().prefetch_related('resources').order_by('label')
|
||||
|
||||
if 'q' in request.GET:
|
||||
if not request.GET['q']:
|
||||
return Response({'data': []})
|
||||
agendas_queryset = agendas_queryset.filter(slug__icontains=request.GET['q'])
|
||||
agendas = [get_agenda_detail(request, agenda) for agenda in agendas_queryset]
|
||||
|
||||
with_open_events = request.GET.get('with_open_events') in ['1', 'true']
|
||||
if with_open_events:
|
||||
# return only events agenda
|
||||
event_queryset = Event.objects.filter(
|
||||
Q(publication_date__isnull=True) | Q(publication_date__lte=localtime(now()).date()),
|
||||
cancelled=False,
|
||||
start_datetime__gte=localtime(now()),
|
||||
).order_by()
|
||||
agendas_queryset = agendas_queryset.filter(kind='events').prefetch_related(
|
||||
Prefetch('event_set', queryset=event_queryset, to_attr='prefetched_events',)
|
||||
)
|
||||
|
||||
agendas = []
|
||||
for agenda in agendas_queryset:
|
||||
if with_open_events and not any(
|
||||
not e.full for e in agenda.get_open_events(prefetched_queryset=True)
|
||||
):
|
||||
# exclude agendas without open events
|
||||
continue
|
||||
agendas.append(get_agenda_detail(request, agenda))
|
||||
|
||||
return Response({'data': agendas})
|
||||
|
||||
|
||||
|
|
|
@ -129,8 +129,8 @@ def virtual_meetings_agenda(meetings_agenda):
|
|||
|
||||
|
||||
def test_agendas_api(app):
|
||||
Agenda.objects.create(label='Foo bar')
|
||||
Agenda.objects.create(label='Foo bar 2')
|
||||
event_agenda = Agenda.objects.create(label='Foo bar')
|
||||
event_agenda2 = Agenda.objects.create(label='Foo bar 2')
|
||||
meetings_agenda1 = Agenda.objects.create(label='Foo bar Meeting', kind='meetings')
|
||||
Agenda.objects.create(label='Foo bar Meeting 2', kind='meetings')
|
||||
resource1 = Resource.objects.create(label='Resource 1', description='Foo bar Resource 1')
|
||||
|
@ -228,6 +228,68 @@ def test_agendas_api(app):
|
|||
resp = app.get('/api/agenda/', params={'q': 'MEET'})
|
||||
assert len(ctx.captured_queries) == 2
|
||||
|
||||
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
||||
assert len(resp.json['data']) == 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=event_agenda,
|
||||
)
|
||||
event2 = Event.objects.create(
|
||||
start_datetime=(now() + datetime.timedelta(days=10)).replace(hour=10, minute=0),
|
||||
places=20,
|
||||
agenda=event_agenda,
|
||||
)
|
||||
event3 = Event.objects.create(
|
||||
start_datetime=(now() + datetime.timedelta(days=15)).replace(hour=10, minute=0),
|
||||
places=20,
|
||||
agenda=event_agenda,
|
||||
)
|
||||
|
||||
# all events are free
|
||||
resp = app.get('/api/agenda/', params={'with_open_events': 'true'})
|
||||
assert len(resp.json['data']) == 1
|
||||
|
||||
# one event is full
|
||||
Event.objects.filter(pk=event1.pk).update(full=True)
|
||||
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
||||
assert len(resp.json['data']) == 1
|
||||
|
||||
# all events are full
|
||||
Event.objects.update(full=True)
|
||||
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
||||
assert len(resp.json['data']) == 0
|
||||
|
||||
# event1 is not full but too soon
|
||||
Event.objects.filter(pk=event1.pk).update(full=False)
|
||||
event_agenda.minimal_booking_delay = 10
|
||||
event_agenda.save()
|
||||
assert list(event_agenda.get_open_events()) == [event2, event3]
|
||||
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
||||
assert len(resp.json['data']) == 0
|
||||
|
||||
# event3 is not full but too late
|
||||
Event.objects.filter(pk=event3.pk).update(full=False)
|
||||
event_agenda.maximal_booking_delay = 12
|
||||
event_agenda.save()
|
||||
assert list(event_agenda.get_open_events()) == [event2]
|
||||
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
||||
assert len(resp.json['data']) == 0
|
||||
|
||||
# events are not full but not published
|
||||
Event.objects.update(full=False)
|
||||
event_agenda.event_set.update(publication_date=now().date() + datetime.timedelta(days=20))
|
||||
assert list(event_agenda.get_open_events()) == []
|
||||
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
||||
assert len(resp.json['data']) == 0
|
||||
|
||||
with CaptureQueriesContext(connection) as ctx:
|
||||
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
||||
assert len(ctx.captured_queries) == 3
|
||||
|
||||
|
||||
def test_agendas_meetingtypes_api(app, some_data, meetings_agenda):
|
||||
resp = app.get('/api/agenda/%s/meetings/' % meetings_agenda.slug)
|
||||
|
|
Loading…
Reference in New Issue