From 5f182d24e4116cacdec41de38d1e483ed6ebbada Mon Sep 17 00:00:00 2001 From: Josue Kouka Date: Tue, 19 Dec 2017 14:50:38 +0100 Subject: [PATCH] manager: prevent time period changes when bookings exist (#20791) --- chrono/manager/forms.py | 21 ++++++++++++++++++++- tests/test_manager.py | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/chrono/manager/forms.py b/chrono/manager/forms.py index 00f5363..813570a 100644 --- a/chrono/manager/forms.py +++ b/chrono/manager/forms.py @@ -19,10 +19,11 @@ import datetime from django import forms from django.forms import ValidationError +from django.utils.timezone import localtime from django.utils.translation import ugettext_lazy as _ from chrono.agendas.models import (Event, MeetingType, TimePeriod, Desk, - TimePeriodException) + TimePeriodException, Booking) from . import widgets @@ -76,6 +77,24 @@ class TimePeriodForm(forms.ModelForm): } exclude = [] + def clean(self): + cleaned_data = super(TimePeriodForm, self).clean() + if hasattr(self.instance, 'desk'): + if not self.changes_ok(): + raise ValidationError(_('One or several bookings exist within this time preiod.')) + return cleaned_data + + def changes_ok(self): + bookings = Booking.objects.filter( + event__desk=self.instance.desk, cancellation_datetime__isnull=True).select_related('event') + for booking in bookings: + event_startdt = localtime(booking.event.start_datetime) + if event_startdt.weekday() != self.instance.weekday: + continue + if self.instance.start_time <= event_startdt.time() < self.instance.end_time: + return False + return True + class NewDeskForm(forms.ModelForm): class Meta: diff --git a/tests/test_manager.py b/tests/test_manager.py index 7283c4e..9d2b494 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -1127,3 +1127,22 @@ def test_agenda_import_time_period_exception_from_remote_ics_with_ssl_error(mock mocked_get.side_effect = mocked_requests_http_ssl_error resp = resp.form.submit(status=200) assert 'Failed to retrieve remote calendar (SSL error).' in resp.content + + +def test_prevent_time_period_changes_when_bookings_exist(app, admin_user): + agenda = Agenda.objects.create(label='Foo bar', kind='meetings') + desk = Desk.objects.create(agenda=agenda, label='Desk A') + MeetingType(agenda=agenda, label='Blah').save() + timeperiod = TimePeriod.objects.create( + weekday=1, desk=desk, start_time=datetime.time(7, 30), end_time=datetime.time(12, 0)) + event = Event.objects.create(agenda=agenda, places=1, desk=desk, + start_datetime=datetime.datetime(2017, 5, 23, 8, 30)) + Booking.objects.create(event=event) + login(app) + resp = app.get('/manage/agendas/%d/' % agenda.pk) + resp = resp.click(href="/manage/timeperiods/%d/edit" % timeperiod.pk) + resp.form['start_time'] = '9:30' + resp.form['end_time'] = '12:00' + resp = resp.form.submit() + error_message = resp.html.find('ul', {'class': 'errorlist'}).text + assert error_message == 'One or several bookings exist within this time preiod.' -- 2.11.0