0005-virtual-agendas-use-real-agendas-booking-delays-4012.patch
chrono/api/views.py | ||
---|---|---|
49 | 49 |
return exceptions_by_desk |
50 | 50 | |
51 | 51 | |
52 |
def get_all_slots(agenda, meeting_type): |
|
52 |
def get_min_datetime(agenda): |
|
53 |
if agenda.minimal_booking_delay is None: |
|
54 |
return None |
|
53 | 55 |
min_datetime = now() + datetime.timedelta(days=agenda.minimal_booking_delay) |
56 |
return min_datetime.replace(hour=0, minute=0, second=0, microsecond=0) |
|
57 | ||
58 | ||
59 |
def get_max_datetime(agenda): |
|
60 |
if agenda.maximal_booking_delay is None: |
|
61 |
return None |
|
54 | 62 |
max_datetime = now() + datetime.timedelta(days=agenda.maximal_booking_delay) |
55 |
min_datetime = min_datetime.replace(hour=0, minute=0, second=0, microsecond=0) |
|
56 | 63 |
max_datetime = max_datetime.replace(hour=0, minute=0, second=0, microsecond=0) |
57 |
max_datetime = max_datetime + datetime.timedelta(days=1) |
|
64 |
return max_datetime + datetime.timedelta(days=1) |
|
65 | ||
58 | 66 | |
67 |
def get_all_slots(agenda, meeting_type): |
|
68 |
min_datetime = get_min_datetime(agenda) |
|
69 |
max_datetime = get_max_datetime(agenda) |
|
59 | 70 |
time_period_filters = { |
60 | 71 |
'min_datetime': min_datetime, |
61 | 72 |
'max_datetime': max_datetime, |
... | ... | |
71 | 82 |
open_slots[agenda] = defaultdict(lambda: Intervals()) |
72 | 83 | |
73 | 84 |
for agenda in agendas: |
85 |
used_time_period_filters = time_period_filters.copy() |
|
86 |
if used_time_period_filters['min_datetime'] is None: |
|
87 |
used_time_period_filters['min_datetime'] = get_min_datetime(agenda) |
|
88 |
if used_time_period_filters['max_datetime'] is None: |
|
89 |
used_time_period_filters['max_datetime'] = get_max_datetime(agenda) |
|
90 | ||
74 | 91 |
for time_period in TimePeriod.objects.filter(desk__agenda=agenda): |
75 | 92 |
duration = ( |
76 | 93 |
datetime.datetime.combine(base_date, time_period.end_time) |
... | ... | |
79 | 96 |
if duration < meeting_type.duration: |
80 | 97 |
# skip time period that can't even hold a single meeting |
81 | 98 |
continue |
82 |
for slot in time_period.get_time_slots(**time_period_filters): |
|
99 |
for slot in time_period.get_time_slots(**used_time_period_filters):
|
|
83 | 100 |
slot.full = False |
84 | 101 |
open_slots[agenda][time_period.desk_id].add(slot.start_datetime, slot.end_datetime, slot) |
85 | 102 | |
... | ... | |
93 | 110 |
open_slots[agenda][desk].remove_overlap(localtime(begin), localtime(end)) |
94 | 111 | |
95 | 112 |
for agenda in agendas: |
113 |
used_min_datetime = min_datetime |
|
114 |
if used_min_datetime is None: |
|
115 |
used_min_datetime = get_min_datetime(agenda) |
|
116 |
used_max_datetime = max_datetime |
|
117 |
if used_max_datetime is None: |
|
118 |
used_max_datetime = get_max_datetime(agenda) |
|
119 | ||
96 | 120 |
for event in ( |
97 | 121 |
agenda.event_set.filter( |
98 | 122 |
agenda=agenda, |
99 |
start_datetime__gte=min_datetime, |
|
100 |
start_datetime__lte=max_datetime + datetime.timedelta(meeting_type.duration), |
|
123 |
start_datetime__gte=used_min_datetime,
|
|
124 |
start_datetime__lte=used_max_datetime + datetime.timedelta(meeting_type.duration),
|
|
101 | 125 |
) |
102 | 126 |
.select_related('meeting_type') |
103 | 127 |
.exclude(booking__cancellation_datetime__isnull=False) |
tests/test_api.py | ||
---|---|---|
2294 | 2294 |
'text': 'Virtual Agenda', |
2295 | 2295 |
'id': 'virtual-agenda', |
2296 | 2296 |
'slug': 'virtual-agenda', |
2297 |
'minimal_booking_delay': 1,
|
|
2298 |
'maximal_booking_delay': 56,
|
|
2297 |
'minimal_booking_delay': None,
|
|
2298 |
'maximal_booking_delay': None,
|
|
2299 | 2299 |
'kind': 'virtual', |
2300 | 2300 |
'api': { |
2301 | 2301 |
'meetings_url': 'http://testserver/api/agenda/%s/meetings/' % virtual_meetings_agenda.slug, |
... | ... | |
2454 | 2454 |
assert len(resp.json['data']) == 3 |
2455 | 2455 | |
2456 | 2456 | |
2457 |
def test_virtual_agendas_meetings_datetimes_delays_api(app, mock_now): |
|
2458 |
foo_agenda = Agenda.objects.create(label='Foo Meeting', kind='meetings', maximal_booking_delay=7) |
|
2459 |
MeetingType.objects.create(agenda=foo_agenda, label='Meeting Type', duration=30) |
|
2460 |
foo_desk_1 = Desk.objects.create(agenda=foo_agenda, label='Foo desk 1') |
|
2461 |
TimePeriod.objects.create( |
|
2462 |
weekday=0, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0), desk=foo_desk_1, |
|
2463 |
) |
|
2464 |
TimePeriod.objects.create( |
|
2465 |
weekday=1, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0), desk=foo_desk_1, |
|
2466 |
) |
|
2467 | ||
2468 |
bar_agenda = Agenda.objects.create(label='Bar Meeting', kind='meetings', maximal_booking_delay=7) |
|
2469 |
MeetingType.objects.create(agenda=bar_agenda, label='Meeting Type', duration=30) |
|
2470 |
bar_desk_1 = Desk.objects.create(agenda=bar_agenda, label='Bar desk 1') |
|
2471 |
TimePeriod.objects.create( |
|
2472 |
weekday=2, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0), desk=bar_desk_1, |
|
2473 |
) |
|
2474 |
TimePeriod.objects.create( |
|
2475 |
weekday=3, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0), desk=bar_desk_1, |
|
2476 |
) |
|
2477 | ||
2478 |
virt_agenda = Agenda.objects.create(label='Virtual Agenda', kind='virtual') |
|
2479 | ||
2480 |
VirtualMember.objects.create(virtual_agenda=virt_agenda, real_agenda=foo_agenda) |
|
2481 |
VirtualMember.objects.create(virtual_agenda=virt_agenda, real_agenda=bar_agenda) |
|
2482 |
virt_meeting_type = virt_agenda.iter_meetingtypes()[0] |
|
2483 |
api_url = '/api/agenda/%s/meetings/%s/datetimes/' % (virt_agenda.slug, virt_meeting_type.slug) |
|
2484 |
resp = app.get(api_url) |
|
2485 |
# 8 slots for m each agenda |
|
2486 |
assert len(resp.json['data']) == 16 |
|
2487 | ||
2488 |
# restrict foo's minimal_booking_delay : only bar's slots are left |
|
2489 |
foo_agenda.minimal_booking_delay = 6 |
|
2490 |
foo_agenda.save() |
|
2491 |
resp = app.get(api_url) |
|
2492 |
assert len(resp.json['data']) == 8 |
|
2493 | ||
2494 |
# restrict bar's maximal_booking_delay : only half of bar's slots are left |
|
2495 |
bar_agenda.maximal_booking_delay = 4 |
|
2496 |
bar_agenda.save() |
|
2497 |
resp = app.get(api_url) |
|
2498 |
assert len(resp.json['data']) == 4 |
|
2499 | ||
2500 |
# put back very slots from foo |
|
2501 |
foo_agenda.minimal_booking_delay = 1 |
|
2502 |
foo_agenda.maximal_booking_delay = 7 |
|
2503 |
foo_agenda.save() |
|
2504 |
resp = app.get(api_url) |
|
2505 |
assert len(resp.json['data']) == 12 |
|
2506 | ||
2507 | ||
2457 | 2508 |
def test_virtual_agendas_meetings_exception(app, user, virtual_meetings_agenda): |
2458 | 2509 |
app.authorization = ('Basic', ('john.doe', 'password')) |
2459 | 2510 |
real_agenda = virtual_meetings_agenda.real_agendas.first() |
2460 |
- |