Projet

Général

Profil

0002-virtual-agendas-use-real-agendas-booking-delays-4012.patch

Emmanuel Cazenave, 25 février 2020 11:51

Télécharger (7,11 ko)

Voir les différences:

Subject: [PATCH 2/2] virtual agendas: use real agendas booking delays (#40121)

If booking delays are defined on the virtual agenda, they will take
precedence.
 chrono/api/views.py | 36 ++++++++++++++++++++++++-----
 tests/test_api.py   | 55 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 83 insertions(+), 8 deletions(-)
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
-