From 6629f72da2b198ef7ddfee24a9bf4ab3c61eb1a4 Mon Sep 17 00:00:00 2001
From: Jorran de Wit <jorrandewit@outlook.com>
Date: Tue, 20 Jun 2017 19:48:39 +0200
Subject: [PATCH] Implement basics for partner environment

---
 partners/admin.py                             | 28 +++++++++++++------
 .../migrations/0013_auto_20170620_1551.py     | 20 +++++++++++++
 .../migrations/0014_auto_20170620_1554.py     | 22 +++++++++++++++
 .../migrations/0015_auto_20170620_1634.py     | 20 +++++++++++++
 partners/models.py                            |  9 +++---
 .../partners/_contact_info_table.html         |  6 ++++
 partners/templates/partners/dashboard.html    | 20 ++++++++++++-
 scipost/admin.py                              |  4 +++
 scipost/templates/scipost/navbar.html         | 13 +++++++--
 9 files changed, 126 insertions(+), 16 deletions(-)
 create mode 100644 partners/migrations/0013_auto_20170620_1551.py
 create mode 100644 partners/migrations/0014_auto_20170620_1554.py
 create mode 100644 partners/migrations/0015_auto_20170620_1634.py
 create mode 100644 partners/templates/partners/_contact_info_table.html

diff --git a/partners/admin.py b/partners/admin.py
index 6aa2fcafc..fc4f71b22 100644
--- a/partners/admin.py
+++ b/partners/admin.py
@@ -1,10 +1,24 @@
 from django.contrib import admin
 
-from .models import Contact, Partner, Consortium,\
+from .models import Contact, Partner, Consortium, Institution,\
                     ProspectivePartner, ProspectiveContact, ProspectivePartnerEvent,\
                     MembershipAgreement
 
 
+class ContactToPartnerInline(admin.TabularInline):
+    model = Contact.partners.through
+    extra = 0
+    verbose_name = 'Contact'
+    verbose_name_plural = 'Contacts'
+
+
+class ContactToUserInline(admin.StackedInline):
+    model = Contact
+    extra = 0
+    min_num = 0
+    verbose_name = 'Contact (Partners)'
+
+
 class ProspectiveContactInline(admin.TabularInline):
     model = ProspectiveContact
     extra = 0
@@ -22,16 +36,14 @@ class ProspectivePartnerAdmin(admin.ModelAdmin):
 
 class PartnerAdmin(admin.ModelAdmin):
     search_fields = ('institution', )
-
-
-class ContactInline(admin.StackedInline):
-    model = Contact
-    extra = 0
-    min_num = 0
-    verbose_name = 'Contact (Partners)'
+    inlines = (
+        ContactToPartnerInline,
+    )
 
 
 admin.site.register(Partner, PartnerAdmin)
 admin.site.register(Consortium)
+admin.site.register(Contact)
+admin.site.register(Institution)
 admin.site.register(ProspectivePartner, ProspectivePartnerAdmin)
 admin.site.register(MembershipAgreement)
diff --git a/partners/migrations/0013_auto_20170620_1551.py b/partners/migrations/0013_auto_20170620_1551.py
new file mode 100644
index 000000000..d0626aef8
--- /dev/null
+++ b/partners/migrations/0013_auto_20170620_1551.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-06-20 13:51
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0012_auto_20170620_1526'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contact',
+            name='consortia',
+            field=models.ManyToManyField(blank=True, help_text='All Consortia for which the Contact has explicit permission to view/edit its data.', to='partners.Consortium'),
+        ),
+    ]
diff --git a/partners/migrations/0014_auto_20170620_1554.py b/partners/migrations/0014_auto_20170620_1554.py
new file mode 100644
index 000000000..42da59192
--- /dev/null
+++ b/partners/migrations/0014_auto_20170620_1554.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-06-20 13:54
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0013_auto_20170620_1551'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contact',
+            name='user',
+            field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='partner_contact', to=settings.AUTH_USER_MODEL),
+        ),
+    ]
diff --git a/partners/migrations/0015_auto_20170620_1634.py b/partners/migrations/0015_auto_20170620_1634.py
new file mode 100644
index 000000000..e5378392c
--- /dev/null
+++ b/partners/migrations/0015_auto_20170620_1634.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-06-20 14:34
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0014_auto_20170620_1554'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='institution',
+            name='address',
+            field=models.TextField(blank=True),
+        ),
+    ]
diff --git a/partners/models.py b/partners/models.py
index 0ab566ee0..211f64a6c 100644
--- a/partners/models.py
+++ b/partners/models.py
@@ -98,7 +98,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)
+    address = models.TextField(blank=True)
     country = CountryField()
 
     def __str__(self):
@@ -112,13 +112,14 @@ class Contact(models.Model):
     (main contact, financial/technical contact etc).
     Contacts and Contributors have different rights.
     """
-    user = models.OneToOneField(User, on_delete=models.CASCADE, unique=True)
+    user = models.OneToOneField(User, on_delete=models.CASCADE, unique=True,
+                                related_name='partner_contact')
     kind = ChoiceArrayField(models.CharField(max_length=4, choices=CONTACT_TYPES))
     title = models.CharField(max_length=4, choices=TITLE_CHOICES)
     partners = models.ManyToManyField('partners.Partner',
                                       help_text=('All Partners (+related Institutions)'
                                                  ' the Contact is related to.'))
-    consortia = models.ManyToManyField('partners.Consortium',
+    consortia = models.ManyToManyField('partners.Consortium', blank=True,
                                        help_text=('All Consortia for which the Contact has'
                                                   ' explicit permission to view/edit its data.'))
 
@@ -173,7 +174,7 @@ class MembershipAgreement(models.Model):
     A new instance is created each time an Agreement is made or renewed.
     """
     partner = models.ForeignKey('partners.Partner', on_delete=models.CASCADE,
-                                blank=True, null=True)
+                                blank=True, null=True, related_name='agreements')
     consortium = models.ForeignKey('partners.Consortium', on_delete=models.CASCADE,
                                    blank=True, null=True)
     status = models.CharField(max_length=16, choices=MEMBERSHIP_AGREEMENT_STATUS)
diff --git a/partners/templates/partners/_contact_info_table.html b/partners/templates/partners/_contact_info_table.html
new file mode 100644
index 000000000..e9adc3645
--- /dev/null
+++ b/partners/templates/partners/_contact_info_table.html
@@ -0,0 +1,6 @@
+<table>
+    <tr><td>Title: </td><td>&nbsp;</td><td>{{ contact.get_title_display }}</td></tr>
+    <tr><td>First name: </td><td>&nbsp;</td><td>{{ contact.user.first_name }}</td></tr>
+    <tr><td>Last name: </td><td>&nbsp;</td><td>{{ contact.user.last_name }}</td></tr>
+    <tr><td>Email: </td><td>&nbsp;</td><td>{{ contact.user.email }}</td></tr>
+</table>
diff --git a/partners/templates/partners/dashboard.html b/partners/templates/partners/dashboard.html
index 13962bb3e..560a8f254 100644
--- a/partners/templates/partners/dashboard.html
+++ b/partners/templates/partners/dashboard.html
@@ -46,9 +46,27 @@
         <div class="row">
             <div class="col-md-6">
                 <h3>Your personal details:</h3>
-                {% include "scipost/_private_info_as_table.html" with contributor=request.user.contributor %}
+                {% include "partners/_contact_info_table.html" with contact=request.user.partner_contact %}
             </div>
             <div class="col-md-6">
+                <h3>Partners</h3>
+                <ul>
+                    {% for partner in request.user.partners.all %}
+                        <li>{{partner}}</li>
+                    {% empty %}
+                        <li>No partners found. Please contact the SciPost admin.</li>
+                    {% endfor %}
+                </ul>
+
+                <h3>Agreements</h3>
+                <ul>
+                    {% for partner in request.user.partners.agreements.all %}
+                        <li>{{partner}}</li>
+                    {% empty %}
+                        <li>No active agreements found.</li>
+                    {% endfor %}
+                </ul>
+
                 <h3>Update your personal data or password</h3>
 
                 <ul>
diff --git a/scipost/admin.py b/scipost/admin.py
index 5db931f3e..32c2c40a9 100644
--- a/scipost/admin.py
+++ b/scipost/admin.py
@@ -14,16 +14,20 @@ from scipost.models import Contributor, Remark,\
                            EditorialCollege, EditorialCollegeFellowship
 
 from journals.models import Publication
+from partners.admin import ContactToUserInline
 from submissions.models import Submission
 
 
 class ContributorInline(admin.StackedInline):
     model = Contributor
+    extra = 0
+    min_num = 0
 
 
 class UserAdmin(UserAdmin):
     inlines = [
         ContributorInline,
+        ContactToUserInline,
         ]
     search_fields = ['last_name', 'email']
 
diff --git a/scipost/templates/scipost/navbar.html b/scipost/templates/scipost/navbar.html
index 181b9fc24..c972b3ae8 100644
--- a/scipost/templates/scipost/navbar.html
+++ b/scipost/templates/scipost/navbar.html
@@ -21,9 +21,16 @@
               <li class="nav-item highlighted">
                 <span class="nav-link">Logged in as {{ user.username }}</span>
               </li>
-              <li class="nav-item{% if '/personal_page' in request.path %} active{% endif %}">
-                <a class="nav-link" href="{% url 'scipost:personal_page' %}">Personal Page</a>
-              </li>
+              {% if user.contributor %}
+                  <li class="nav-item{% if '/personal_page' in request.path %} active{% endif %}">
+                    <a class="nav-link" href="{% url 'scipost:personal_page' %}">Personal Page</a>
+                  </li>
+              {% endif %}
+              {% if user.partner_contact %}
+                  <li class="nav-item{% if '/partners/dashboard' in request.path %} active{% endif %}">
+                    <a class="nav-link" href="{% url 'partners:dashboard' %}">Partner Page</a>
+                  </li>
+              {% endif %}
               <li class="nav-item">
                 <a class="nav-link" href="{% url 'scipost:logout' %}">Logout</a>
               </li>
-- 
GitLab