0002-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 | ||
---|---|---|
2180 | 2180 |
'text': 'Virtual Agenda', |
2181 | 2181 |
'id': 'virtual-agenda', |
2182 | 2182 |
'slug': 'virtual-agenda', |
2183 |
'minimal_booking_delay': 1,
|
|
2184 |
'maximal_booking_delay': 56,
|
|
2183 |
'minimal_booking_delay': None,
|
|
2184 |
'maximal_booking_delay': None,
|
|
2185 | 2185 |
'kind': 'virtual', |
2186 | 2186 |
'api': { |
2187 | 2187 |
'meetings_url': 'http://testserver/api/agenda/%s/meetings/' % virtual_meetings_agenda.slug, |
... | ... | |
2340 | 2340 |
assert len(resp.json['data']) == 3 |
2341 | 2341 | |
2342 | 2342 | |
2343 |
def test_virtual_agendas_meetings_datetimes_delays_api(app, mock_now): |
|
2344 |
foo_agenda = Agenda.objects.create(label='Foo Meeting', kind='meetings', maximal_booking_delay=7) |
|
2345 |
MeetingType.objects.create(agenda=foo_agenda, label='Meeting Type', duration=30) |
|
2346 |
foo_desk_1 = Desk.objects.create(agenda=foo_agenda, label='Foo desk 1') |
|
2347 |
TimePeriod.objects.create( |
|
2348 |
weekday=0, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0), desk=foo_desk_1, |
|
2349 |
) |
|
2350 |
TimePeriod.objects.create( |
|
2351 |
weekday=1, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0), desk=foo_desk_1, |
|
2352 |
) |
|
2353 | ||
2354 |
bar_agenda = Agenda.objects.create(label='Bar Meeting', kind='meetings', maximal_booking_delay=7) |
|
2355 |
MeetingType.objects.create(agenda=bar_agenda, label='Meeting Type', duration=30) |
|
2356 |
bar_desk_1 = Desk.objects.create(agenda=bar_agenda, label='Bar desk 1') |
|
2357 |
TimePeriod.objects.create( |
|
2358 |
weekday=2, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0), desk=bar_desk_1, |
|
2359 |
) |
|
2360 |
TimePeriod.objects.create( |
|
2361 |
weekday=3, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0), desk=bar_desk_1, |
|
2362 |
) |
|
2363 | ||
2364 |
virt_agenda = Agenda.objects.create(label='Virtual Agenda', kind='virtual') |
|
2365 | ||
2366 |
VirtualMember.objects.create(virtual_agenda=virt_agenda, real_agenda=foo_agenda) |
|
2367 |
VirtualMember.objects.create(virtual_agenda=virt_agenda, real_agenda=bar_agenda) |
|
2368 |
virt_meeting_type = virt_agenda.iter_meetingtypes()[0] |
|
2369 |
api_url = '/api/agenda/%s/meetings/%s/datetimes/' % (virt_agenda.slug, virt_meeting_type.slug) |
|
2370 |
resp = app.get(api_url) |
|
2371 |
# 8 slots for m each agenda |
|
2372 |
assert len(resp.json['data']) == 16 |
|
2373 | ||
2374 |
# restrict foo's minimal_booking_delay : only bar's slots are left |
|
2375 |
foo_agenda.minimal_booking_delay = 6 |
|
2376 |
foo_agenda.save() |
|
2377 |
resp = app.get(api_url) |
|
2378 |
assert len(resp.json['data']) == 8 |
|
2379 | ||
2380 |
# restrict bar's maximal_booking_delay : only half of bar's slots are left |
|
2381 |
bar_agenda.maximal_booking_delay = 4 |
|
2382 |
bar_agenda.save() |
|
2383 |
resp = app.get(api_url) |
|
2384 |
assert len(resp.json['data']) == 4 |
|
2385 | ||
2386 |
# put back very slots from foo |
|
2387 |
foo_agenda.minimal_booking_delay = 1 |
|
2388 |
foo_agenda.maximal_booking_delay = 7 |
|
2389 |
foo_agenda.save() |
|
2390 |
resp = app.get(api_url) |
|
2391 |
assert len(resp.json['data']) == 12 |
|
2392 | ||
2393 | ||
2343 | 2394 |
def test_virtual_agendas_meetings_exception(app, user, virtual_meetings_agenda): |
2344 | 2395 |
app.authorization = ('Basic', ('john.doe', 'password')) |
2345 | 2396 |
real_agenda = virtual_meetings_agenda.real_agendas.first() |
2346 |
- |