Merged in [13324] from rcross@amsl.com:

Disallow multi-day interim meetings with non-consecutive dates.  Fixes #2193.
 - Legacy-Id: 13325
Note: SVN reference [13324] has been migrated to Git commit 75a7beb596
This commit is contained in:
Henrik Levkowetz 2017-05-11 20:15:49 +00:00
commit db40ddc231
4 changed files with 76 additions and 9 deletions

View file

@ -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)

View file

@ -995,6 +995,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()

View file

@ -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':

View file

@ -40,15 +40,13 @@
<div class="col-md-2 radio-inline"><strong>Meeting Type:</strong></div>
<label class="radio-inline">
<input type="radio" value="single" checked="checked" name="meeting_type">Single
</label>
<label class="radio-inline">
<input type="radio" value="multi-day" name="meeting_type">Multi-Day
</label>
<label class="radio-inline">
<input type="radio" value="series" name="meeting_type">Series
{% for radio in form.meeting_type %}
<label class="radio-inline" for="{{ radio.id_for_label }}">
{{ radio.tag }}
{{ radio.choice_label }}
</label>
{% endfor %}
</div> <!-- col-md-offset-2 -->
</div> <!-- form-group form-inline -->
@ -89,6 +87,13 @@
</div>
{{ formset.management_form }}
{% if formset.non_form_errors %}
<div class="form-group alert alert-danger">
{{ formset.non_form_errors }}
</div>
{% endif %}
{% for form in formset %}
<div class="fieldset{% if forloop.last %} template{% endif %}" >