0003-api-show-events-out-of-minimal-delay-58286.patch
chrono/agendas/models.py | ||
---|---|---|
600 | 600 |
for weektime_interval in IntervalSet.simple(*time_period_interval) - closed_hours_by_days: |
601 | 601 |
yield SharedTimePeriod.from_weektime_interval(weektime_interval, desks=desks) |
602 | 602 | |
603 |
@property |
|
603 |
@functional.cached_property
|
|
604 | 604 |
def max_booking_datetime(self): |
605 | 605 |
if self.maximal_booking_delay is None: |
606 | 606 |
return None |
... | ... | |
618 | 618 |
t = t.replace(hour=0, minute=0, second=0, microsecond=0) |
619 | 619 |
return localtime(t) |
620 | 620 | |
621 |
@property |
|
621 |
@functional.cached_property
|
|
622 | 622 |
def min_booking_datetime(self): |
623 | 623 |
if self.minimal_booking_delay is None: |
624 | 624 |
return None |
... | ... | |
651 | 651 |
max_start=None, |
652 | 652 |
user_external_id=None, |
653 | 653 |
bypass_delays=False, |
654 |
show_out_of_minimal_delay=False, |
|
654 | 655 |
): |
655 | 656 |
assert self.kind == 'events' |
656 | 657 | |
... | ... | |
672 | 673 |
if not include_full: |
673 | 674 |
entries = entries.filter(Q(full=False) | Q(primary_event__isnull=False)) |
674 | 675 | |
675 |
if not bypass_delays and self.minimal_booking_delay: |
|
676 |
if not bypass_delays and not show_out_of_minimal_delay and self.minimal_booking_delay:
|
|
676 | 677 |
min_start = max(self.min_booking_datetime, min_start) if min_start else self.min_booking_datetime |
677 | 678 | |
678 | 679 |
if min_start: |
chrono/api/views.py | ||
---|---|---|
420 | 420 |
return places |
421 | 421 | |
422 | 422 | |
423 |
def is_event_disabled(event, min_places=1, disable_booked=True, bookable_events=None): |
|
423 |
def is_event_disabled(event, min_places=1, disable_booked=True, bookable_events=None, bypass_delays=False):
|
|
424 | 424 |
if disable_booked and getattr(event, 'user_places_count', 0) > 0: |
425 | 425 |
return True |
426 | 426 |
if event.start_datetime < now(): |
... | ... | |
430 | 430 |
return False |
431 | 431 |
# we just want to show past events, but they are not bookable |
432 | 432 |
return True |
433 |
elif ( |
|
434 |
not bypass_delays |
|
435 |
and event.agenda.min_booking_datetime |
|
436 |
and event.start_datetime < event.agenda.min_booking_datetime |
|
437 |
): |
|
438 |
# event is out of minimal delay and we don't want to bypass delays |
|
439 |
return True |
|
433 | 440 |
if event.remaining_places < min_places and event.remaining_waiting_list_places < min_places: |
434 | 441 |
return True |
435 | 442 |
return False |
... | ... | |
466 | 473 |
bookable_events=None, |
467 | 474 |
multiple_agendas=False, |
468 | 475 |
disable_booked=True, |
476 |
bypass_delays=False, |
|
469 | 477 |
): |
470 | 478 |
agenda = agenda or event.agenda |
471 | 479 |
details = { |
... | ... | |
496 | 504 |
min_places=min_places, |
497 | 505 |
disable_booked=disable_booked, |
498 | 506 |
bookable_events=bookable_events, |
507 |
bypass_delays=bypass_delays, |
|
499 | 508 |
), |
500 | 509 |
'api': { |
501 | 510 |
'bookings_url': request.build_absolute_uri( |
... | ... | |
538 | 547 | |
539 | 548 | |
540 | 549 |
def get_events_meta_detail( |
541 |
request, events, agenda=None, min_places=1, bookable_events=None, multiple_agendas=False |
|
550 |
request, |
|
551 |
events, |
|
552 |
agenda=None, |
|
553 |
min_places=1, |
|
554 |
bookable_events=None, |
|
555 |
multiple_agendas=False, |
|
556 |
bypass_delays=False, |
|
542 | 557 |
): |
543 | 558 |
bookable_datetimes_number_total = 0 |
544 | 559 |
bookable_datetimes_number_available = 0 |
545 | 560 |
first_bookable_slot = None |
546 | 561 |
for event in events: |
547 | 562 |
bookable_datetimes_number_total += 1 |
548 |
if not is_event_disabled(event, min_places=min_places, bookable_events=bookable_events): |
|
563 |
if not is_event_disabled( |
|
564 |
event, min_places=min_places, bookable_events=bookable_events, bypass_delays=bypass_delays |
|
565 |
): |
|
549 | 566 |
bookable_datetimes_number_available += 1 |
550 | 567 |
if not first_bookable_slot: |
551 | 568 |
first_bookable_slot = get_event_detail( |
... | ... | |
555 | 572 |
min_places=min_places, |
556 | 573 |
bookable_events=bookable_events, |
557 | 574 |
multiple_agendas=multiple_agendas, |
575 |
bypass_delays=bypass_delays, |
|
558 | 576 |
) |
559 | 577 |
return { |
560 | 578 |
'no_bookable_datetimes': bool(bookable_datetimes_number_available == 0), |
... | ... | |
824 | 842 |
e |
825 | 843 |
for e in entries |
826 | 844 |
if not is_event_disabled( |
827 |
e, payload['min_places'], disable_booked=disable_booked, bookable_events=bookable_events |
|
845 |
e, |
|
846 |
payload['min_places'], |
|
847 |
disable_booked=disable_booked, |
|
848 |
bookable_events=bookable_events, |
|
849 |
bypass_delays=payload.get('bypass_delays'), |
|
828 | 850 |
) |
829 | 851 |
] |
830 | 852 | |
... | ... | |
838 | 860 |
booked_user_external_id=payload.get('user_external_id'), |
839 | 861 |
bookable_events=bookable_events_raw, |
840 | 862 |
disable_booked=disable_booked, |
863 |
bypass_delays=payload.get('bypass_delays'), |
|
841 | 864 |
) |
842 | 865 |
for x in entries |
843 | 866 |
], |
... | ... | |
900 | 923 |
min_start=payload.get('date_start'), |
901 | 924 |
max_start=payload.get('date_end'), |
902 | 925 |
bypass_delays=payload.get('bypass_delays'), |
926 |
show_out_of_minimal_delay=show_past_events, |
|
903 | 927 |
) |
904 | 928 |
) |
905 | 929 | |
... | ... | |
915 | 939 |
booked_user_external_id=payload.get('user_external_id'), |
916 | 940 |
multiple_agendas=True, |
917 | 941 |
disable_booked=disable_booked, |
942 |
bypass_delays=payload.get('bypass_delays'), |
|
918 | 943 |
) |
919 | 944 |
for x in entries |
920 | 945 |
], |
tests/api/test_datetimes.py | ||
---|---|---|
694 | 694 |
# check delays |
695 | 695 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug) |
696 | 696 |
assert len(resp.json['data']) == 4 |
697 |
assert [e['disabled'] for e in resp.json['data']] == [False] * 4 |
|
697 | 698 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'bypass_delays': True}) |
698 | 699 |
assert len(resp.json['data']) == 53 |
700 |
assert [e['disabled'] for e in resp.json['data']] == [False] * 53 |
|
699 | 701 |
agenda.minimal_booking_delay = 10 |
700 | 702 |
agenda.mmaximal_booking_delay = 20 |
701 | 703 |
agenda.save() |
702 | 704 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug) |
703 | 705 |
assert len(resp.json['data']) == 3 |
706 |
assert [e['disabled'] for e in resp.json['data']] == [False] * 3 |
|
704 | 707 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'bypass_delays': True}) |
705 | 708 |
assert len(resp.json['data']) == 53 |
709 |
assert [e['disabled'] for e in resp.json['data']] == [False] * 53 |
|
706 | 710 | |
707 | 711 | |
708 | 712 |
def test_recurring_events_api_various_times(app, user, mock_now): |
... | ... | |
1498 | 1502 |
date_end = localtime() + datetime.timedelta(days=60) # with a date end to have recurring events |
1499 | 1503 |
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'date_end': date_end}) |
1500 | 1504 |
assert len(resp.json['data']) == 2 |
1505 |
assert [d['disabled'] for d in resp.json['data']] == [False, False] |
|
1506 |
assert resp.json['data'][0]['id'] == 'second-agenda@event' |
|
1507 |
assert resp.json['data'][1]['id'] == 'first-agenda@recurring:2021-05-13-1700' |
|
1501 | 1508 |
resp = app.get( |
1502 | 1509 |
'/api/agendas/datetimes/', |
1503 | 1510 |
params={'agendas': agenda_slugs, 'date_end': date_end, 'bypass_delays': True}, |
1504 | 1511 |
) |
1505 | 1512 |
assert len(resp.json['data']) == 5 |
1513 |
assert resp.json['data'][0]['id'] == 'first-agenda@recurring:2021-05-06-1700' |
|
1514 |
assert resp.json['data'][1]['id'] == 'first-agenda@event' |
|
1515 |
assert resp.json['data'][2]['id'] == 'second-agenda@event' |
|
1516 |
assert resp.json['data'][3]['id'] == 'first-agenda@recurring:2021-05-13-1700' |
|
1517 |
assert resp.json['data'][4]['id'] == 'first-agenda@recurring:2021-05-20-1700' |
|
1518 |
assert [d['disabled'] for d in resp.json['data']] == [False, False, False, False, False] |
|
1506 | 1519 |
Agenda.objects.update(minimal_booking_delay=0, maximal_booking_delay=45) |
1507 | 1520 | |
1508 | 1521 |
# invalid slugs |
... | ... | |
1520 | 1533 |
assert resp.json['data'][2]['id'] == 'second-agenda@event' |
1521 | 1534 |
assert resp.json['data'][3]['id'] == 'first-agenda@recurring:2021-05-13-1700' |
1522 | 1535 |
assert resp.json['data'][4]['id'] == 'first-agenda@recurring:2021-05-20-1700' |
1536 |
assert [d['disabled'] for d in resp.json['data']] == [False, False, False, False, False] |
|
1537 | ||
1538 |
# and events out of minimal_booking_delay |
|
1539 |
Agenda.objects.update(minimal_booking_delay=6, maximal_booking_delay=14) |
|
1540 |
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'show_past_events': True}) |
|
1541 |
assert len(resp.json['data']) == 4 |
|
1542 |
assert resp.json['data'][0]['id'] == 'first-agenda@recurring:2021-05-06-1700' |
|
1543 |
assert resp.json['data'][1]['id'] == 'first-agenda@event' |
|
1544 |
assert resp.json['data'][2]['id'] == 'second-agenda@event' |
|
1545 |
assert resp.json['data'][3]['id'] == 'first-agenda@recurring:2021-05-13-1700' |
|
1546 |
assert [d['disabled'] for d in resp.json['data']] == [True, True, False, False] |
|
1547 |
Agenda.objects.update(minimal_booking_delay=0, maximal_booking_delay=45) |
|
1523 | 1548 | |
1524 | 1549 |
Event.objects.create( |
1525 | 1550 |
slug='event-in-past', |
tests/test_agendas.py | ||
---|---|---|
206 | 206 |
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10) |
207 | 207 |
agenda.minimal_booking_delay_in_working_days = False |
208 | 208 |
agenda.save() |
209 |
del agenda.min_booking_datetime |
|
209 | 210 |
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10) |
210 | 211 | |
211 | 212 |
settings.WORKING_DAY_CALENDAR = 'workalendar.europe.France' |
212 | 213 |
agenda.minimal_booking_delay_in_working_days = True |
213 | 214 |
agenda.save() |
215 |
del agenda.min_booking_datetime |
|
214 | 216 |
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 12) |
215 | 217 |
agenda.minimal_booking_delay_in_working_days = False |
216 | 218 |
agenda.save() |
219 |
del agenda.min_booking_datetime |
|
217 | 220 |
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10) |
218 | 221 | |
219 | 222 | |
220 |
- |