0001-api-return-opened_events_available-in-events-agenda-.patch
chrono/agendas/models.py | ||
---|---|---|
363 | 363 |
for weektime_interval in IntervalSet.simple(*time_period_interval) - closed_hours_by_days: |
364 | 364 |
yield SharedTimePeriod.from_weektime_interval(weektime_interval, desks=desks) |
365 | 365 | |
366 |
def get_opened_events(self): |
|
367 |
assert self.kind == 'events' |
|
368 | ||
369 |
entries = self.event_set.all() |
|
370 |
# we never want to allow booking for past events. |
|
371 |
entries = entries.filter(start_datetime__gte=localtime(now())) |
|
372 |
# exclude non published events |
|
373 |
entries = entries.filter( |
|
374 |
Q(publication_date__isnull=True) | Q(publication_date__lte=localtime(now()).date()) |
|
375 |
) |
|
376 |
if self.minimal_booking_delay: |
|
377 |
entries = entries.filter( |
|
378 |
start_datetime__gte=localtime( |
|
379 |
now() + datetime.timedelta(days=self.minimal_booking_delay) |
|
380 |
).replace(hour=0, minute=0) |
|
381 |
) |
|
382 |
if self.maximal_booking_delay: |
|
383 |
entries = entries.filter( |
|
384 |
start_datetime__lt=localtime( |
|
385 |
now() + datetime.timedelta(days=self.maximal_booking_delay) |
|
386 |
).replace(hour=0, minute=0) |
|
387 |
) |
|
388 |
return entries |
|
389 | ||
366 | 390 | |
367 | 391 |
class VirtualMember(models.Model): |
368 | 392 |
'''Trough model to link virtual agendas to their real agendas. |
chrono/api/views.py | ||
---|---|---|
273 | 273 |
break |
274 | 274 | |
275 | 275 | |
276 |
def get_agenda_detail(request, agenda): |
|
276 |
def get_agenda_detail(request, agenda, check_events=False):
|
|
277 | 277 |
agenda_detail = { |
278 | 278 |
'id': agenda.slug, |
279 | 279 |
'slug': agenda.slug, # kept for compatibility |
... | ... | |
293 | 293 |
reverse('api-agenda-datetimes', kwargs={'agenda_identifier': agenda.slug}) |
294 | 294 |
) |
295 | 295 |
} |
296 |
if check_events: |
|
297 |
agenda_detail['opened_events_available'] = agenda.get_opened_events().filter(full=False).exists() |
|
296 | 298 |
elif agenda.accept_meetings(): |
297 | 299 |
agenda_detail['api'] = { |
298 | 300 |
'meetings_url': request.build_absolute_uri( |
... | ... | |
370 | 372 | |
371 | 373 |
def get(self, request, agenda_identifier): |
372 | 374 |
agenda = get_object_or_404(Agenda, slug=agenda_identifier) |
373 |
return Response({'data': get_agenda_detail(request, agenda)}) |
|
375 |
return Response({'data': get_agenda_detail(request, agenda, check_events=True)})
|
|
374 | 376 | |
375 | 377 | |
376 | 378 |
agenda_detail = AgendaDetail.as_view() |
... | ... | |
391 | 393 |
if agenda.kind != 'events': |
392 | 394 |
raise Http404('agenda found, but it was not an events agenda') |
393 | 395 | |
394 |
entries = Event.objects.filter(agenda=agenda) |
|
395 | ||
396 |
# we never want to allow booking for past events. |
|
397 |
entries = entries.filter(start_datetime__gte=localtime(now())) |
|
398 | ||
399 |
# exclude non published events |
|
400 |
entries = entries.filter( |
|
401 |
Q(publication_date__isnull=True) | Q(publication_date__lte=localtime(now()).date()) |
|
402 |
) |
|
403 | ||
404 |
if agenda.minimal_booking_delay: |
|
405 |
entries = entries.filter( |
|
406 |
start_datetime__gte=localtime( |
|
407 |
now() + datetime.timedelta(days=agenda.minimal_booking_delay) |
|
408 |
).replace(hour=0, minute=0) |
|
409 |
) |
|
410 | ||
411 |
if agenda.maximal_booking_delay: |
|
412 |
entries = entries.filter( |
|
413 |
start_datetime__lt=localtime( |
|
414 |
now() + datetime.timedelta(days=agenda.maximal_booking_delay) |
|
415 |
).replace(hour=0, minute=0) |
|
416 |
) |
|
396 |
entries = agenda.get_opened_events() |
|
417 | 397 | |
418 | 398 |
if 'date_start' in request.GET: |
419 | 399 |
entries = entries.filter( |
tests/test_api.py | ||
---|---|---|
2311 | 2311 |
assert Event.objects.get(id=event.id).booked_places == 1 |
2312 | 2312 | |
2313 | 2313 | |
2314 |
def test_agenda_detail_api(app, some_data): |
|
2315 |
agenda = Agenda.objects.get(slug='foo-bar') |
|
2314 |
def test_agenda_detail_api(app): |
|
2315 |
agenda = Agenda.objects.create(label='Foo bar', kind='events', minimal_booking_delay=0) |
|
2316 |
first_date = localtime(now()).replace(hour=17, minute=0, second=0, microsecond=0) |
|
2317 |
first_date += datetime.timedelta(days=1) |
|
2318 |
event1 = Event.objects.create( |
|
2319 |
start_datetime=(now() + datetime.timedelta(days=5)).replace(hour=10, minute=0), |
|
2320 |
places=20, |
|
2321 |
agenda=agenda, |
|
2322 |
) |
|
2323 |
event2 = Event.objects.create( |
|
2324 |
start_datetime=(now() + datetime.timedelta(days=10)).replace(hour=10, minute=0), |
|
2325 |
places=20, |
|
2326 |
agenda=agenda, |
|
2327 |
) |
|
2328 |
event3 = Event.objects.create( |
|
2329 |
start_datetime=(now() + datetime.timedelta(days=15)).replace(hour=10, minute=0), |
|
2330 |
places=20, |
|
2331 |
agenda=agenda, |
|
2332 |
) |
|
2316 | 2333 |
resp = app.get('/api/agenda/%s/' % agenda.slug) |
2317 | 2334 |
data = resp.json['data'] |
2318 | 2335 |
assert data['id'] == 'foo-bar' |
2319 | 2336 |
assert data['slug'] == 'foo-bar' |
2320 | 2337 |
assert data['text'] == 'Foo bar' |
2321 | 2338 |
assert data['kind'] == 'events' |
2339 |
assert data['opened_events_available'] is True |
|
2322 | 2340 |
assert data['api']['datetimes_url'] == 'http://testserver/api/agenda/foo-bar/datetimes/' |
2323 | 2341 | |
2342 |
# one event is full |
|
2343 |
Event.objects.filter(pk=event1.pk).update(full=True) |
|
2344 |
resp = app.get('/api/agenda/%s/' % agenda.slug) |
|
2345 |
assert resp.json['data']['opened_events_available'] is True |
|
2346 | ||
2347 |
# all events are full |
|
2348 |
Event.objects.update(full=True) |
|
2349 |
resp = app.get('/api/agenda/%s/' % agenda.slug) |
|
2350 |
assert resp.json['data']['opened_events_available'] is False |
|
2351 | ||
2352 |
# event1 is not full but too soon |
|
2353 |
Event.objects.filter(pk=event1.pk).update(full=False) |
|
2354 |
agenda.minimal_booking_delay = 10 |
|
2355 |
agenda.save() |
|
2356 |
resp = app.get('/api/agenda/%s/' % agenda.slug) |
|
2357 |
assert list(agenda.get_opened_events()) == [event2, event3] |
|
2358 |
assert resp.json['data']['opened_events_available'] is False |
|
2359 | ||
2360 |
# event3 is not full but too late |
|
2361 |
Event.objects.filter(pk=event3.pk).update(full=False) |
|
2362 |
agenda.maximal_booking_delay = 12 |
|
2363 |
agenda.save() |
|
2364 |
resp = app.get('/api/agenda/%s/' % agenda.slug) |
|
2365 |
assert list(agenda.get_opened_events()) == [event2] |
|
2366 |
assert resp.json['data']['opened_events_available'] is False |
|
2367 | ||
2368 |
# events are not full but not published |
|
2369 |
Event.objects.update(full=False) |
|
2370 |
agenda.event_set.update(publication_date=now().date() + datetime.timedelta(days=20)) |
|
2371 |
resp = app.get('/api/agenda/%s/' % agenda.slug) |
|
2372 |
assert list(agenda.get_opened_events()) == [] |
|
2373 |
assert resp.json['data']['opened_events_available'] is False |
|
2374 | ||
2324 | 2375 |
# unknown |
2325 | 2376 |
app.get('/api/agenda/whatever/', status=404) |
2326 | 2377 | |
2327 |
- |