diff --git a/ietf/meeting/forms.py b/ietf/meeting/forms.py index 15d3576fd..3618ce59a 100644 --- a/ietf/meeting/forms.py +++ b/ietf/meeting/forms.py @@ -3,6 +3,7 @@ import codecs from django import forms from django.db.models import Q +from django.forms import BaseInlineFormSet from ietf.doc.models import Document, DocAlias, State, NewRevisionDocEvent from ietf.doc.utils import get_document_content @@ -36,6 +37,29 @@ class GroupModelChoiceField(forms.ModelChoiceField): # Forms # ------------------------------------------------- +class InterimSessionInlineFormSet(BaseInlineFormSet): + def __init__(self, *args, **kwargs): + super(InterimSessionInlineFormSet, self).__init__(*args, **kwargs) + if 'data' in kwargs: + self.meeting_type = kwargs['data']['meeting_type'] + + def clean(self): + '''Custom clean method to verify dates are consecutive for multi-day meetings''' + super(InterimSessionInlineFormSet, self).clean() + if self.meeting_type == 'multi-day': + dates = [] + for form in self.forms: + date = form.cleaned_data.get('date') + if date: + dates.append(date) + if len(dates) < 2: + return + dates.sort() + last_date = dates[0] + for date in dates[1:]: + if last_date.day + 1 != date.day: + raise forms.ValidationError('For Multi-Day meetings, days must be consecutive') + last_date = date class InterimMeetingModelForm(forms.ModelForm): group = GroupModelChoiceField(queryset=Group.objects.filter(type__in=('wg', 'rg'), state__in=('active', 'proposed', 'bof')).order_by('acronym'), required=False) diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index 2f4788c65..798ca00ac 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -993,6 +993,43 @@ class InterimTests(TestCase): self.assertEqual(timeslot.duration,duration) self.assertEqual(session.agenda_note,agenda_note) + def test_interim_request_multi_day_non_consecutive(self): + make_meeting_test_data() + date = datetime.date.today() + datetime.timedelta(days=30) + date2 = date + datetime.timedelta(days=2) + time = datetime.datetime.now().time().replace(microsecond=0,second=0) + group = Group.objects.get(acronym='mars') + city = 'San Francisco' + country = 'US' + time_zone = 'US/Pacific' + remote_instructions = 'Use webex' + agenda = 'Intro. Slides. Discuss.' + agenda_note = 'On second level' + self.client.login(username="secretary", password="secretary+password") + data = {'group':group.pk, + 'meeting_type':'multi-day', + 'city':city, + 'country':country, + 'time_zone':time_zone, + 'session_set-0-date':date.strftime("%Y-%m-%d"), + 'session_set-0-time':time.strftime('%H:%M'), + 'session_set-0-requested_duration':'03:00:00', + 'session_set-0-remote_instructions':remote_instructions, + 'session_set-0-agenda':agenda, + 'session_set-0-agenda_note':agenda_note, + 'session_set-1-date':date2.strftime("%Y-%m-%d"), + 'session_set-1-time':time.strftime('%H:%M'), + 'session_set-1-requested_duration':'03:00:00', + 'session_set-1-remote_instructions':remote_instructions, + 'session_set-1-agenda':agenda, + 'session_set-1-agenda_note':agenda_note, + 'session_set-TOTAL_FORMS':2, + 'session_set-INITIAL_FORMS':0} + + r = self.client.post(urlreverse("ietf.meeting.views.interim_request"),data) + self.assertEqual(r.status_code, 200) + self.assertTrue('days must be consecutive' in r.content) + def test_interim_request_series(self): make_meeting_test_data() meeting_count_before = Meeting.objects.filter(type='interim').count() diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index f0bf08ec9..e1a8c12c5 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -66,7 +66,7 @@ from ietf.utils.pdf import pdf_pages from ietf.utils.text import xslugify from .forms import (InterimMeetingModelForm, InterimAnnounceForm, InterimSessionModelForm, - InterimCancelForm) + InterimCancelForm, InterimSessionInlineFormSet) def get_menu_entries(request): @@ -1743,6 +1743,7 @@ def interim_request(request): Meeting, Session, form=InterimSessionModelForm, + formset=InterimSessionInlineFormSet, can_delete=False, extra=2) if request.method == 'POST': diff --git a/ietf/templates/meeting/interim_request.html b/ietf/templates/meeting/interim_request.html index f29018e19..042373dcb 100644 --- a/ietf/templates/meeting/interim_request.html +++ b/ietf/templates/meeting/interim_request.html @@ -40,15 +40,13 @@
Meeting Type:
- - -