diff --git a/ietf/meeting/forms.py b/ietf/meeting/forms.py index 4a3b1e1f7..4537e2172 100644 --- a/ietf/meeting/forms.py +++ b/ietf/meeting/forms.py @@ -191,7 +191,7 @@ class InterimSessionForm(forms.Form): def _save_agenda(self, text): pass - def save(self, request, group, meeting): + def save(self, request, group, meeting, is_approved): person = request.user.person agenda = self.cleaned_data.get('agenda') agenda_note = self.cleaned_data.get('agenda_note') @@ -199,12 +199,16 @@ class InterimSessionForm(forms.Form): time = self.cleaned_data.get('time') duration = self.cleaned_data.get('duration') remote_instructions = self.cleaned_data.get('remote_instructions') - time=datetime.datetime.combine(date, time) + time = datetime.datetime.combine(date, time) + if is_approved: + status_id = 'scheda' + else: + status_id = 'apprw' session = Session.objects.create(meeting=meeting, group=group, requested_by=person, requested_duration=duration, - status_id='apprw', + status_id=status_id, type_id='session', remote_instructions=remote_instructions, agenda_note=agenda_note,) diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index ecbce5b2c..a5dcdfe17 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -6,6 +6,7 @@ import urlparse from django.core.urlresolvers import reverse as urlreverse from django.conf import settings from django.contrib.auth.models import User +from django.http import HttpRequest from pyquery import PyQuery @@ -14,6 +15,7 @@ from ietf.group.models import Group from ietf.meeting.helpers import can_approve_interim_request, can_view_interim_request from ietf.meeting.models import Session, TimeSlot, Meeting from ietf.meeting.test_data import make_meeting_test_data +from ietf.name.models import SessionStatusName from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent class MeetingTests(TestCase): @@ -339,13 +341,43 @@ class EditTests(TestCase): # ------------------------------------------------- class InterimTests(TestCase): + def test_interim_announce(self): + make_meeting_test_data() + url = urlreverse("ietf.meeting.views.interim_announce") + meeting = Meeting.objects.filter(type='interim',session__group__acronym='mars').first() + session = meeting.session_set.first() + session.status = SessionStatusName.objects.get(slug='scheda') + session.save() + login_testing_unauthorized(self,"secretary",url) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + self.assertTrue(meeting.number in r.content) + + def test_interim_send_announcement(self): + make_meeting_test_data() + meeting = Meeting.objects.filter(type='interim',session__status='apprw',session__group__acronym='mars').first() + url = urlreverse("ietf.meeting.views.interim_send_announcement", kwargs={'number':meeting.number}) + login_testing_unauthorized(self,"secretary",url) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + + def test_interim_approve(self): + make_meeting_test_data() + meeting = Meeting.objects.filter(type='interim',session__status='apprw',session__group__acronym='mars').first() + url = urlreverse('ietf.meeting.views.interim_request_details',kwargs={'number':meeting.number}) + login_testing_unauthorized(self,"secretary",url) + r = self.client.post(url,{'approve':'approve'}) + self.assertRedirects(r,urlreverse('ietf.meeting.views.interim_send_announcement',kwargs={'number':meeting.number})) + for session in meeting.session_set.all(): + self.assertEqual(session.status.slug,'scheda') + def test_upcoming(self): make_meeting_test_data() r = self.client.get("/meeting/upcoming/") self.assertEqual(r.status_code, 200) today = datetime.date.today() - mars_interim = Meeting.objects.filter(date__gt=today,type='interim',number__contains='mars').first() - ames_interim = Meeting.objects.filter(date__gt=today,type='interim',number__contains='ames').first() + mars_interim = Meeting.objects.filter(date__gt=today,type='interim',session__group__acronym='mars',session__status='sched').first() + ames_interim = Meeting.objects.filter(date__gt=today,type='interim',session__group__acronym='ames',session__status='canceled').first() self.assertTrue(mars_interim.number in r.content) self.assertTrue(ames_interim.number in r.content) # cancelled session diff --git a/ietf/meeting/urls.py b/ietf/meeting/urls.py index 39c7e5576..a384312d5 100644 --- a/ietf/meeting/urls.py +++ b/ietf/meeting/urls.py @@ -68,8 +68,10 @@ urlpatterns = [ url(r'^(?P\d+)/', include(type_ietf_only_patterns)), url(r'^upcoming/$', views.upcoming), url(r'^upcoming.ics/$', views.ical_upcoming), - url(r'^interim/request/(?P[A-Za-z0-9._+-]+)/$', views.interim_request_details), + url(r'^interim/announce/$', views.interim_announce), + url(r'^interim/announce/(?P[A-Za-z0-9._+-]+)/$', views.interim_send_announcement), url(r'^interim/request/$', views.interim_request), + url(r'^interim/request/(?P[A-Za-z0-9._+-]+)/$', views.interim_request_details), url(r'^interim/pending/$', views.interim_pending), url(r'^$', views.current_materials), ] diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 0858b992b..2b589e5af 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -903,6 +903,21 @@ def ajax_get_utc(request): context_data = {'timezone':timezone,'time':time,'utc':utc} return HttpResponse(json.dumps(context_data),content_type='application/json') + +@role_required('Secretariat',) +def interim_announce(request): + '''View which shows interim meeting requests awaiting announcement''' + meetings = Meeting.objects.filter(type='interim',session__status='scheda') + + return render(request, "meeting/interim_announce.html", {"meetings":meetings}) + +@role_required('Secretariat',) +def interim_send_announcement(request,number): + '''View for sending the announcement of a new interim meeting''' + meeting = get_object_or_404(Meeting,number=number) + + return render(request, "meeting/interim_send_announcement.html") + @role_required('Area Director','Secretariat','IRTF Chair','WG Chair','RG Chair') def interim_pending(request): '''View which shows interim meeting requests pending approval''' @@ -926,6 +941,7 @@ def interim_request(request): #person = request.user.person if form.is_valid() and formset.is_valid(): group = form.cleaned_data.get('group') + is_approved = form.cleaned_data.get('approved', False) meeting_type = form.cleaned_data.get('meeting_type') # pre create meeting @@ -939,7 +955,7 @@ def interim_request(request): continue if meeting_type == 'series': meeting = create_interim_meeting_from_forms(form,f) - f.save(request,group,meeting) + f.save(request,group,meeting,is_approved) return redirect(upcoming) else: assert False, (form.errors, formset.errors) @@ -957,6 +973,16 @@ def interim_request_details(request, number): can_edit = can_view_interim_request(meeting,request.user) can_approve = can_approve_interim_request(meeting,request.user) + if request.method == 'POST': + if request.POST.get('approve'): + meeting.session_set.update(status_id='scheda') + if has_role(request.user, 'Secretariat'): + return redirect(interim_send_announcement, number=number) + if request.POST.get('disapprove'): + pass + if request.POST.get('cancel'): + pass + return render(request, "meeting/interim_request_details.html",{ "meeting":meeting, "sessions":sessions, @@ -976,7 +1002,7 @@ def ical_upcoming(request): def upcoming(request): '''List of upcoming meetings''' today = datetime.datetime.today() - meetings = Meeting.objects.filter(date__gte=today).order_by('date') + meetings = Meeting.objects.filter(date__gte=today,session__status__in=('sched','canceled')).order_by('date') # extract groups hierarchy seen = set() diff --git a/ietf/name/fixtures/names.json b/ietf/name/fixtures/names.json index 0f355ee2f..4480780a5 100644 --- a/ietf/name/fixtures/names.json +++ b/ietf/name/fixtures/names.json @@ -2022,6 +2022,16 @@ "model": "name.sessionstatusname", "pk": "sched" }, +{ + "fields": { + "order": 0, + "used": true, + "name": "Scheduled - Announcement to be sent", + "desc": "" + }, + "model": "name.sessionstatusname", + "pk": "scheda" +}, { "fields": { "order": 0, diff --git a/ietf/name/migrations/0011_add_session_status.py b/ietf/name/migrations/0011_add_session_status.py new file mode 100644 index 000000000..87049f4a9 --- /dev/null +++ b/ietf/name/migrations/0011_add_session_status.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + +def populate_names(apps, schema_editor): + SessionStatusName = apps.get_model("name", "SessionStatusName") + SessionStatusName.objects.create(slug="scheda",name="Scheduled - Announcement to be sent") + + +class Migration(migrations.Migration): + + dependencies = [ + ('name', '0010_new_liaison_names'), + ] + + operations = [ + migrations.RunPython(populate_names), + ] diff --git a/ietf/templates/meeting/interim_announce.html b/ietf/templates/meeting/interim_announce.html new file mode 100644 index 000000000..7a40b811b --- /dev/null +++ b/ietf/templates/meeting/interim_announce.html @@ -0,0 +1,55 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2015, All Rights Reserved #} +{% load origin %} +{% load staticfiles bootstrap3 widget_tweaks %} + +{% block title %}Announce Interim Meeting{% endblock %} + +{% block pagehead %} + + +{% endblock %} + +{% block content %} + {% origin %} +

Announce Interim Meeting

+ + {% if meetings %} + + + + + + + + + + {% for meeting in meetings %} + {% if meeting.type.slug == 'interim' %} + + {% else %} + + {% endif %} + + {% if meeting.type.slug == 'interim' %} + + {% else %} + + {% endif %} + + + {% endfor %} + +
DateGroupName
{{ meeting.date }}{{ meeting.session_set.all.0.group.acronym }}ietf + {{ meeting.number }} +
+ {% else %} +

No interim meetings waiting announcement

+ {% endif %} + +{% endblock %} + +{% block js %} + + +{% endblock %} diff --git a/ietf/templates/meeting/interim_request_details.html b/ietf/templates/meeting/interim_request_details.html index 0436d0e0d..c310da9ab 100644 --- a/ietf/templates/meeting/interim_request_details.html +++ b/ietf/templates/meeting/interim_request_details.html @@ -18,6 +18,8 @@
{{ sessions.0.group.acronym }}
Requested By
{{ sessions.0.requested_by }} +
Status
+
{{ sessions.0.status }}
City
{{ meeting.city }}
Country
@@ -44,7 +46,8 @@ Edit {% endif %} {% if can_approve %} - + + {% endif %} {% if can_edit %} diff --git a/ietf/templates/meeting/interim_send_announcement.html b/ietf/templates/meeting/interim_send_announcement.html new file mode 100644 index 000000000..3cdbca020 --- /dev/null +++ b/ietf/templates/meeting/interim_send_announcement.html @@ -0,0 +1,23 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2015, All Rights Reserved #} +{% load origin %} +{% load staticfiles bootstrap3 widget_tweaks %} + +{% block title %}Announce Interim Meeting{% endblock %} + +{% block pagehead %} + + +{% endblock %} + +{% block content %} + {% origin %} +

Announce Interim Meeting

+ + +{% endblock %} + +{% block js %} + + +{% endblock %}