Projet

Général

Profil

0001-manager-display-exceptions-in-day-month-views-39906.patch

Frédéric Péters, 02 mars 2020 13:54

Télécharger (8,97 ko)

Voir les différences:

Subject: [PATCH] manager: display exceptions in day/month views (#39906)

 chrono/manager/static/css/style.scss          |  6 +++-
 .../chrono/manager_agenda_day_view.html       |  5 +++
 .../manager_meetings_agenda_month_view.html   |  5 +++
 chrono/manager/views.py                       | 33 +++++++++++++++++--
 tests/test_manager.py                         | 25 ++++++++++++++
 5 files changed, 70 insertions(+), 4 deletions(-)
chrono/manager/static/css/style.scss
172 172
	padding: 1ex;
173 173
	position: absolute;
174 174
	overflow: hidden;
175
	&.opening-hours {
175
	&.opening-hours, &.exception-hours {
176 176
		z-index: 1;
177 177
		background: #b1ea4d linear-gradient(135deg, #b1ea4d 0%, #459522 100%);
178 178
		opacity: 0.6;
179 179
		left: 0.5ex;
180 180
		width: calc(100% - 1ex);
181 181
	}
182
	&.exception-hours {
183
		background: #fee linear-gradient(135deg, #fee 0%, #fdd 100%);
184
		text-align: center;
185
	}
182 186
	&.booking {
183 187
		background: #eef linear-gradient(135deg, #eef 0%, #ddf 100%);
184 188
		box-shadow: 0 0 1px 0 #2d2dad;
chrono/manager/templates/chrono/manager_agenda_day_view.html
60 60
               style="height: {{ slot.css_height }}%; top: {{ slot.css_top }}%;"
61 61
                  >{{slot.begin}} {{slot.end}}</div>
62 62
          {% endfor %}
63
          {% for slot in desk_info.exceptions %}
64
          <div class="exception-hours"
65
               style="height: {{ slot.css_height }}%; top: {{ slot.css_top }}%;"
66
               >{% if slot.label %}<span class="exception-label">{{slot.label}}</span>{% endif %}</div>
67
          {% endfor %}
63 68
        {% endif %}
64 69

  
65 70
        {% for booking in desk_info.bookings %}
chrono/manager/templates/chrono/manager_meetings_agenda_month_view.html
26 26
      {% for slot in day.infos.opening_hours %}
27 27
      <div class="opening-hours" style="height:{{ slot.css_height|stringformat:".1f" }}%;top:{{ slot.css_top|stringformat:".1f" }}%;width:{{ slot.css_width|stringformat:".1f" }}%;left:{{ slot.css_left|stringformat:".1f" }}%;"></div>
28 28
      {% endfor %}
29

  
30
      {% for slot in day.infos.exceptions %}
31
      <div class="exception-hours" style="height:{{ slot.css_height|stringformat:".1f" }}%;top:{{ slot.css_top|stringformat:".1f" }}%;width:{{ slot.css_width|stringformat:".1f" }}%;left:{{ slot.css_left|stringformat:".1f" }}%;" {% if slot.label %}title="{{ slot.label }}"{% endif %}></div>
32
      {% endfor %}
33

  
29 34
      {% for slot in day.infos.booked_slots %}
30 35
      <div class="booking" style="left:{{ slot.css_left|stringformat:".1f" }}%;height:{{ slot.css_height|stringformat:".1f" }}%;top:{{ slot.css_top|stringformat:".1f" }}%;width:{{ slot.css_width|stringformat:".1f" }}%">
31 36
        <span class="start-time">{{slot.booking.event.start_datetime|date:"TIME_FORMAT"}}</span>
chrono/manager/views.py
376 376
            # until the end of the last hour.
377 377
            max_date += datetime.timedelta(hours=1)
378 378

  
379
        desks = self.agenda.desk_set.all()
379
        desks = self.agenda.desk_set.all().prefetch_related('timeperiodexception_set')
380 380

  
381 381
        first = True
382 382
        while current_date < max_date:
......
395 395
                                'css_height': 100 * (opening_hour.end - opening_hour.begin).seconds // 3600,
396 396
                            }
397 397
                        )
398

  
399
                    # and exceptions for this desk
400
                    info['exceptions'] = []
401
                    for exception in desk.timeperiodexception_set.all():
402
                        if exception.end_datetime < start_date:
403
                            continue
404
                        if exception.start_datetime > max_date:
405
                            continue
406
                        start_max = max(start_date, exception.start_datetime)
407
                        end_min = min(max_date, exception.end_datetime)
408
                        exception.css_top = int(100 * (start_max - start_date).seconds // 3600)
409
                        exception.css_height = int(100 * (end_min - start_max).seconds // 3600)
410
                        info['exceptions'].append(exception)
411

  
398 412
                infos.append(info)
399 413
                info['bookings'] = bookings = []  # bookings for this desk
400 414
                finish_datetime = current_date + interval
......
507 521
            'date': current_date,
508 522
            'today': day.date() == datetime.date.today(),
509 523
            'other_month': day.month != self.date.month,
510
            'infos': {'opening_hours': [], 'booked_slots': []},
524
            'infos': {'opening_hours': [], 'exceptions': [], 'booked_slots': []},
511 525
        }
512 526

  
513
        desks = self.agenda.desk_set.all()
527
        desks = self.agenda.desk_set.all().prefetch_related('timeperiodexception_set')
514 528
        desks_len = len(desks)
515 529
        max_date = day.replace(hour=self.max_timeperiod.hour, minute=0)
516 530

  
......
553 567
                                'css_left': left,
554 568
                            }
555 569
                        )
570
                    for exception in desk.timeperiodexception_set.all():
571
                        if exception.end_datetime < current_date:
572
                            continue
573
                        if exception.start_datetime > max_date:
574
                            continue
575
                        start_max = max(current_date, exception.start_datetime)
576
                        end_min = min(max_date, exception.end_datetime)
577
                        exception.css_top = int(100 * (start_max - current_date).seconds // 3600)
578
                        exception.css_height = int(100 * (end_min - current_date).seconds // 3600)
579
                        exception.css_width = width
580
                        exception.css_left = left
581
                        timetable['infos']['exceptions'].append(exception)
582

  
556 583
                left += width + 1
557 584
            period += interval
558 585

  
tests/test_manager.py
1704 1704
    agenda.save()
1705 1705
    resp = app.get('/manage/agendas/%s/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day), status=200)
1706 1706

  
1707
    # display exception
1708
    TimePeriodException.objects.create(
1709
        label='Exception for the afternoon',
1710
        desk=desk,
1711
        start_datetime=make_aware(datetime.datetime(date.year, date.month, date.day, 13, 0)),
1712
        end_datetime=make_aware(datetime.datetime(date.year, date.month, date.day, 23, 0)),
1713
    )
1714
    resp = app.get('/manage/agendas/%s/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day), status=200)
1715
    # day is displaying rows from 10am to 6pm,
1716
    # opening hours, 10am to 1pm gives top: 300%
1717
    # rest of the day, 1pm to 6(+1)pm gives 600%
1718
    assert 'height: 600%; top: 300%' in resp.text
1719
    assert 'Exception for the afternoon' in resp.text
1720

  
1707 1721

  
1708 1722
def test_agenda_day_view_late_meeting(app, admin_user, manager_user, api_user):
1709 1723
    agenda = Agenda.objects.create(label='New Example', kind='meetings')
......
1868 1882
    resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, today.year, today.month))
1869 1883
    assert not 'No opening hours this month.' in resp.text
1870 1884

  
1885
    # display exception
1886
    TimePeriodException.objects.create(
1887
        label='Exception for a December day',
1888
        desk=desk,
1889
        start_datetime=make_aware(datetime.datetime(2018, 12, 15, 5, 0)),
1890
        end_datetime=make_aware(datetime.datetime(2018, 12, 15, 23, 0)),
1891
    )
1892
    resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, today.year, today.month))
1893
    assert 'height:800.0%;top:0.0%;width:48.0%;left:50.0%;' in resp.text
1894
    assert 'Exception for a December day' in resp.text
1895

  
1871 1896

  
1872 1897
def test_agenda_month_view_weekend(app, admin_user, manager_user, api_user):
1873 1898
    agenda = Agenda.objects.create(label='Passeports', kind='meetings')
1874
-