diff --git a/bin/mkdiagram b/bin/mkdiagram index ef50ce673..4f015c0ab 100755 --- a/bin/mkdiagram +++ b/bin/mkdiagram @@ -28,17 +28,16 @@ export PYTHONPATH="$PWD/.." echo "Validating..." ./manage.py validate -echo "Dump tables" -./manage.py sql $apps > tables.sql export PYTHONPATH=`dirname $PWD` module=${PWD##*/} export DJANGO_SETTINGS_MODULE=$module.settings export graph export title + echo "Generate model graph" graph="models-with-names-and-events" title="New IETF Database schema" -modelviz.py --exclude="$proxy,$legacy" --title "$title" $apps > $graph.dot && dot -Tpng $graph.dot > $graph.png +${0%/*}/../ietf/manage.py graph_models --exclude="$proxy,$legacy" --title "$title" $apps > $graph.dot && dot -Tpng $graph.dot > $graph.png echo "Generate new model without names" graph="models-with-names" diff --git a/ietf/meeting/forms.py b/ietf/meeting/forms.py index b4884b7b8..ce5d303be 100644 --- a/ietf/meeting/forms.py +++ b/ietf/meeting/forms.py @@ -180,6 +180,12 @@ class InterimMeetingModelForm(forms.ModelForm): return self.cleaned_data + def is_virtual(self): + if not self.is_bound or self.data.get('in_person'): + return False + else: + return True + def set_group_options(self): '''Set group options based on user accessing the form''' if has_role(self.user, "Secretariat"): @@ -242,8 +248,8 @@ class InterimSessionModelForm(forms.ModelForm): self.user = kwargs.pop('user') if 'group' in kwargs: self.group = kwargs.pop('group') - if 'is_approved' in kwargs: - self.is_approved = kwargs.pop('is_approved') + if 'is_approved_or_virtual' in kwargs: + self.is_approved_or_virtual = kwargs.pop('is_approved_or_virtual') super(InterimSessionModelForm, self).__init__(*args, **kwargs) self.is_edit = bool(self.instance.pk) # setup fields that aren't intrinsic to the Session object @@ -267,7 +273,7 @@ class InterimSessionModelForm(forms.ModelForm): """NOTE: as the baseform of an inlineformset self.save(commit=True) never gets called""" session = super(InterimSessionModelForm, self).save(commit=kwargs.get('commit', True)) - if self.is_approved: + if self.is_approved_or_virtual: session.status_id = 'scheda' else: session.status_id = 'apprw' diff --git a/ietf/meeting/helpers.py b/ietf/meeting/helpers.py index 23c604772..944c8dd4a 100644 --- a/ietf/meeting/helpers.py +++ b/ietf/meeting/helpers.py @@ -563,13 +563,13 @@ def send_interim_approval_request(meetings): cc=cc_list) def send_interim_announcement_request(meeting): - """Sends an email to the secretariat that approval has been granted for an - interim meeting which includes the link to send the official announcement""" + """Sends an email to the secretariat that an interim meeting is ready for + announcement, includes the link to send the official announcement""" group = meeting.session_set.first().group requester = meeting.session_set.first().requested_by (to_email, cc_list) = gather_address_lists('interim_approved') from_email = ('"IETF Meeting Session Request Tool"','session_request_developers@ietf.org') - subject = '{group} - Interim Meeting Approved'.format(group=group.acronym) + subject = '{group} - interim meeting ready for announcement'.format(group=group.acronym) template = 'meeting/interim_announcement_request.txt' announce_url = settings.IDTRACKER_BASE_URL + reverse('ietf.meeting.views.interim_request_details', kwargs={'number': meeting.number}) context = locals() diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index 9bc9ea712..d4e2170ca 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -599,7 +599,7 @@ class InterimTests(TestCase): for session in meeting.session_set.all(): self.assertEqual(session.status.slug, 'scheda') self.assertEqual(len(outbox), length_before + 1) - self.assertTrue('Approved' in outbox[-1]['Subject']) + self.assertTrue('ready for announcement' in outbox[-1]['Subject']) def test_interim_approve_by_secretariat(self): make_meeting_test_data() @@ -682,7 +682,7 @@ class InterimTests(TestCase): len(q("#id_group option")) - 1) # -1 for options placeholder - def test_interim_request_single(self): + def test_interim_request_single_virtual(self): make_meeting_test_data() group = Group.objects.get(acronym='mars') date = datetime.date.today() + datetime.timedelta(days=30) @@ -692,7 +692,8 @@ class InterimTests(TestCase): remote_instructions = 'Use webex' agenda = 'Intro. Slides. Discuss.' agenda_note = 'On second level' - self.client.login(username="secretary", password="secretary+password") + length_before = len(outbox) + self.client.login(username="marschairman", password="marschairman+password") data = {'group':group.pk, 'meeting_type':'single', 'city':'', @@ -710,7 +711,6 @@ class InterimTests(TestCase): 'session_set-MAX_NUM_FORMS':1000} r = self.client.post(urlreverse("ietf.meeting.views.interim_request"),data) - self.assertRedirects(r,urlreverse('ietf.meeting.views.upcoming')) meeting = Meeting.objects.order_by('id').last() self.assertEqual(meeting.type_id,'interim') @@ -722,6 +722,7 @@ class InterimTests(TestCase): session = meeting.session_set.first() self.assertEqual(session.remote_instructions,remote_instructions) self.assertEqual(session.agenda_note,agenda_note) + self.assertEqual(session.status.slug,'scheda') timeslot = session.official_timeslotassignment().timeslot self.assertEqual(timeslot.time,dt) self.assertEqual(timeslot.duration,duration) @@ -730,6 +731,10 @@ class InterimTests(TestCase): doc = session.materials.first() path = os.path.join(doc.get_file_path(),doc.filename_with_rev()) self.assertTrue(os.path.exists(path)) + # check notice to secretariat + self.assertEqual(len(outbox), length_before + 1) + self.assertTrue('interim meeting ready for announcement' in outbox[-1]['Subject']) + self.assertTrue('iesg-secretary@ietf.org' in outbox[-1]['To']) def test_interim_request_single_in_person(self): make_meeting_test_data() diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 052789ae1..ae41a0255 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -1319,6 +1319,7 @@ def interim_request(request): if form.is_valid() and formset.is_valid(): group = form.cleaned_data.get('group') is_approved = form.cleaned_data.get('approved', False) + is_virtual = form.is_virtual() meeting_type = form.cleaned_data.get('meeting_type') # pre create meeting @@ -1330,14 +1331,16 @@ def interim_request(request): InterimSessionModelForm, user=request.user, group=group, - is_approved=is_approved)) + is_approved_or_virtual=(is_approved or is_virtual))) formset = SessionFormset(instance=meeting, data=request.POST) formset.is_valid() formset.save() sessions_post_save(formset) - if not is_approved: + if not (is_approved or is_virtual): send_interim_approval_request(meetings=[meeting]) + elif not has_role(request.user, 'Secretariat'): + send_interim_announcement_request(meeting=meeting) # series require special handling, each session gets it's own # meeting object we won't see this on edit because series are @@ -1348,7 +1351,7 @@ def interim_request(request): InterimSessionModelForm, user=request.user, group=group, - is_approved=is_approved)) + is_approved_or_virtual=(is_approved or is_virtual))) formset = SessionFormset(instance=Meeting(), data=request.POST) formset.is_valid() # re-validate for session_form in formset.forms: @@ -1365,8 +1368,10 @@ def interim_request(request): series.append(meeting) sessions_post_save([session_form]) - if not is_approved: + if not (is_approved or is_virtual): send_interim_approval_request(meetings=series) + elif not has_role(request.user, 'Secretariat'): + send_interim_announcement_request(meeting=meeting) messages.success(request, 'Interim meeting request submitted') return redirect(upcoming) @@ -1465,7 +1470,7 @@ def interim_request_edit(request, number): InterimSessionModelForm, user=request.user, group=group, - is_approved=is_approved)) + is_approved_or_virtual=is_approved)) formset = SessionFormset(instance=meeting, data=request.POST) if form.is_valid() and formset.is_valid(): diff --git a/ietf/templates/meeting/interim_announcement_request.txt b/ietf/templates/meeting/interim_announcement_request.txt index fd87ff1ea..cbdb331ae 100644 --- a/ietf/templates/meeting/interim_announcement_request.txt +++ b/ietf/templates/meeting/interim_announcement_request.txt @@ -1,5 +1,5 @@ {% load ams_filters %}{% load ietf_filters %} -An interim meeting for {{ group.acronym }} has just been approved. +An interim meeting for {{ group.acronym }} has been approved or does not require approval and is ready for announcement. Use this link to officially announce the meeting: {{ announce_url }}