Projet

Général

Profil

0001-manager-prevent-time-period-changes-when-bookings-ex.patch

Josué Kouka, 22 décembre 2017 12:17

Télécharger (7,19 ko)

Voir les différences:

Subject: [PATCH] manager: prevent time period changes when bookings exist
 (#20791)

 chrono/manager/forms.py | 34 +++++++++++++++++++++-
 tests/test_manager.py   | 75 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+), 1 deletion(-)
chrono/manager/forms.py
19 19

  
20 20
from django import forms
21 21
from django.forms import ValidationError
22
from django.utils.timezone import localtime, make_aware, now
22 23
from django.utils.translation import ugettext_lazy as _
23 24

  
24 25
from chrono.agendas.models import (Event, MeetingType, TimePeriod, Desk,
25
                                   TimePeriodException)
26
                                   TimePeriodException, Booking)
26 27

  
27 28
from . import widgets
28 29

  
......
76 77
        }
77 78
        exclude = []
78 79

  
80
    def clean(self):
81
        cleaned_data = super(TimePeriodForm, self).clean()
82
        if not self.are_changes_valid():
83
            raise ValidationError(_('One or several bookings exist within this time period.'))
84
        return cleaned_data
85

  
86
    def are_changes_valid(self):
87
        if not self.instance.desk_id:
88
            return True
89
        has_booking = self.has_booking_out_of_bounds()
90
        if self.cleaned_data['start_time'] > self.instance.start_time:
91
            return not(has_booking)
92
        if self.cleaned_data['end_time'] < self.instance.end_time:
93
            return not(has_booking)
94
        return True
95

  
96
    def has_booking_out_of_bounds(self):
97
        bookings = Booking.objects.filter(
98
            event__start_datetime__gte=now(),
99
            event__desk=self.instance.desk, cancellation_datetime__isnull=True).select_related('event')
100
        for booking in bookings:
101
            event_startdt = booking.event.start_datetime
102
            event_enddt = booking.event.end_datetime
103
            if event_startdt.weekday() != self.instance.weekday:
104
                continue
105
            start = make_aware(datetime.datetime.combine(event_startdt, self.cleaned_data['start_time']))
106
            end = make_aware(datetime.datetime.combine(event_enddt, self.cleaned_data['end_time']))
107
            if (event_startdt < start) or (event_enddt) > end:
108
                return True
109
        return False
110

  
79 111

  
80 112
class NewDeskForm(forms.ModelForm):
81 113
    class Meta:
tests/test_manager.py
1127 1127
    mocked_get.side_effect = mocked_requests_http_ssl_error
1128 1128
    resp = resp.form.submit(status=200)
1129 1129
    assert 'Failed to retrieve remote calendar (SSL error).' in resp.content
1130

  
1131

  
1132
@mock.patch('chrono.manager.forms.now', lambda: datetime.datetime(2017, 5, 20, 10, 23))
1133
def test_prevent_time_period_changes_when_bookings_exist(app, admin_user):
1134
    agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
1135
    desk = Desk.objects.create(agenda=agenda, label='Desk A')
1136
    meeting_type = MeetingType(agenda=agenda, label='Blah', duration=30)
1137
    meeting_type.save()
1138
    timeperiod = TimePeriod.objects.create(
1139
        weekday=1, desk=desk, start_time=datetime.time(8, 00), end_time=datetime.time(11, 0))
1140
    event = Event.objects.create(agenda=agenda, places=1, desk=desk, meeting_type=meeting_type,
1141
                                 start_datetime=make_aware(datetime.datetime(2017, 5, 22, 8, 30)))
1142
    Booking.objects.create(event=event)
1143
    event = Event.objects.create(agenda=agenda, places=1, desk=desk, meeting_type=meeting_type,
1144
                                 start_datetime=make_aware(datetime.datetime(2017, 5, 23, 8, 30)))
1145
    Booking.objects.create(event=event)
1146
    login(app)
1147
    timeperiod_edit_link = "/manage/timeperiods/%d/edit" % timeperiod.pk
1148
    # extend time period start
1149
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1150
    resp = resp.click(href=timeperiod_edit_link)
1151
    resp.form['start_time'] = '7:30'
1152
    resp = resp.form.submit().follow()
1153
    assert resp.html.find('a', {'href': timeperiod_edit_link}).text.strip() == u'Tuesday / 7:30 a.m. \u2192 11 a.m.'
1154
    # shorten time period start at booking's bound
1155
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1156
    resp = resp.click(href=timeperiod_edit_link)
1157
    resp.form['start_time'] = '8:30'
1158
    resp = resp.form.submit().follow()
1159
    assert resp.html.find('a', {'href': timeperiod_edit_link}).text.strip() == u'Tuesday / 8:30 a.m. \u2192 11 a.m.'
1160
    # shorten time period start
1161
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1162
    resp = resp.click(href=timeperiod_edit_link)
1163
    resp.form['start_time'] = '9:30'
1164
    resp = resp.form.submit()
1165
    error_message = resp.html.find('ul', {'class': 'errorlist'}).text.strip()
1166
    assert error_message == 'One or several bookings exist within this time period.'
1167
    # extend time period end
1168
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1169
    resp = resp.click(href=timeperiod_edit_link)
1170
    resp.form['end_time'] = '12:30'
1171
    resp = resp.form.submit().follow()
1172
    assert resp.html.find('a', {'href': timeperiod_edit_link}).text.strip() == u'Tuesday / 8:30 a.m. \u2192 12:30 p.m.'
1173
    event = Event.objects.create(agenda=agenda, places=1, desk=desk, meeting_type=meeting_type,
1174
                                 start_datetime=make_aware(datetime.datetime(2017, 5, 23, 11, 30)))
1175
    Booking.objects.create(event=event)
1176
    # shorten time period end at booking's bound
1177
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1178
    resp = resp.click(href=timeperiod_edit_link)
1179
    resp.form['end_time'] = '12:00'
1180
    resp = resp.form.submit().follow()
1181
    assert resp.html.find('a', {'href': timeperiod_edit_link}).text.strip() == u'Tuesday / 8:30 a.m. \u2192 noon'
1182
    # shorten time period end
1183
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1184
    resp = resp.click(href=timeperiod_edit_link)
1185
    resp.form['end_time'] = '11:00'
1186
    resp = resp.form.submit()
1187
    error_message = resp.html.find('ul', {'class': 'errorlist'}).text.strip()
1188
    assert error_message == 'One or several bookings exist within this time period.'
1189
    # extend both time period start and end
1190
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1191
    resp = resp.click(href=timeperiod_edit_link)
1192
    resp.form['start_time'] = '7:00'
1193
    resp.form['end_time'] = '12:30'
1194
    resp = resp.form.submit().follow()
1195
    assert resp.html.find('a', {'href': timeperiod_edit_link}).text.strip() == u'Tuesday / 7 a.m. \u2192 12:30 p.m.'
1196
    # shorten both time period start and end
1197
    Booking.objects.create(event=event)
1198
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1199
    resp = resp.click(href=timeperiod_edit_link)
1200
    resp.form['start_time'] = '8:00'
1201
    resp.form['end_time'] = '11:00'
1202
    resp = resp.form.submit()
1203
    error_message = resp.html.find('ul', {'class': 'errorlist'}).text.strip()
1204
    assert error_message == 'One or several bookings exist within this time period.'
1130
-