Skip to content

Commit 75a7beb

Browse files
committed
Disallow multi-day interim meetings with non-consecutive dates. Fixes ietf-tools#2193. Commit ready for merge.
- Legacy-Id: 13324
1 parent a35cb5f commit 75a7beb

4 files changed

Lines changed: 76 additions & 9 deletions

File tree

ietf/meeting/forms.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from django import forms
55
from django.db.models import Q
6+
from django.forms import BaseInlineFormSet
67

78
from ietf.doc.models import Document, DocAlias, State, NewRevisionDocEvent
89
from ietf.doc.utils import get_document_content
@@ -36,6 +37,29 @@ def label_from_instance(self, obj):
3637
# Forms
3738
# -------------------------------------------------
3839

40+
class InterimSessionInlineFormSet(BaseInlineFormSet):
41+
def __init__(self, *args, **kwargs):
42+
super(InterimSessionInlineFormSet, self).__init__(*args, **kwargs)
43+
if 'data' in kwargs:
44+
self.meeting_type = kwargs['data']['meeting_type']
45+
46+
def clean(self):
47+
'''Custom clean method to verify dates are consecutive for multi-day meetings'''
48+
super(InterimSessionInlineFormSet, self).clean()
49+
if self.meeting_type == 'multi-day':
50+
dates = []
51+
for form in self.forms:
52+
date = form.cleaned_data.get('date')
53+
if date:
54+
dates.append(date)
55+
if len(dates) < 2:
56+
return
57+
dates.sort()
58+
last_date = dates[0]
59+
for date in dates[1:]:
60+
if last_date.day + 1 != date.day:
61+
raise forms.ValidationError('For Multi-Day meetings, days must be consecutive')
62+
last_date = date
3963

4064
class InterimMeetingModelForm(forms.ModelForm):
4165
group = GroupModelChoiceField(queryset=Group.objects.filter(type__in=('wg', 'rg'), state__in=('active', 'proposed', 'bof')).order_by('acronym'), required=False)

ietf/meeting/tests_views.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,43 @@ def test_interim_request_multi_day(self):
993993
self.assertEqual(timeslot.duration,duration)
994994
self.assertEqual(session.agenda_note,agenda_note)
995995

996+
def test_interim_request_multi_day_non_consecutive(self):
997+
make_meeting_test_data()
998+
date = datetime.date.today() + datetime.timedelta(days=30)
999+
date2 = date + datetime.timedelta(days=2)
1000+
time = datetime.datetime.now().time().replace(microsecond=0,second=0)
1001+
group = Group.objects.get(acronym='mars')
1002+
city = 'San Francisco'
1003+
country = 'US'
1004+
time_zone = 'US/Pacific'
1005+
remote_instructions = 'Use webex'
1006+
agenda = 'Intro. Slides. Discuss.'
1007+
agenda_note = 'On second level'
1008+
self.client.login(username="secretary", password="secretary+password")
1009+
data = {'group':group.pk,
1010+
'meeting_type':'multi-day',
1011+
'city':city,
1012+
'country':country,
1013+
'time_zone':time_zone,
1014+
'session_set-0-date':date.strftime("%Y-%m-%d"),
1015+
'session_set-0-time':time.strftime('%H:%M'),
1016+
'session_set-0-requested_duration':'03:00:00',
1017+
'session_set-0-remote_instructions':remote_instructions,
1018+
'session_set-0-agenda':agenda,
1019+
'session_set-0-agenda_note':agenda_note,
1020+
'session_set-1-date':date2.strftime("%Y-%m-%d"),
1021+
'session_set-1-time':time.strftime('%H:%M'),
1022+
'session_set-1-requested_duration':'03:00:00',
1023+
'session_set-1-remote_instructions':remote_instructions,
1024+
'session_set-1-agenda':agenda,
1025+
'session_set-1-agenda_note':agenda_note,
1026+
'session_set-TOTAL_FORMS':2,
1027+
'session_set-INITIAL_FORMS':0}
1028+
1029+
r = self.client.post(urlreverse("ietf.meeting.views.interim_request"),data)
1030+
self.assertEqual(r.status_code, 200)
1031+
self.assertTrue('days must be consecutive' in r.content)
1032+
9961033
def test_interim_request_series(self):
9971034
make_meeting_test_data()
9981035
meeting_count_before = Meeting.objects.filter(type='interim').count()

ietf/meeting/views.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
from ietf.utils.text import xslugify
6767

6868
from .forms import (InterimMeetingModelForm, InterimAnnounceForm, InterimSessionModelForm,
69-
InterimCancelForm)
69+
InterimCancelForm, InterimSessionInlineFormSet)
7070

7171

7272
def get_menu_entries(request):
@@ -1743,6 +1743,7 @@ def interim_request(request):
17431743
Meeting,
17441744
Session,
17451745
form=InterimSessionModelForm,
1746+
formset=InterimSessionInlineFormSet,
17461747
can_delete=False, extra=2)
17471748

17481749
if request.method == 'POST':

ietf/templates/meeting/interim_request.html

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,13 @@ <h1>Interim Meeting Request</h1>
4040

4141
<div class="col-md-2 radio-inline"><strong>Meeting Type:</strong></div>
4242

43-
<label class="radio-inline">
44-
<input type="radio" value="single" checked="checked" name="meeting_type">Single
45-
</label>
46-
<label class="radio-inline">
47-
<input type="radio" value="multi-day" name="meeting_type">Multi-Day
48-
</label>
49-
<label class="radio-inline">
50-
<input type="radio" value="series" name="meeting_type">Series
43+
{% for radio in form.meeting_type %}
44+
<label class="radio-inline" for="{{ radio.id_for_label }}">
45+
{{ radio.tag }}
46+
{{ radio.choice_label }}
5147
</label>
48+
{% endfor %}
49+
5250
</div> <!-- col-md-offset-2 -->
5351
</div> <!-- form-group form-inline -->
5452

@@ -81,6 +79,13 @@ <h1>Interim Meeting Request</h1>
8179
</div>
8280

8381
{{ formset.management_form }}
82+
83+
{% if formset.non_form_errors %}
84+
<div class="form-group alert alert-danger">
85+
{{ formset.non_form_errors }}
86+
</div>
87+
{% endif %}
88+
8489
{% for form in formset %}
8590
<div class="fieldset{% if forloop.last %} template{% endif %}" >
8691

0 commit comments

Comments
 (0)