From b350f2256981c6d93e769fba63ec73d05c6f2e1d Mon Sep 17 00:00:00 2001
From: Jorran de Wit <jorrandewit@outlook.com>
Date: Sun, 4 Jun 2017 22:37:03 +0200
Subject: [PATCH] General improvements

---
 partners/constants.py                         | 14 ++--
 partners/forms.py                             |  8 +-
 partners/managers.py                          |  8 ++
 .../migrations/0008_auto_20170604_2228.py     | 48 ++++++++++++
 partners/models.py                            | 56 ++++++-------
 .../partners/_prospective_partner_card.html   | 45 ++++++-----
 .../partners/add_prospartner_contact.html     | 33 ++++----
 .../partners/add_prospective_partner.html     | 19 +++--
 .../templates/partners/manage_partners.html   | 78 +++++++++----------
 .../partners/supporting_partners.html         | 16 ++--
 partners/urls.py                              | 13 +---
 partners/views.py                             | 52 +++++--------
 12 files changed, 220 insertions(+), 170 deletions(-)
 create mode 100644 partners/managers.py
 create mode 100644 partners/migrations/0008_auto_20170604_2228.py

diff --git a/partners/constants.py b/partners/constants.py
index 104cbbf0f..5c63ec8a9 100644
--- a/partners/constants.py
+++ b/partners/constants.py
@@ -1,6 +1,7 @@
 import datetime
 
 
+PARTNER_KIND_UNI_LIBRARY = 'Univ. Library'
 PARTNER_KINDS = (
     ('Res. Inst.', 'Research Institute'),
     ('Int. Fund. Agency', 'International Funding Agency'),
@@ -8,17 +9,18 @@ PARTNER_KINDS = (
     ('Nat. Lab.', 'National Laboratory'),
     ('Nat. Library', 'National Library'),
     ('Nat. Acad.', 'National Academy'),
-    ('Univ. Library', 'University (and its Library)'),
+    (PARTNER_KIND_UNI_LIBRARY, 'University (and its Library)'),
     ('Res. Library', 'Research Library'),
     ('Prof. Soc.', 'Professional Society'),
     ('Foundation', 'Foundation'),
     ('Individual', 'Individual'),
 )
 
-
+PROSPECTIVE_PARTNER_REQUESTED = 'requested'
+PROSPECTIVE_PARTNER_ADDED = 'added'
 PROSPECTIVE_PARTNER_STATUS = (
-    ('requested', 'Requested (from online form)'),
-    ('added', 'Added internally'),
+    (PROSPECTIVE_PARTNER_REQUESTED, 'Requested (from online form)'),
+    (PROSPECTIVE_PARTNER_ADDED, 'Added internally'),
     ('processed', 'Processed into Partner object'),
 )
 
@@ -50,9 +52,9 @@ PARTNER_EVENTS = (
     ('comment', 'Comment added'),
 )
 
-
+MEMBERSHIP_SUBMITTED = 'Submitted'
 MEMBERSHIP_AGREEMENT_STATUS = (
-    ('Submitted', 'Request submitted by Partner'),
+    (MEMBERSHIP_SUBMITTED, 'Request submitted by Partner'),
     ('Pending', 'Sent to Partner, response pending'),
     ('Signed', 'Signed by Partner'),
     ('Honoured', 'Honoured: payment of Partner received'),
diff --git a/partners/forms.py b/partners/forms.py
index e25909625..fa766263a 100644
--- a/partners/forms.py
+++ b/partners/forms.py
@@ -6,8 +6,7 @@ from django_countries.widgets import CountrySelectWidget
 from django_countries.fields import LazyTypedChoiceField
 
 from .constants import PARTNER_KINDS
-from .models import Partner, ProspectivePartner, ProspectiveContact, \
-    ProspectivePartnerEvent, MembershipAgreement
+from .models import Partner, ProspectivePartner, ProspectiveContact, ProspectivePartnerEvent
 
 from scipost.models import TITLE_CHOICES
 
@@ -30,8 +29,7 @@ class ProspectivePartnerForm(forms.ModelForm):
     """
     class Meta:
         model = ProspectivePartner
-        exclude = ['date_received', 'date_processed']
-        widgets = {'status': forms.HiddenInput()}
+        fields = ('kind', 'institution_name', 'country')
 
 
 class ProspectiveContactForm(forms.ModelForm):
@@ -44,7 +42,7 @@ class ProspectiveContactForm(forms.ModelForm):
 class ProspectivePartnerEventForm(forms.ModelForm):
     class Meta:
         model = ProspectivePartnerEvent
-        exclude = ['prospartner', 'noted_on', 'noted_by']
+        fields = ('event', 'comments')
         widgets = {
             'comments': forms.Textarea(attrs={'cols': 16, 'rows': 3}),
         }
diff --git a/partners/managers.py b/partners/managers.py
new file mode 100644
index 000000000..53729dc30
--- /dev/null
+++ b/partners/managers.py
@@ -0,0 +1,8 @@
+from django.db import models
+
+from .constants import MEMBERSHIP_SUBMITTED
+
+
+class MembershipAgreementManager(models.Manager):
+    def submitted(self):
+        return self.filter(status=MEMBERSHIP_SUBMITTED)
diff --git a/partners/migrations/0008_auto_20170604_2228.py b/partners/migrations/0008_auto_20170604_2228.py
new file mode 100644
index 000000000..c62a4d9c2
--- /dev/null
+++ b/partners/migrations/0008_auto_20170604_2228.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-06-04 20:28
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0007_auto_20170604_0629'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='institution',
+            name='address',
+            field=models.CharField(blank=True, default='', max_length=1000),
+            preserve_default=False,
+        ),
+        migrations.AlterField(
+            model_name='partnerevent',
+            name='comments',
+            field=models.TextField(blank=True, default=''),
+            preserve_default=False,
+        ),
+        migrations.AlterField(
+            model_name='partnerevent',
+            name='noted_on',
+            field=models.DateTimeField(auto_now_add=True),
+        ),
+        migrations.AlterField(
+            model_name='prospectivepartner',
+            name='date_received',
+            field=models.DateTimeField(auto_now_add=True),
+        ),
+        migrations.AlterField(
+            model_name='prospectivepartnerevent',
+            name='comments',
+            field=models.TextField(blank=True, default=''),
+            preserve_default=False,
+        ),
+        migrations.AlterField(
+            model_name='prospectivepartnerevent',
+            name='noted_on',
+            field=models.DateTimeField(auto_now_add=True),
+        ),
+    ]
diff --git a/partners/models.py b/partners/models.py
index b773bcc1d..8c5777ade 100644
--- a/partners/models.py
+++ b/partners/models.py
@@ -1,15 +1,15 @@
 from django.contrib.auth.models import User
 from django.db import models
-from django.utils import timezone
 
 from django_countries.fields import CountryField
 
-from .constants import PARTNER_KINDS, PARTNER_STATUS, CONSORTIUM_STATUS,\
-    PROSPECTIVE_PARTNER_STATUS, PROSPECTIVE_PARTNER_EVENTS, PARTNER_EVENTS,\
-    MEMBERSHIP_AGREEMENT_STATUS, MEMBERSHIP_DURATION
+from .constants import PARTNER_KINDS, PARTNER_STATUS, CONSORTIUM_STATUS, MEMBERSHIP_DURATION,\
+                       PROSPECTIVE_PARTNER_STATUS, PROSPECTIVE_PARTNER_EVENTS, PARTNER_EVENTS,\
+                       MEMBERSHIP_AGREEMENT_STATUS, PROSPECTIVE_PARTNER_ADDED,\
+                       PARTNER_KIND_UNI_LIBRARY
+from .managers import MembershipAgreementManager
 
 from scipost.constants import TITLE_CHOICES
-from scipost.models import Contributor
 
 
 ########################
@@ -20,20 +20,20 @@ class ProspectivePartner(models.Model):
     """
     Created from the membership_request page, after submitting a query form.
     """
-    kind = models.CharField(max_length=32, choices=PARTNER_KINDS,
-                            default='Univ. Library')
+    kind = models.CharField(max_length=32, choices=PARTNER_KINDS, default=PARTNER_KIND_UNI_LIBRARY)
     institution_name = models.CharField(max_length=256)
     country = CountryField()
-    date_received = models.DateTimeField(default=timezone.now)
+    date_received = models.DateTimeField(auto_now_add=True)
     date_processed = models.DateTimeField(blank=True, null=True)
     status = models.CharField(max_length=32, choices=PROSPECTIVE_PARTNER_STATUS,
-                              default='added')
+                              default=PROSPECTIVE_PARTNER_ADDED)
 
     def __str__(self):
         return '%s (received %s), %s' % (self.institution_name,
                                          self.date_received.strftime("%Y-%m-%d"),
                                          self.get_status_display())
 
+
 class ProspectiveContact(models.Model):
     """
     A ProspectiveContact is a person's name and contact details, with a
@@ -41,7 +41,7 @@ class ProspectiveContact(models.Model):
     It does not have a corresponding User object.
     It is meant to be used internally at SciPost, during Partner mining.
     """
-    prospartner = models.ForeignKey(ProspectivePartner, on_delete=models.CASCADE)
+    prospartner = models.ForeignKey('partners.ProspectivePartner', on_delete=models.CASCADE)
     title = models.CharField(max_length=4, choices=TITLE_CHOICES)
     first_name = models.CharField(max_length=64)
     last_name = models.CharField(max_length=64)
@@ -50,11 +50,11 @@ class ProspectiveContact(models.Model):
 
 
 class ProspectivePartnerEvent(models.Model):
-    prospartner = models.ForeignKey(ProspectivePartner, on_delete=models.CASCADE)
+    prospartner = models.ForeignKey('partners.ProspectivePartner', on_delete=models.CASCADE)
     event = models.CharField(max_length=64, choices=PROSPECTIVE_PARTNER_EVENTS)
-    comments = models.TextField(blank=True, null=True)
-    noted_on = models.DateTimeField(default=timezone.now)
-    noted_by = models.ForeignKey(Contributor, on_delete=models.CASCADE)
+    comments = models.TextField(blank=True)
+    noted_on = models.DateTimeField(auto_now_add=True)
+    noted_by = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE)
 
     def __str__(self):
         return '%s: %s' % (str(self.prospective_partner), self.get_event_display())
@@ -71,7 +71,7 @@ class Institution(models.Model):
     kind = models.CharField(max_length=32, choices=PARTNER_KINDS)
     name = models.CharField(max_length=256)
     acronym = models.CharField(max_length=16)
-    address = models.CharField(max_length=1000, blank=True, null=True)
+    address = models.CharField(max_length=1000, blank=True)
     country = CountryField()
 
     def __str__(self):
@@ -98,16 +98,16 @@ class Partner(models.Model):
     Supporting Partners.
     These are the official Partner objects created by SciPost Admin.
     """
-    institution = models.ForeignKey(Institution, on_delete=models.CASCADE,
+    institution = models.ForeignKey('partners.Institution', on_delete=models.CASCADE,
                                     blank=True, null=True)
     status = models.CharField(max_length=16, choices=PARTNER_STATUS)
-    main_contact = models.ForeignKey(Contact, on_delete=models.CASCADE,
+    main_contact = models.ForeignKey('partners.Contact', on_delete=models.CASCADE,
                                      blank=True, null=True,
                                      related_name='partner_main_contact')
-    financial_contact = models.ForeignKey(Contact, on_delete=models.CASCADE,
+    financial_contact = models.ForeignKey('partners.Contact', on_delete=models.CASCADE,
                                           blank=True, null=True,
                                           related_name='partner_financial_contact')
-    technical_contact = models.ForeignKey(Contact, on_delete=models.CASCADE,
+    technical_contact = models.ForeignKey('partners.Contact', on_delete=models.CASCADE,
                                           blank=True, null=True,
                                           related_name='partner_technical_contact')
 
@@ -118,11 +118,11 @@ class Partner(models.Model):
 
 
 class PartnerEvent(models.Model):
-    partner = models.ForeignKey(Partner, on_delete=models.CASCADE)
+    partner = models.ForeignKey('partners.Partner', on_delete=models.CASCADE)
     event = models.CharField(max_length=64, choices=PARTNER_EVENTS)
-    comments = models.TextField(blank=True, null=True)
-    noted_on = models.DateTimeField(default=timezone.now)
-    noted_by = models.ForeignKey(Contributor, on_delete=models.CASCADE)
+    comments = models.TextField(blank=True)
+    noted_on = models.DateTimeField(auto_now_add=True)
+    noted_by = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE)
 
     def __str__(self):
         return '%s: %s' % (str(self.partner), self.get_event_display())
@@ -133,7 +133,7 @@ class Consortium(models.Model):
     Collection of Partners.
     """
     name = models.CharField(max_length=128)
-    partners = models.ManyToManyField(Partner, blank=True)
+    partners = models.ManyToManyField('partners.Partner', blank=True)
     status = models.CharField(max_length=16, choices=CONSORTIUM_STATUS)
 
     class Meta:
@@ -145,14 +145,18 @@ class MembershipAgreement(models.Model):
     Agreement for membership of the Supporting Partners Board.
     A new instance is created each time an Agreement is made or renewed.
     """
-    partner = models.ForeignKey(Partner, on_delete=models.CASCADE, blank=True, null=True)
-    consortium = models.ForeignKey(Consortium, on_delete=models.CASCADE, blank=True, null=True)
+    partner = models.ForeignKey('partners.Partner', on_delete=models.CASCADE,
+                                blank=True, null=True)
+    consortium = models.ForeignKey('partners.Consortium', on_delete=models.CASCADE,
+                                   blank=True, null=True)
     status = models.CharField(max_length=16, choices=MEMBERSHIP_AGREEMENT_STATUS)
     date_requested = models.DateField()
     start_date = models.DateField()
     duration = models.DurationField(choices=MEMBERSHIP_DURATION)
     offered_yearly_contribution = models.SmallIntegerField(default=0)
 
+    objects = MembershipAgreementManager()
+
     def __str__(self):
         return (str(self.partner) +
                 ' [' + self.get_duration_display() +
diff --git a/partners/templates/partners/_prospective_partner_card.html b/partners/templates/partners/_prospective_partner_card.html
index d83086ead..0cac1a900 100644
--- a/partners/templates/partners/_prospective_partner_card.html
+++ b/partners/templates/partners/_prospective_partner_card.html
@@ -2,10 +2,10 @@
 
 <div class="card-block">
   <div class="row">
-    <div class="col-1">
+    <div class="col-md-1">
       <p>{{ pp.country }}</p>
     </div>
-    <div class="col-4">
+    <div class="col-md-4">
       <h3>{{ pp.institution_name }}</h3>
       <p>({{ pp.get_kind_display }})</p>
       <p>Received {{ pp.date_received }}</p>
@@ -14,24 +14,29 @@
       {% endif %}
       <p>{{ pp.get_status_display }}</p>
     </div>
-    <div class="col-4">
+    <div class="col-md-7">
       <h3>Contacts:</h3>
-      <ul class="list-group list-group-flush">
-	{% for contact in pp.prospectivecontact_set.all %}
-	<li class="list-group-item flex-column align-items-start">
-	  <p>Role: {{ contact.role }}</p>
-	  <p>{{ contact.get_title_display }} {{ contact.first_name }} {{ contact.last_name }}</p>
-	  <p>{{ contact.email }}</p>
-	</li>
-	{% endfor %}
-      </ul>
-    </div>
-    <div class="col-3">
-      <ul class="list-group list-group-flush">
-	<li class="list-group-item">
-	  <a href="{% url 'partners:add_prospartner_contact' prospartner_id=pp.id %}">Add a contact</a>
-	</li>
-      </ul>
+      <a class="d-inline-block mb-2" href="{% url 'partners:add_prospartner_contact' prospartner_id=pp.id %}">Add a contact</a>
+        <table class="table">
+            <thead>
+                <th>Role</th>
+                <th>Contact</th>
+                <th>Email</th>
+            </thead>
+            <tbody>
+        	{% for contact in pp.prospectivecontact_set.all %}
+            	<tr>
+            	  <td>{{ contact.role }}</td>
+            	  <td>{{ contact.get_title_display }} {{ contact.first_name }} {{ contact.last_name }}</td>
+            	  <td>{{ contact.email }}</td>
+              </tr>
+            {% empty %}
+                <tr>
+                    <td colspan="3">No contacts found, <a href="{% url 'partners:add_prospartner_contact' prospartner_id=pp.id %}">add a contact</a>.</td>
+                </tr>
+        	{% endfor %}
+            </tbody>
+        </table>
     </div>
   </div>
 
@@ -52,7 +57,7 @@
       <form action="{% url 'partners:add_prospartner_event' prospartner_id=pp.id %}" method="post">
 	{% csrf_token %}
 	{{ ppevent_form|bootstrap }}
-	<input type="submit" name="submit" value="Submit">
+	<input type="submit" name="submit" value="Submit" class="btn btn-secondary">
       </form>
     </div>
   </div>
diff --git a/partners/templates/partners/add_prospartner_contact.html b/partners/templates/partners/add_prospartner_contact.html
index bad159fd6..d0f72fcd0 100644
--- a/partners/templates/partners/add_prospartner_contact.html
+++ b/partners/templates/partners/add_prospartner_contact.html
@@ -6,25 +6,26 @@
 
 {% block content %}
 
-<section>
-  <div class="flex-container">
-    <div class="flex-greybox">
-      <h1>Add a Contact for a Prospective Partner</h1>
+<div class="row">
+    <div class="col-12">
+        <h1 class="highlight">Add a Contact for a Prospective Partner</h1>
     </div>
-  </div>
+</div>
 
-  <h3>Add a contact for {{ prospartner.institution_name }}:</h3>
-  <br/>
-  <form action="{% url 'partners:add_prospartner_contact' prospartner_id=prospartner.id %}" method="post">
-    {% csrf_token %}
-    {{ form|bootstrap }}
-    <input class="btn btn-primary" type="submit" value="Submit"/>
-  </form>
+<div class="row">
+    <div class="col-12">
+      <h3>Add a contact for {{ prospartner.institution_name }}:</h3>
 
-  {% if errormessage %}
-  <p class="text-danger">{{ errormessage }}</p>
-  {% endif %}
+      <form action="{% url 'partners:add_prospartner_contact' prospartner_id=prospartner.id %}" method="post">
+        {% csrf_token %}
+        {{ form|bootstrap }}
+        <input class="btn btn-primary" type="submit" value="Submit"/>
+      </form>
 
-</section>
+      {% if errormessage %}
+      <p class="text-danger">{{ errormessage }}</p>
+      {% endif %}
+    </div>
+</div>
 
 {% endblock content %}
diff --git a/partners/templates/partners/add_prospective_partner.html b/partners/templates/partners/add_prospective_partner.html
index 737780443..8475f8374 100644
--- a/partners/templates/partners/add_prospective_partner.html
+++ b/partners/templates/partners/add_prospective_partner.html
@@ -6,13 +6,15 @@
 
 {% block content %}
 
-<section>
-  <div class="flex-container">
-    <div class="flex-greybox">
-      <h1>Add a Prospective Partner</h1>
+<div class="row">
+    <div class="col-12">
+        <h1 class="highlight">Add a Prospective Partner</h1>
     </div>
-  </div>
-  <p>Please provide contact details of an appropriate representative, and details about the potential Partner.</p>
+</div>
+
+<div class="row">
+    <div class="col-12">
+        <p>Please provide contact details of an appropriate representative, and details about the potential Partner.</p>
 
     <form action="{% url 'partners:add_prospective_partner' %}" method="post">
       {% csrf_token %}
@@ -21,9 +23,10 @@
     </form>
 
     {% if errormessage %}
-    <p class="text-danger">{{ errormessage }}</p>
+        <p class="text-danger">{{ errormessage }}</p>
     {% endif %}
 
-</section>
+    </div>
+</div>
 
 {% endblock content %}
diff --git a/partners/templates/partners/manage_partners.html b/partners/templates/partners/manage_partners.html
index 9cfa3e406..666d85ce0 100644
--- a/partners/templates/partners/manage_partners.html
+++ b/partners/templates/partners/manage_partners.html
@@ -5,14 +5,14 @@
 
 {% block content %}
 
-  <div class="row">
+<div class="row">
     <div class="col-12">
       <h1 class="highlight">Partners Management Page</h1>
     </div>
-  </div>
+</div>
 
 
-  <div class="row">
+<div class="row">
     <div class="col-12">
       <div class="tab-nav-container">
 	<div class="tab-nav-inner">
@@ -30,48 +30,46 @@
 	</div>
       </div>
     </div>
-  </div>
+</div>
 
   <div class="tab-content">
     <div class="tab-pane active" id="prospartners" role="tabpanel">
-      <div class="row">
-	<div class="col-12">
-	  <h2 class="highlight">Prospective Partners</h2>
-	</div>
-      </div>
-      <h3><a href="{% url 'partners:add_prospective_partner' %}">Add a prospective partner</a></h3>
-      <br/>
+          <div class="row">
+        	<div class="col-12">
+        	  <h2 class="highlight">Prospective Partners</h2>
+        	</div>
+          </div>
+          <h3><a href="{% url 'partners:add_prospective_partner' %}">Add a prospective partner</a></h3>
+          <br/>
 
-      <div class="row">
-	<div class="col-2">Country</div>
-	<div class="col-3">Institution name</div>
-	<div class="col-3">Kind</div>
-	<div class="col-3">Status</div>
-	<div class="col-1">Date received</div>
-      </div>
+          <table class="table table-hover">
+              <thead class="thead-default">
+                  <tr>
+                	<th>Country</th>
+                	<th>Institution name</th>
+                	<th>Kind</th>
+                	<th>Status</th>
+                	<th>Date received</th>
+                </tr>
+              </thead>
 
-      <div id="accordion" role="tablist" aria-multiselectable="true">
-	{% for partner in prospective_partners %}
-	<div class="card">
-	  <div class="card-header" role="tab" id="heading{{ partner.id }}">
-	    <h4 class="mb-0">
-	      <a data-toggle="collapse" data-parent="#accordion" href="#collapse{{ partner.id }}" aria-expanded="true" aria-controls="collapse{{ partner.id }}">
-		<div class="row">
-		  <div class="col-2">{{ partner.get_country_display }}</div>
-		  <div class="col-3">{{ partner.institution_name }}</div>
-		  <div class="col-3">{{ partner.get_kind_display }}</div>
-		  <div class="col-3">{{ partner.get_status_display }}</div>
-		  <div class="col-1">{{ partner.date_received|date:"Y-m-d" }}</div>
-		</div>
-	      </a>
-	    </h4>
-	  </div>
-	  <div id="collapse{{ partner.id }}" class="collapse" role="tabpanel" aria-labelledby="heading{{ partner.id}}">
-	    {% include 'partners/_prospective_partner_card.html' with pp=partner %}
-	  </div>
-	</div>
-	{% endfor %}
-      </div>
+              <tbody id="accordion" role="tablist" aria-multiselectable="true">
+                {% for partner in prospective_partners %}
+        	      <tr data-toggle="collapse" data-parent="#accordion" href="#collapse{{ partner.id }}" aria-expanded="true" aria-controls="collapse{{ partner.id }}" style="cursor: pointer;">
+                		  <td>{{ partner.get_country_display }}</td>
+                		  <td>{{ partner.institution_name }}</td>
+                		  <td>{{ partner.get_kind_display }}</td>
+                		  <td>{{ partner.get_status_display }}</td>
+                		  <td>{{ partner.date_received|date:"Y-m-d" }}</td>
+                	</tr>
+                    <tr id="collapse{{ partner.id }}" class="collapse" role="tabpanel" aria-labelledby="heading{{ partner.id}}" style="background-color: #fff;">
+                        <td colspan="5">
+                    	    {% include 'partners/_prospective_partner_card.html' with pp=partner %}
+                        </td>
+                    </tr>
+            	{% endfor %}
+            </tbody>
+        </table>
     </div>
 
     <div class="tab-pane" id="partners" role="tabpanel">
diff --git a/partners/templates/partners/supporting_partners.html b/partners/templates/partners/supporting_partners.html
index eb9090b0e..e6e6a4eda 100644
--- a/partners/templates/partners/supporting_partners.html
+++ b/partners/templates/partners/supporting_partners.html
@@ -118,17 +118,15 @@
 </div>
 
 
-{% if request.user|is_in_group:'Editorial Administrators' %}
+{% if prospective_partners %}
 <div class="row">
     <div class="col-12">
-      <h1 class="highglight">Prospective Partners</h1>
-  <ul>
-    {% for agreement in prospective_agreements %}
-        <li>{{ agreement }}</li>
-    {% empty %}
-        <li>No agreements found</li>
-    {% endfor %}
-  </ul>
+      <h1 class="highlight">Prospective Partners</h1>
+      <ul>
+        {% for agreement in prospective_agreements %}
+            <li>{{ agreement }}</li>
+        {% endfor %}
+      </ul>
     </div>
 </div>
 
diff --git a/partners/urls.py b/partners/urls.py
index f49cd75db..a03e61ffa 100644
--- a/partners/urls.py
+++ b/partners/urls.py
@@ -3,18 +3,13 @@ from django.conf.urls import url
 from . import views
 
 urlpatterns = [
-
-    url(r'^$', views.supporting_partners,
-        name='partners'),
-    url(r'^membership_request$', views.membership_request,
-        name='membership_request'),
+    url(r'^$', views.supporting_partners, name='partners'),
+    url(r'^membership_request$', views.membership_request, name='membership_request'),
     url(r'^manage$', views.manage, name='manage'),
     url(r'^add_prospective_partner$', views.add_prospective_partner,
         name='add_prospective_partner'),
     url(r'^add_prospective_contact/(?P<prospartner_id>[0-9]+)$',
-        views.add_prospartner_contact,
-        name='add_prospartner_contact'),
+        views.add_prospartner_contact, name='add_prospartner_contact'),
     url(r'^add_prospartner_event/(?P<prospartner_id>[0-9]+)$',
-        views.add_prospartner_event,
-        name='add_prospartner_event'),
+        views.add_prospartner_event, name='add_prospartner_event'),
 ]
diff --git a/partners/views.py b/partners/views.py
index 19c9b7e9c..67c1b3895 100644
--- a/partners/views.py
+++ b/partners/views.py
@@ -5,16 +5,18 @@ from django.utils import timezone
 
 from guardian.decorators import permission_required
 
-from .models import Partner, ProspectivePartner, ProspectiveContact, \
-    ProspectivePartnerEvent, MembershipAgreement
-from .forms import ProspectivePartnerForm, ProspectiveContactForm, \
-    ProspectivePartnerEventForm, MembershipQueryForm
+from .constants import PROSPECTIVE_PARTNER_REQUESTED
+from .models import Partner, ProspectivePartner, ProspectiveContact, MembershipAgreement
+from .forms import ProspectivePartnerForm, ProspectiveContactForm,\
+                   ProspectivePartnerEventForm, MembershipQueryForm
 
 
 def supporting_partners(request):
-    prospective_agreements = MembershipAgreement.objects.filter(
-        status='Submitted').order_by('date_requested')
-    context = {'prospective_partners': prospective_agreements, }
+    context = {}
+    if request.user.groups.filter(name='Editorial Administrators').exists():
+        # Show Agreements to Administrators only!
+        prospective_agreements = MembershipAgreement.objects.submitted().order_by('date_requested')
+        context['prospective_partners'] = prospective_agreements
     return render(request, 'partners/supporting_partners.html', context)
 
 
@@ -27,7 +29,7 @@ def membership_request(request):
             institution_name=query_form.cleaned_data['institution_name'],
             country=query_form.cleaned_data['country'],
             date_received=timezone.now(),
-            status = 'requested',
+            status=PROSPECTIVE_PARTNER_REQUESTED,
         )
         prospartner.save()
         contact = ProspectiveContact(
@@ -41,7 +43,7 @@ def membership_request(request):
         ack_message = ('Thank you for your SPB Membership query. '
                        'We will get back to you in the very near future '
                        'with further details.')
-        context = {'ack_message': ack_message, }
+        context = {'ack_message': ack_message}
         return render(request, 'scipost/acknowledgement.html', context)
     context = {'query_form': query_form}
     return render(request, 'partners/membership_request.html', context)
@@ -53,10 +55,9 @@ def manage(request):
     Lists relevant info regarding management of Supporting Partners Board.
     """
     partners = Partner.objects.all()
-    prospective_partners = ProspectivePartner.objects.all(
-    ).order_by('country', 'institution_name')
+    prospective_partners = ProspectivePartner.objects.order_by('country', 'institution_name')
     ppevent_form = ProspectivePartnerEventForm()
-    agreements = MembershipAgreement.objects.all().order_by('date_requested')
+    agreements = MembershipAgreement.objects.order_by('date_requested')
     context = {'partners': partners,
                'prospective_partners': prospective_partners,
                'ppevent_form': ppevent_form,
@@ -65,15 +66,11 @@ def manage(request):
 
 
 @permission_required('scipost.can_manage_SPB', return_403=True)
-@transaction.atomic
 def add_prospective_partner(request):
-    form = ProspectivePartnerForm(request.POST or None,
-                                  initial={'status': 'added',
-                                           'kind': 'Univ. Library'})
+    form = ProspectivePartnerForm(request.POST or None)
     if form.is_valid():
         pp = form.save()
         messages.success(request, 'Prospective Partner successfully added')
-#        return redirect(reverse('partners:manage'))
         return redirect(reverse('partners:add_prospartner_contact',
                                 kwargs={'prospartner_id': pp.id}))
     context = {'form': form}
@@ -81,17 +78,14 @@ def add_prospective_partner(request):
 
 
 @permission_required('scipost.can_manage_SPB', return_403=True)
-@transaction.atomic
 def add_prospartner_contact(request, prospartner_id):
     prospartner = get_object_or_404(ProspectivePartner, pk=prospartner_id)
-    form = ProspectiveContactForm(
-        request.POST or None, initial={'prospartner': prospartner })
+    form = ProspectiveContactForm(request.POST or None, initial={'prospartner': prospartner})
     if form.is_valid():
         form.save()
         messages.success(request, 'Contact successfully added to Prospective Partner')
         return redirect(reverse('partners:manage'))
-    context = {'form': form,
-               'prospartner': prospartner }
+    context = {'form': form, 'prospartner': prospartner}
     return render(request, 'partners/add_prospartner_contact.html', context)
 
 
@@ -102,17 +96,13 @@ def add_prospartner_event(request, prospartner_id):
     if request.method == 'POST':
         ppevent_form = ProspectivePartnerEventForm(request.POST)
         if ppevent_form.is_valid():
-            ppevent = ProspectivePartnerEvent(
-                prospartner=prospartner,
-                event=ppevent_form.cleaned_data['event'],
-                comments=ppevent_form.cleaned_data['comments'],
-                noted_on=timezone.now(),
-                noted_by=request.user.contributor,)
+            ppevent = ppevent_form.save(commit=False)
+            ppevent.prospartner = prospartner
+            ppevent.noted_by = request.user.contributor
             ppevent.save()
             return redirect(reverse('partners:manage'))
         else:
             errormessage = 'The form was invalidly filled.'
             return render(request, 'scipost/error.html', {'errormessage': errormessage})
-    else:
-        errormessage = 'This view can only be posted to.'
-        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    errormessage = 'This view can only be posted to.'
+    return render(request, 'scipost/error.html', {'errormessage': errormessage})
-- 
GitLab