Projet

Général

Profil

0005-manager-account-for-time-period-weekday-indexes-in-c.patch

Valentin Deniaud, 15 mars 2022 13:39

Télécharger (7,3 ko)

Voir les différences:

Subject: [PATCH 5/5] manager: account for time period weekday indexes in
 calendar views (#45159)

 chrono/agendas/models.py   |  3 ++
 chrono/manager/views.py    |  8 ++++-
 tests/manager/test_all.py  | 49 ++++++++++++++++++++++++++++
 tests/test_time_periods.py | 65 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 124 insertions(+), 1 deletion(-)
chrono/agendas/models.py
2215 2215

  
2216 2216
    def get_opening_hours(self, date):
2217 2217
        openslots = IntervalSet()
2218
        weekday_index = get_weekday_index(date)
2218 2219
        for timeperiod in self.timeperiod_set.all():
2220
            if timeperiod.weekday_indexes and weekday_index not in timeperiod.weekday_indexes:
2221
                continue
2219 2222
            # timeperiod_set.all() are prefetched, do not filter in queryset
2220 2223
            if timeperiod.weekday != date.weekday():
2221 2224
                continue
chrono/manager/views.py
84 84
    UnavailabilityCalendar,
85 85
    VirtualMember,
86 86
)
87
from chrono.utils.date import get_weekday_index
87 88

  
88 89
from .forms import (
89 90
    AbsenceReasonForm,
......
1223 1224

  
1224 1225
    def get_timetable_infos(self):
1225 1226
        timeperiods = itertools.chain(*(d.timeperiod_set.all() for d in self.agenda.prefetched_desks))
1226
        timeperiods = [t for t in timeperiods if t.weekday == self.date.weekday()]
1227
        timeperiods = [
1228
            t
1229
            for t in timeperiods
1230
            if t.weekday == self.date.weekday()
1231
            and (not t.weekday_indexes or get_weekday_index(self.date) in t.weekday_indexes)
1232
        ]
1227 1233
        timeperiods = sorted(timeperiods, key=lambda t: t.start_time)
1228 1234

  
1229 1235
        interval = datetime.timedelta(minutes=60)
tests/manager/test_all.py
2828 2828
    assert resp.text.count('Swimming') == 2  # 1 booking + legend
2829 2829
    assert 'Booking colors:' in resp.text
2830 2830
    assert len(resp.pyquery.find('div.booking-colors span.booking-color-label')) == 2
2831

  
2832

  
2833
@freezegun.freeze_time('2022-03-01 14:00')
2834
def test_agenda_day_and_month_views_weekday_indexes(app, admin_user):
2835
    agenda = Agenda.objects.create(label='New Example', kind='meetings')
2836
    desk = Desk.objects.create(agenda=agenda, label='New Desk')
2837
    MeetingType.objects.create(agenda=agenda, label='Bar', duration=30)
2838
    today = datetime.date.today()
2839
    TimePeriod.objects.create(
2840
        desk=desk,
2841
        weekday=today.weekday(),
2842
        start_time=datetime.time(10, 0),
2843
        end_time=datetime.time(14, 0),
2844
        weekday_indexes=[1, 3],
2845
    )
2846
    TimePeriod.objects.create(
2847
        desk=desk,
2848
        weekday=today.weekday(),
2849
        start_time=datetime.time(14, 0),
2850
        end_time=datetime.time(17, 0),
2851
        weekday_indexes=[3, 5],
2852
    )
2853
    login(app)
2854

  
2855
    # check day view
2856
    resp = app.get('/manage/agendas/%s/%s/%s/%s/' % (agenda.pk, today.year, today.month, today.day))
2857
    assert resp.text.count('<tr') == 5  # 10->14
2858
    assert 'style="height: 400%; top: 0%;"' in resp.text
2859

  
2860
    resp = app.get('/manage/agendas/%s/%s/%s/%s/' % (agenda.pk, today.year, today.month, today.day + 7))
2861
    assert 'No opening hours this day.' in resp.text
2862

  
2863
    resp = app.get('/manage/agendas/%s/%s/%s/%s/' % (agenda.pk, today.year, today.month, today.day + 14))
2864
    assert resp.text.count('<tr') == 8  # 10->14, 14->17
2865
    assert 'style="height: 700%; top: 0%;"' in resp.text
2866

  
2867
    resp = app.get('/manage/agendas/%s/%s/%s/%s/' % (agenda.pk, today.year, today.month, today.day + 21))
2868
    assert 'No opening hours this day.' in resp.text
2869

  
2870
    resp = app.get('/manage/agendas/%s/%s/%s/%s/' % (agenda.pk, today.year, today.month, today.day + 28))
2871
    assert resp.text.count('<tr') == 4  # 14->17
2872
    assert 'style="height: 300%; top: 0%;"' in resp.text
2873

  
2874
    # check month view
2875
    resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.pk, today.year, today.month))
2876
    assert resp.text.count('height:') == 3
2877
    assert resp.text.count('height:400.0%') == 1
2878
    assert resp.text.count('height:700.0%') == 1
2879
    assert resp.text.count('height:300.0%') == 1
tests/test_time_periods.py
233 233
    assert localtime(hours[2].end).time() == datetime.time(17, 0)
234 234

  
235 235

  
236
def test_desk_opening_hours_weekday_indexes():
237
    def set_prefetched_exceptions(desk):
238
        desk.prefetched_exceptions = TimePeriodException.objects.filter(
239
            Q(desk=desk) | Q(unavailability_calendar__desks=desk)
240
        )
241

  
242
    agenda = Agenda.objects.create(label='Foo bar', slug='bar')
243
    desk = Desk.objects.create(label='Desk 1', agenda=agenda)
244

  
245
    # morning
246
    timeperiod = TimePeriod.objects.create(
247
        desk=desk,
248
        weekday=0,
249
        start_time=datetime.time(9, 0),
250
        end_time=datetime.time(12, 0),
251
        weekday_indexes=[4],
252
    )
253
    set_prefetched_exceptions(desk)
254
    hours = desk.get_opening_hours(datetime.date(2018, 1, 22))
255
    assert len(hours) == 1
256
    assert hours[0].begin.time() == datetime.time(9, 0)
257
    assert hours[0].end.time() == datetime.time(12, 0)
258

  
259
    # and afternoon
260
    TimePeriod.objects.create(
261
        desk=desk,
262
        weekday=0,
263
        start_time=datetime.time(14, 0),
264
        end_time=datetime.time(17, 0),
265
        weekday_indexes=[4],
266
    )
267
    set_prefetched_exceptions(desk)
268
    hours = desk.get_opening_hours(datetime.date(2018, 1, 22))
269
    assert len(hours) == 2
270
    assert hours[0].begin.time() == datetime.time(9, 0)
271
    assert hours[0].end.time() == datetime.time(12, 0)
272

  
273
    assert hours[1].begin.time() == datetime.time(14, 0)
274
    assert hours[1].end.time() == datetime.time(17, 0)
275

  
276
    timeperiod.weekday_indexes = [5]
277
    timeperiod.save()
278
    hours = desk.get_opening_hours(datetime.date(2018, 1, 22))
279
    assert len(hours) == 1
280
    assert hours[0].begin.time() == datetime.time(14, 0)
281
    assert hours[0].end.time() == datetime.time(17, 0)
282

  
283
    hours = desk.get_opening_hours(datetime.date(2018, 1, 29))
284
    assert len(hours) == 1
285
    assert hours[0].begin.time() == datetime.time(9, 0)
286
    assert hours[0].end.time() == datetime.time(12, 0)
287

  
288
    # full day exception
289
    exception = TimePeriodException(
290
        desk=desk,
291
        start_datetime=make_aware(datetime.datetime(2018, 1, 22)),
292
        end_datetime=make_aware(datetime.datetime(2018, 1, 23)),
293
    )
294
    exception.save()
295

  
296
    set_prefetched_exceptions(desk)
297
    hours = desk.get_opening_hours(datetime.date(2018, 1, 22))
298
    assert len(hours) == 0
299

  
300

  
236 301
def test_timeperiod_midnight_overlap_time_slots():
237 302
    # https://dev.entrouvert.org/issues/29142
238 303
    agenda = Agenda(label='Foo bar', slug='bar')
239
-