From c9d944b31255a46853e232610a35f16e7c1141d0 Mon Sep 17 00:00:00 2001
From: Robert Sparks <rjsparks@nostrum.com>
Date: Wed, 8 Jan 2020 19:51:14 +0000
Subject: [PATCH] Make it easier for the nomcom chair to manage generic IESG
 requirements. Fixes #2794. Commit ready for merge.  - Legacy-Id: 17201

---
 ietf/dbtemplate/fixtures/nomcom_templates.xml |  6 ++++
 .../0008_add_default_iesg_req_template.py     | 32 +++++++++++++++++++
 ietf/nomcom/forms.py                          |  4 +--
 .../management/commands/make_dummy_nomcom.py  |  4 +--
 .../0007_position_is_iesg_position.py         | 21 ++++++++++++
 ietf/nomcom/models.py                         | 18 ++++++++---
 ietf/nomcom/test_data.py                      |  5 +--
 ietf/nomcom/utils.py                          |  6 ++--
 .../nomcom/iesg_position_requirements.html    | 12 +++++++
 ietf/templates/nomcom/list_positions.html     |  2 +-
 ietf/templates/nomcom/requirements.html       | 11 +++++++
 11 files changed, 108 insertions(+), 13 deletions(-)
 create mode 100644 ietf/dbtemplate/migrations/0008_add_default_iesg_req_template.py
 create mode 100644 ietf/nomcom/migrations/0007_position_is_iesg_position.py
 create mode 100644 ietf/templates/nomcom/iesg_position_requirements.html

diff --git a/ietf/dbtemplate/fixtures/nomcom_templates.xml b/ietf/dbtemplate/fixtures/nomcom_templates.xml
index b13f4db00..369cad73c 100644
--- a/ietf/dbtemplate/fixtures/nomcom_templates.xml
+++ b/ietf/dbtemplate/fixtures/nomcom_templates.xml
@@ -181,4 +181,10 @@ The questionaire is repeated below for your convenience.
 Describe the topic and add any information/instructions for the responder here.
 </field>
     </object>
+    <object pk="13" model="dbtemplate.dbtemplate">
+        <field type="CharField" name="path">/nomcom/defaults/iesg_requirements</field>
+        <field type="CharField" name="title">Generic IESG Requirements</field>
+        <field to="name.dbtemplatetypename" name="type" rel="ManyToOneRel">rst</field>
+        <field type="TextField" name="content">Generic IESG Requirements Yo!</field>
+    </object>
 </django-objects>
diff --git a/ietf/dbtemplate/migrations/0008_add_default_iesg_req_template.py b/ietf/dbtemplate/migrations/0008_add_default_iesg_req_template.py
new file mode 100644
index 000000000..0fe0d04fe
--- /dev/null
+++ b/ietf/dbtemplate/migrations/0008_add_default_iesg_req_template.py
@@ -0,0 +1,32 @@
+# Copyright The IETF Trust 2020, All Rights Reserved
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.27 on 2020-01-07 09:25
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+def forward(apps, schema_editor):
+    DBTemplate = apps.get_model('dbtemplate', 'DBTemplate')
+    DBTemplate.objects.create(path='/nomcom/defaults/iesg_requirements', type_id='rst', title='Generic IESG requirements',
+                              content="""=============================
+IESG MEMBER DESIRED EXPERTISE
+=============================
+
+Place this years Generic IESG Member Desired Expertise here.
+
+This template uses reStructured text for formatting. Feel free to use it (to change the above header for example). 
+""")
+
+def reverse(apps, schema_editor):
+    DBTemplate = apps.get_model('dbtemplate', 'DBTemplate')
+    DBTemplate.objects.filter(path='/nomcom/defaults/iesg_requirements').delete()
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('dbtemplate', '0007_adjust_review_assigned'),
+    ]
+
+    operations = [
+        migrations.RunPython(forward, reverse)
+    ]
diff --git a/ietf/nomcom/forms.py b/ietf/nomcom/forms.py
index 30ef70176..fe8942bbc 100644
--- a/ietf/nomcom/forms.py
+++ b/ietf/nomcom/forms.py
@@ -1,4 +1,4 @@
-# Copyright The IETF Trust 2012-2019, All Rights Reserved
+# Copyright The IETF Trust 2012-2020, All Rights Reserved
 # -*- coding: utf-8 -*-
 
 
@@ -603,7 +603,7 @@ class PositionForm(forms.ModelForm):
 
     class Meta:
         model = Position
-        fields = ('name', 'is_open', 'accepting_nominations', 'accepting_feedback')
+        fields = ('name', 'is_iesg_position', 'is_open', 'accepting_nominations', 'accepting_feedback')
 
     def __init__(self, *args, **kwargs):
         self.nomcom = kwargs.pop('nomcom', None)
diff --git a/ietf/nomcom/management/commands/make_dummy_nomcom.py b/ietf/nomcom/management/commands/make_dummy_nomcom.py
index 92d71dcac..2e34aba6a 100644
--- a/ietf/nomcom/management/commands/make_dummy_nomcom.py
+++ b/ietf/nomcom/management/commands/make_dummy_nomcom.py
@@ -1,4 +1,4 @@
-# Copyright The IETF Trust 2017-2019, All Rights Reserved
+# Copyright The IETF Trust 2017-2020, All Rights Reserved
 # -*- coding: utf-8 -*-
 
 
@@ -56,7 +56,7 @@ class Command(BaseCommand):
                 e.person.user.set_password('password')
                 e.person.user.save()
                 NomineePositionFactory(nominee__nomcom=nc, nominee__person=e.person,
-                                       position__nomcom=nc, position__name='Dummy Area Director',
+                                       position__nomcom=nc, position__name='Dummy Area Director', position__is_iesg_position=True,
                                       )
 
                 self.stdout.write("%s\n" % key)
diff --git a/ietf/nomcom/migrations/0007_position_is_iesg_position.py b/ietf/nomcom/migrations/0007_position_is_iesg_position.py
new file mode 100644
index 000000000..25ebb48f9
--- /dev/null
+++ b/ietf/nomcom/migrations/0007_position_is_iesg_position.py
@@ -0,0 +1,21 @@
+# Copyright The IETF Trust 2020, All Rights Reserved
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.27 on 2020-01-07 14:41
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('nomcom', '0006_auto_20190716_1216'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='position',
+            name='is_iesg_position',
+            field=models.BooleanField(default=False, verbose_name='Is IESG Position'),
+        ),
+    ]
diff --git a/ietf/nomcom/models.py b/ietf/nomcom/models.py
index 8b852415e..1ba9448de 100644
--- a/ietf/nomcom/models.py
+++ b/ietf/nomcom/models.py
@@ -1,4 +1,4 @@
-# Copyright The IETF Trust 2012-2019, All Rights Reserved
+# Copyright The IETF Trust 2012-2020, All Rights Reserved
 # -*- coding: utf-8 -*-
 from __future__ import absolute_import, print_function, unicode_literals
 
@@ -202,6 +202,7 @@ class Position(models.Model):
     is_open = models.BooleanField(verbose_name='Is open', default=False, help_text="Set is_open when the nomcom is working on a position. Clear it when an appointment is confirmed.")
     accepting_nominations = models.BooleanField(verbose_name='Is accepting nominations', default=False)
     accepting_feedback = models.BooleanField(verbose_name='Is accepting feedback', default=False)
+    is_iesg_position = models.BooleanField(verbose_name='Is IESG Position', default=False)
 
     objects = PositionManager()
 
@@ -235,10 +236,19 @@ class Position(models.Model):
         return render_to_string(self.questionnaire.path, {'position': self})
 
     def get_requirement(self):
-        rendered = render_to_string(self.requirement.path, {'position': self})
+        specific_reqs = render_to_string(self.requirement.path, {'position': self})
         if self.requirement.type_id=='plain':
-            rendered = linebreaks(rendered)
-        return rendered
+            specific_reqs = linebreaks(specific_reqs)
+
+        generic_iesg_template = DBTemplate.objects.filter(group=self.nomcom.group,path__endswith='iesg_requirements').first()
+
+        if self.is_iesg_position and generic_iesg_template:
+            generic_iesg_reqs = render_to_string(generic_iesg_template.path, {})
+            if generic_iesg_template.type_id=='plain':
+                generic_iesg_reqs = linebreaks(generic_iesg_reqs)
+            return render_to_string("nomcom/iesg_position_requirements.html", dict(position=self, generic_iesg_reqs=generic_iesg_reqs, specific_reqs=specific_reqs))
+        else:
+            return specific_reqs
 
 @python_2_unicode_compatible
 class Topic(models.Model):
diff --git a/ietf/nomcom/test_data.py b/ietf/nomcom/test_data.py
index 072f43e92..30b61e34f 100644
--- a/ietf/nomcom/test_data.py
+++ b/ietf/nomcom/test_data.py
@@ -1,4 +1,4 @@
-# Copyright The IETF Trust 2012-2019, All Rights Reserved
+# Copyright The IETF Trust 2012-2020, All Rights Reserved
 # -*- coding: utf-8 -*-
 
 
@@ -141,7 +141,8 @@ def nomcom_test_data():
                                                            name=name,
                                                            is_open=True,
                                                            accepting_nominations=True,
-                                                           accepting_feedback=True)
+                                                           accepting_feedback=True,
+                                                           is_iesg_position= POSITIONS.index(name) < 9)
 
     ChangeStateGroupEvent.objects.get_or_create(group=group,
                                                 type="changed_state",
diff --git a/ietf/nomcom/utils.py b/ietf/nomcom/utils.py
index 5f8da9b06..670cfbfc0 100644
--- a/ietf/nomcom/utils.py
+++ b/ietf/nomcom/utils.py
@@ -1,4 +1,4 @@
-# Copyright The IETF Trust 2012-2019, All Rights Reserved
+# Copyright The IETF Trust 2012-2020, All Rights Reserved
 # -*- coding: utf-8 -*-
 
 
@@ -47,6 +47,7 @@ NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE = 'email/questionnaire_reminder.txt'
 NOMINATION_RECEIPT_TEMPLATE = 'email/nomination_receipt.txt'
 FEEDBACK_RECEIPT_TEMPLATE = 'email/feedback_receipt.txt'
 DESCRIPTION_TEMPLATE = 'topic/description'
+IESG_GENERIC_REQUIREMENTS_TEMPLATE = 'iesg_requirements'
 
 DEFAULT_NOMCOM_TEMPLATES = [HOME_TEMPLATE,
                             INEXISTENT_PERSON_TEMPLATE,
@@ -55,7 +56,8 @@ DEFAULT_NOMCOM_TEMPLATES = [HOME_TEMPLATE,
                             NOMINEE_ACCEPT_REMINDER_TEMPLATE,
                             NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE,
                             NOMINATION_RECEIPT_TEMPLATE,
-                            FEEDBACK_RECEIPT_TEMPLATE]
+                            FEEDBACK_RECEIPT_TEMPLATE,
+                            IESG_GENERIC_REQUIREMENTS_TEMPLATE]
 
 
 def get_nomcom_by_year(year):
diff --git a/ietf/templates/nomcom/iesg_position_requirements.html b/ietf/templates/nomcom/iesg_position_requirements.html
new file mode 100644
index 000000000..e78a35996
--- /dev/null
+++ b/ietf/templates/nomcom/iesg_position_requirements.html
@@ -0,0 +1,12 @@
+<div class="panel panel-default">
+  <div class="panel-heading"><a data-toggle="collapse" href="#generic_iesg_reqs" id="generic_iesg_reqs_header">General IESG Requirements</a></div>
+  <div id="generic_iesg_reqs" class="panel-body collapse in">
+    {{generic_iesg_reqs|safe}}
+  </div>
+</div>
+<div class="panel panel-default">
+  <div class="panel-heading">{{position.name}} Specific Requirements</div>
+  <div class="panel-body">
+    {{specific_reqs|safe}}
+  </div>
+</div>
\ No newline at end of file
diff --git a/ietf/templates/nomcom/list_positions.html b/ietf/templates/nomcom/list_positions.html
index 66bd222a1..d71815fca 100644
--- a/ietf/templates/nomcom/list_positions.html
+++ b/ietf/templates/nomcom/list_positions.html
@@ -20,7 +20,7 @@
       <div class="panel-heading"><h3>{{ group.grouper| yesno:"Open Positions,Closed Positions"}}</h3></div>
       <div class="panel-body">
       {% for position in group.list %}
-      <h4>{{ position.name }}</h4>
+      <h4>{{ position.name }}{% if position.is_iesg_position %} (IESG){% endif %}</h4>
       {% if group.grouper %}
         <dl class="dl-horizontal">
           <dt>Accepting</dt>
diff --git a/ietf/templates/nomcom/requirements.html b/ietf/templates/nomcom/requirements.html
index 0b0ced68e..8f779e98c 100644
--- a/ietf/templates/nomcom/requirements.html
+++ b/ietf/templates/nomcom/requirements.html
@@ -32,3 +32,14 @@
   </div>
 
 {% endblock %}
+
+{% block js %}
+<script>
+  $('.collapse').collapse()
+  var header = $('#generic_iesg_reqs_header')
+  header.addClass('fa')
+  header.addClass('fa-caret-right')
+  header.text(' '+header.text()+' (click to expand)')
+</script>
+{% endblock %}
+