diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py
index 760615bd5f411f88a7d34b7df20f3ac85cd48ccb..0f3ea5de4bd041519094eb14dc7baf163ca6a74f 100644
--- a/SciPost_v1/settings/base.py
+++ b/SciPost_v1/settings/base.py
@@ -86,6 +86,7 @@ INSTALLED_APPS = (
     'sphinxdoc',
     'commentaries',
     'comments',
+    'finances',
     'journals',
     'mails',
     'mailing_lists',
@@ -227,9 +228,13 @@ USE_TZ = True
 
 # MEDIA
 MEDIA_URL = '/media/'
-MEDIA_ROOT = 'local_files/media/'
+MEDIA_URL_SECURE = '/files/secure/'
 MAX_UPLOAD_SIZE = "1310720"  # Default max attachment size in Bytes
 
+# -- These MEDIA settings are machine-dependent
+MEDIA_ROOT = 'local_files/media/'
+MEDIA_ROOT_SECURE = 'local_files/secure/media/'
+
 # Static files (CSS, JavaScript, Images)
 STATIC_URL = '/static/'
 STATIC_ROOT = 'local_files/static/'
diff --git a/SciPost_v1/urls.py b/SciPost_v1/urls.py
index aabec88b1b1947e7d1087ee37e9d4ac3734646c2..ab3ea6f377dc701332e17b0f0a9f4152416c6126 100644
--- a/SciPost_v1/urls.py
+++ b/SciPost_v1/urls.py
@@ -33,6 +33,7 @@ urlpatterns = [
     url(r'^commentary/', include('commentaries.urls', namespace="_commentaries")),
     url(r'^comments/', include('comments.urls', namespace="comments")),
     url(r'^funders/', include('funders.urls', namespace="funders")),
+    url(r'^finances/', include('finances.urls', namespace="finances")),
     url(r'^journals/', include('journals.urls.general', namespace="journals")),
     url(r'^mailing_list/', include('mailing_lists.urls', namespace="mailing_lists")),
     url(r'^submissions/', include('submissions.urls', namespace="submissions")),
diff --git a/commentaries/migrations/0019_auto_20170925_2124.py b/commentaries/migrations/0019_auto_20170925_2124.py
new file mode 100644
index 0000000000000000000000000000000000000000..869d355df63987056b768158f5b090a7e0093ef7
--- /dev/null
+++ b/commentaries/migrations/0019_auto_20170925_2124.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-25 19:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('commentaries', '0018_auto_20170909_1649'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='commentary',
+            name='authors',
+            field=models.ManyToManyField(blank=True, related_name='commentaries', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='commentary',
+            name='authors_claims',
+            field=models.ManyToManyField(blank=True, related_name='claimed_commentaries', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='commentary',
+            name='authors_false_claims',
+            field=models.ManyToManyField(blank=True, related_name='false_claimed_commentaries', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='commentary',
+            name='requested_by',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='requested_commentaries', to='scipost.Contributor'),
+        ),
+    ]
diff --git a/commentaries/models.py b/commentaries/models.py
index aa5df1de3fd4e8f87c100e52c856ae7bdd18e74f..add1f6b8ca87771c4527dd64646ccb71cb405ff6 100644
--- a/commentaries/models.py
+++ b/commentaries/models.py
@@ -16,7 +16,8 @@ class Commentary(TimeStampedModel):
     A Commentary contains all the contents of a SciPost Commentary page for a given publication.
     """
     requested_by = models.ForeignKey('scipost.Contributor', blank=True, null=True,
-                                     on_delete=models.CASCADE, related_name='requested_by')
+                                     on_delete=models.CASCADE,
+                                     related_name='requested_commentaries')
     vetted = models.BooleanField(default=False)
     vetted_by = models.ForeignKey('scipost.Contributor', blank=True, null=True,
                                   on_delete=models.CASCADE)
@@ -44,11 +45,11 @@ class Commentary(TimeStampedModel):
 
     # Authors which have been mapped to contributors:
     authors = models.ManyToManyField('scipost.Contributor', blank=True,
-                                     related_name='authors_com')
+                                     related_name='commentaries')
     authors_claims = models.ManyToManyField('scipost.Contributor', blank=True,
-                                            related_name='authors_com_claims')
+                                            related_name='claimed_commentaries')
     authors_false_claims = models.ManyToManyField('scipost.Contributor', blank=True,
-                                                  related_name='authors_com_false_claims')
+                                                  related_name='false_claimed_commentaries')
     journal = models.CharField(max_length=300, blank=True)
     volume = models.CharField(max_length=50, blank=True)
     pages = models.CharField(max_length=50, blank=True)
diff --git a/comments/migrations/0017_auto_20170729_0717.py b/comments/migrations/0017_auto_20170729_0717.py
index db86be1347d9f1c75a3c61ef6d07bf5028ae94c9..8ac6202aae5df406daa83cbee1b9f94c043ded68 100644
--- a/comments/migrations/0017_auto_20170729_0717.py
+++ b/comments/migrations/0017_auto_20170729_0717.py
@@ -11,10 +11,10 @@ from guardian.shortcuts import assign_perm
 
 def update_all_contenttypes(**kwargs):
     from django.apps import apps
-    from django.contrib.contenttypes.management import update_contenttypes
+    from django.contrib.contenttypes.management import create_contenttypes
 
     for app_config in apps.get_app_configs():
-        update_contenttypes(app_config, **kwargs)
+        create_contenttypes(app_config, **kwargs)
 
 
 def create_all_permissions(**kwargs):
diff --git a/finances/__init__.py b/finances/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/finances/admin.py b/finances/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c38f3f3dad51e4585f3984282c2a4bec5349c1e
--- /dev/null
+++ b/finances/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/finances/apps.py b/finances/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..4a1db0117b5f1f8dca3c5ba77a8b9c55a9201f34
--- /dev/null
+++ b/finances/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class FinancesConfig(AppConfig):
+    name = 'finances'
diff --git a/finances/migrations/__init__.py b/finances/migrations/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/finances/models.py b/finances/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..71a836239075aa6e6e4ecb700e9c42c95c022d91
--- /dev/null
+++ b/finances/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/finances/templates/finances/timesheets.html b/finances/templates/finances/timesheets.html
new file mode 100644
index 0000000000000000000000000000000000000000..63d43519a766bf7535bedf40f08346554eb7c837
--- /dev/null
+++ b/finances/templates/finances/timesheets.html
@@ -0,0 +1,61 @@
+{% extends 'scipost/base.html' %}
+
+{% block breadcrumb_items %}
+    <span class="breadcrumb-item">Team Timesheets</span>
+{% endblock %}
+
+{% block pagetitle %}: Team Timesheets{% endblock pagetitle %}
+
+{% load bootstrap %}
+
+{% block content %}
+
+<div class="row">
+    <div class="col-12">
+        <h1 class="highlight">Team Timesheets</h1>
+
+        <form method="get" action="{% url 'finances:timesheets' %}">
+            {{ form|bootstrap }}
+            <input type="submit" class="btn btn-primary" value="Filter">
+        </form>
+    </div>
+</div>
+
+<div class="row">
+    <div class="col-12">
+        <h2 class="mb-2 mt-4">Team Timesheets</h2>
+        {% for total in totals %}
+            <h3 class="mb-1">{{ total.user }}</h3>
+            <table class="table">
+                <thead class="thead-default">
+                  <tr>
+                      <th>Date</th>
+                      <th>By</th>
+                      <th>Stream</th>
+                      <th>Event</th>
+                      <th>Duration</th>
+                  </tr>
+                </thead>
+
+                <tbody>
+                    {% for event in total.events %}
+                        <tr>
+                            <td>{{ event.noted_on }}</td>
+                            <td>{{ event.noted_by }}</td>
+                            <td>{{ event.stream }}</td>
+                            <td>{{ event.get_event_display }}</td>
+                            <td>{{ event.duration }}</td>
+                        </tr>
+                    {% endfor %}
+                    <tr>
+                        <td colspan="4"></td>
+                        <td><strong>{{ total.duration.total }}</strong></td>
+                    </tr>
+                </tbody>
+            </table>
+        {% empty %}
+            <h3>Timesheet is empty for this month.</h3>
+        {% endfor %}
+    </div>
+</div>
+{% endblock %}
diff --git a/finances/tests.py b/finances/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6
--- /dev/null
+++ b/finances/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/finances/urls.py b/finances/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..21569e295d98c0c64a768ff55dc9c71bcbf07e7e
--- /dev/null
+++ b/finances/urls.py
@@ -0,0 +1,8 @@
+from django.conf.urls import url
+
+from . import views
+
+urlpatterns = [
+    url(r'^$', views.timesheets, name='finance'),
+    url(r'^timesheets$', views.timesheets, name='timesheets'),
+]
diff --git a/finances/views.py b/finances/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..b967443f18581bfd581f6710541e6f73e46fbf4f
--- /dev/null
+++ b/finances/views.py
@@ -0,0 +1,20 @@
+from django.contrib.auth.decorators import permission_required
+from django.shortcuts import render
+
+from production.forms import ProductionUserMonthlyActiveFilter
+
+
+@permission_required('scipost.can_view_timesheets', raise_exception=True)
+def timesheets(request):
+    """
+    See an overview per month of all timesheets.
+    """
+    form = ProductionUserMonthlyActiveFilter(request.GET or None)
+    context = {
+        'form': form,
+    }
+
+    # if form.is_valid():
+    context['totals'] = form.get_totals()
+
+    return render(request, 'finances/timesheets.html', context)
diff --git a/journals/migrations/0045_auto_20170925_2124.py b/journals/migrations/0045_auto_20170925_2124.py
new file mode 100644
index 0000000000000000000000000000000000000000..73a946327c5389eec5dcfeb32ac89933e8a95fa3
--- /dev/null
+++ b/journals/migrations/0045_auto_20170925_2124.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-25 19:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0044_publication_doideposit_needs_updating'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='publication',
+            name='authors',
+            field=models.ManyToManyField(blank=True, related_name='publications', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='publication',
+            name='authors_claims',
+            field=models.ManyToManyField(blank=True, related_name='claimed_publications', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='publication',
+            name='authors_false_claims',
+            field=models.ManyToManyField(blank=True, related_name='false_claimed_publications', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='publication',
+            name='authors_unregistered',
+            field=models.ManyToManyField(blank=True, related_name='publications', to='journals.UnregisteredAuthor'),
+        ),
+        migrations.AlterField(
+            model_name='publication',
+            name='first_author',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='first_author_publications', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='publication',
+            name='first_author_unregistered',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='first_author_publications', to='journals.UnregisteredAuthor'),
+        ),
+    ]
diff --git a/journals/models.py b/journals/models.py
index 4dc87d39843fc4957040606eb819aaf8259f3712..613acad1ffe2089ef1b7a3c6b1e1f50dfe7b5dd2 100644
--- a/journals/models.py
+++ b/journals/models.py
@@ -131,23 +131,27 @@ class Publication(models.Model):
                                        blank=True, null=True)
     title = models.CharField(max_length=300)
     author_list = models.CharField(max_length=1000, verbose_name="author list")
+
     # Authors which have been mapped to contributors:
-    authors = models.ManyToManyField(Contributor, blank=True, related_name='authors_pub')
+    authors = models.ManyToManyField('scipost.Contributor', blank=True,
+                                     related_name='publications')
     authors_unregistered = models.ManyToManyField(UnregisteredAuthor, blank=True,
-                                                  related_name='authors_unregistered')
-    first_author = models.ForeignKey(Contributor, blank=True, null=True, on_delete=models.CASCADE)
+                                                  related_name='publications')
+    first_author = models.ForeignKey('scipost.Contributor', blank=True, null=True,
+                                     on_delete=models.CASCADE,
+                                     related_name='first_author_publications')
     first_author_unregistered = models.ForeignKey(UnregisteredAuthor, blank=True, null=True,
                                                   on_delete=models.CASCADE,
-                                                  related_name='first_author_unregistered')
-    authors_claims = models.ManyToManyField(Contributor, blank=True,
-                                            related_name='authors_pub_claims')
-    authors_false_claims = models.ManyToManyField(Contributor, blank=True,
-                                                  related_name='authors_pub_false_claims')
+                                                  related_name='first_author_publications')
+    authors_claims = models.ManyToManyField('scipost.Contributor', blank=True,
+                                            related_name='claimed_publications')
+    authors_false_claims = models.ManyToManyField('scipost.Contributor', blank=True,
+                                                  related_name='false_claimed_publications')
     abstract = models.TextField()
     pdf_file = models.FileField(upload_to='UPLOADS/PUBLICATIONS/%Y/%m/', max_length=200)
     cc_license = models.CharField(max_length=32, choices=CC_LICENSES, default=CCBY4)
     grants = models.ManyToManyField('funders.Grant', blank=True)
-    funders_generic = models.ManyToManyField('funders.Funder', blank=True) # not linked to a grant
+    funders_generic = models.ManyToManyField('funders.Funder', blank=True)  # not linked to a grant
     metadata = JSONField(default={}, blank=True, null=True)
     metadata_xml = models.TextField(blank=True, null=True)  # for Crossref deposit
     latest_metadata_update = models.DateTimeField(blank=True, null=True)
diff --git a/notifications/templates/notifications/partials/notice.html b/notifications/templates/notifications/partials/notice.html
index 411a96e0e9da56cc939b11ce65bf4a44c51e01b2..5ce4c87d0a529b780c99a5cb9a5113a1cb5497c2 100644
--- a/notifications/templates/notifications/partials/notice.html
+++ b/notifications/templates/notifications/partials/notice.html
@@ -3,9 +3,9 @@
         <div class="actions">
             <a href="{% url 'notifications:mark_toggle' notice.slug %}">
                 {% if notice.unread %}
-                    <i class="fa fa-circle" data-toggle="tooltip" data-placement="auto" title="Mark as unread" aria-hidden="true"></i>
+                    <i class="fa fa-circle" data-toggle="tooltip" data-placement="auto" title="Mark as read" aria-hidden="true"></i>
                 {% else %}
-                    <i class="fa fa-circle-o" data-toggle="tooltip" data-placement="auto" title="Mark as read" aria-hidden="true"></i>
+                    <i class="fa fa-circle-o" data-toggle="tooltip" data-placement="auto" title="Mark as unread" aria-hidden="true"></i>
                 {% endif %}
             </a>
         </div>
diff --git a/notifications/views.py b/notifications/views.py
index 38dd0329b46e900f6b569d04e50cbb586c2fb517..e309196bb51f93c2f465baad3b931219655118d6 100644
--- a/notifications/views.py
+++ b/notifications/views.py
@@ -49,6 +49,10 @@ def mark_all_as_read(request):
 
     if _next:
         return redirect(_next)
+
+    if request.GET.get('json'):
+        return JsonResponse({'unread': 0})
+
     return redirect('notifications:all')
 
 
diff --git a/partners/models.py b/partners/models.py
index 1d7f39a882f9a0ba0d2aa4c2ae123cc1ccecbe33..ff95d07990170d04286329cc4d70a0c625203715 100644
--- a/partners/models.py
+++ b/partners/models.py
@@ -26,6 +26,7 @@ from .constants import PROSPECTIVE_PARTNER_EVENT_EMAIL_SENT,\
 
 from .managers import MembershipAgreementManager, ProspectivePartnerManager, PartnerManager,\
                       ContactRequestManager, PartnersAttachmentManager
+from .storage import SecureFileStorage
 
 from scipost.constants import TITLE_CHOICES
 from scipost.fields import ChoiceArrayField
@@ -291,7 +292,8 @@ class PartnersAttachment(models.Model):
     An Attachment which can (in the future) be related to a Partner, Contact, MembershipAgreement,
     etc.
     """
-    attachment = models.FileField(upload_to='UPLOADS/PARTNERS/ATTACHMENTS')
+    attachment = models.FileField(upload_to='UPLOADS/PARTNERS/ATTACHMENTS',
+                                  storage=SecureFileStorage())
     name = models.CharField(max_length=128)
     agreement = models.ForeignKey('partners.MembershipAgreement', related_name='attachments',
                                   blank=True)
diff --git a/partners/storage.py b/partners/storage.py
new file mode 100644
index 0000000000000000000000000000000000000000..1821e4f48a785229435e4963d81ac33e881aea19
--- /dev/null
+++ b/partners/storage.py
@@ -0,0 +1,25 @@
+from django.conf import settings
+from django.core.files.storage import FileSystemStorage
+from django.utils.functional import cached_property
+
+
+class SecureFileStorage(FileSystemStorage):
+    """
+    Inherit default FileStorage system to prevent files from being publicly accessible
+    from an server location that is permitted to be opened without explicit permissions.
+    """
+    @cached_property
+    def location(self):
+        """
+        This method determines the storage location for a new file. To secure the file from
+        'the public', we'll store it outside the publicly accessible MEDIA_ROOT folder.
+
+        This also means you need to explicitly handle the file reading/opening!
+        """
+        if hasattr(settings, 'MEDIA_ROOT_SECURE'):
+            return self._value_or_setting(self._location, settings.MEDIA_ROOT_SECURE)
+        return super().location
+
+    @cached_property
+    def base_url(self):
+        return settings.MEDIA_URL_SECURE
diff --git a/partners/views.py b/partners/views.py
index 04a4c5f1ef0615d1310fb3d420d3a764aad27fe6..1a94818df5390b13a87b613425656fcfd2f2b4be 100644
--- a/partners/views.py
+++ b/partners/views.py
@@ -1,8 +1,10 @@
+import mimetypes
+
 from django.contrib import messages
 from django.contrib.auth.decorators import login_required
 from django.db import transaction
 from django.forms import modelformset_factory
-from django.http import HttpResponse
+from django.http import FileResponse, HttpResponse
 from django.shortcuts import get_object_or_404, render, reverse, redirect
 from django.utils import timezone
 
@@ -95,7 +97,7 @@ def membership_request(request):
     return render(request, 'partners/membership_request.html', context)
 
 
-@permission_required('scipost.can_promote_prospect_to_partner', return_403=True)
+@permission_required('scipost.can_promote_to_production_team', return_403=True)
 @transaction.atomic
 def promote_prospartner(request, prospartner_id):
     prospartner = get_object_or_404(ProspectivePartner.objects.not_yet_partner(),
@@ -386,7 +388,11 @@ def agreement_details(request, agreement_id):
 def agreement_attachments(request, agreement_id, attachment_id):
     attachment = get_object_or_404(PartnersAttachment.objects.my_attachments(request.user),
                                    agreement__id=agreement_id, id=attachment_id)
-    response = HttpResponse(attachment.attachment.read(), content_type='application/pdf')
+
+    content_type, encoding = mimetypes.guess_type(attachment.attachment.path)
+    content_type = content_type or 'application/octet-stream'
+    response = HttpResponse(attachment.attachment.read(), content_type=content_type)
+    response["Content-Encoding"] = encoding
     response['Content-Disposition'] = ('filename=%s' % attachment.name)
     return response
 
diff --git a/production/admin.py b/production/admin.py
index 7969db8ec5fb3bbc2427fc3751b86fc871763e62..dc5cbd236c21019ed1fb12ece7a8a9d13a89b09e 100644
--- a/production/admin.py
+++ b/production/admin.py
@@ -1,10 +1,18 @@
 from django.contrib import admin
 
-from .models import ProductionStream, ProductionEvent
+from guardian.admin import GuardedModelAdmin
+
+from .models import ProductionStream, ProductionEvent, ProductionUser
 
 
 def event_count(obj):
-    return obj.productionevent_set.count()
+    return obj.events.count()
+
+
+class ProductionUserInline(admin.StackedInline):
+    model = ProductionUser
+    extra = 0
+    min_num = 0
 
 
 class ProductionEventInline(admin.TabularInline):
@@ -13,7 +21,7 @@ class ProductionEventInline(admin.TabularInline):
     readonly_fields = ()
 
 
-class ProductionStreamAdmin(admin.ModelAdmin):
+class ProductionStreamAdmin(GuardedModelAdmin):
     search_fields = ['submission']
     list_filter = ['status']
     list_display = ['submission', 'opened', 'status', event_count]
@@ -22,4 +30,5 @@ class ProductionStreamAdmin(admin.ModelAdmin):
     )
 
 
+admin.site.register(ProductionUser)
 admin.site.register(ProductionStream, ProductionStreamAdmin)
diff --git a/production/apps.py b/production/apps.py
index 549c6bd6bb6fac43a2edebae72c2e580cb66bb11..d633dcd69d8e1462ea12d64fa04cf8492c2dafe9 100644
--- a/production/apps.py
+++ b/production/apps.py
@@ -8,7 +8,7 @@ class ProductionConfig(AppConfig):
     def ready(self):
         super().ready()
 
-        from .models import ProductionStream, ProductionEvent
-        from .signals import notify_new_stream, notify_new_event
-        post_save.connect(notify_new_stream, sender=ProductionStream)
+        from .models import ProductionEvent, ProductionStream
+        from .signals import notify_new_event, notify_new_stream
         post_save.connect(notify_new_event, sender=ProductionEvent)
+        post_save.connect(notify_new_stream, sender=ProductionStream)
diff --git a/production/forms.py b/production/forms.py
index fec37e4b4ba232b9432bfc52c173229c640c709a..4c284c839e6bd44202ee6d78d5479515211f1c2a 100644
--- a/production/forms.py
+++ b/production/forms.py
@@ -1,6 +1,13 @@
+import datetime
+
 from django import forms
+from django.contrib.auth import get_user_model
+from django.utils.dates import MONTHS
+from django.db.models import Sum
+
+from .models import ProductionUser, ProductionStream, ProductionEvent
 
-from .models import ProductionEvent
+today = datetime.datetime.today()
 
 
 class ProductionEventForm(forms.ModelForm):
@@ -15,3 +22,73 @@ class ProductionEventForm(forms.ModelForm):
             'comments': forms.Textarea(attrs={'rows': 4}),
             'duration': forms.TextInput(attrs={'placeholder': 'HH:MM:SS'})
         }
+
+
+class AssignOfficerForm(forms.ModelForm):
+    class Meta:
+        model = ProductionStream
+        fields = ('officer',)
+
+
+class AssignSupervisorForm(forms.ModelForm):
+    class Meta:
+        model = ProductionStream
+        fields = ('supervisor',)
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.fields['supervisor'].queryset = self.fields['supervisor'].queryset.filter(
+            user__groups__name='Production Supervisor')
+
+
+class UserToOfficerForm(forms.ModelForm):
+    class Meta:
+        model = ProductionUser
+        fields = (
+            'user',
+        )
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.fields['user'].queryset = self.fields['user'].queryset.filter(
+            production_user__isnull=True).order_by('last_name')
+
+
+class ProductionUserMonthlyActiveFilter(forms.Form):
+    month = forms.ChoiceField(choices=[(k, v) for k, v in MONTHS.items()])
+    year = forms.ChoiceField(choices=[(y, y) for y in reversed(range(today.year-6, today.year+1))])
+
+    def __init__(self, *args, **kwargs):
+        if not kwargs.get('data', False) and not args[0]:
+            args = list(args)
+            args[0] = {
+                'month': today.month,
+                'year': today.year
+            }
+            args = tuple(args)
+        kwargs['initial'] = {
+            'month': today.month,
+            'year': today.year
+        }
+        super().__init__(*args, **kwargs)
+
+    def get_totals(self):
+        # Make accessible without need to explicitly check validity of form.
+        self.is_valid()
+
+        users = ProductionUser.objects.filter(events__duration__isnull=False,
+                                              events__noted_on__month=self.cleaned_data['month'],
+                                              events__noted_on__year=self.cleaned_data['year']
+                                              ).distinct()
+        output = []
+        for user in users:
+            events = user.events.filter(duration__isnull=False,
+                                        noted_on__month=self.cleaned_data['month'],
+                                        noted_on__year=self.cleaned_data['year'])
+            output.append({
+                'events': events,
+                'duration': events.aggregate(total=Sum('duration')),
+                'user': user
+            })
+
+        return output
diff --git a/production/managers.py b/production/managers.py
index ca9b5d0ba99fb56cdce96d96963337445f27d16e..1980044f4840ed438519832433c5603dbe9fa012 100644
--- a/production/managers.py
+++ b/production/managers.py
@@ -3,14 +3,17 @@ from django.db import models
 from .constants import PRODUCTION_STREAM_COMPLETED, PRODUCTION_STREAM_ONGOING
 
 
-class ProductionStreamManager(models.Manager):
+class ProductionStreamQuerySet(models.QuerySet):
     def completed(self):
         return self.filter(status=PRODUCTION_STREAM_COMPLETED)
 
     def ongoing(self):
         return self.filter(status=PRODUCTION_STREAM_ONGOING)
 
+    def filter_for_user(self, production_user):
+        return self.filter(officer=production_user)
+
 
 class ProductionEventManager(models.Manager):
-    def get_my_events(self, current_contributor):
-        return self.filter(noted_by=current_contributor)
+    def get_my_events(self, production_user):
+        return self.filter(noted_by=production_user)
diff --git a/production/migrations/0011_productionuser.py b/production/migrations/0011_productionuser.py
new file mode 100644
index 0000000000000000000000000000000000000000..ed1ec512c86ec9a248b976035bc7448adc1ca8e2
--- /dev/null
+++ b/production/migrations/0011_productionuser.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-14 17:07
+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 = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('production', '0010_auto_20170707_0600'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='ProductionUser',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('user', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+    ]
diff --git a/production/migrations/0012_productionstream_officers.py b/production/migrations/0012_productionstream_officers.py
new file mode 100644
index 0000000000000000000000000000000000000000..37835f8f2b46f2c8f4b02aa52b031145ca3cc27a
--- /dev/null
+++ b/production/migrations/0012_productionstream_officers.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-14 18:20
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('production', '0011_productionuser'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='productionstream',
+            name='officers',
+            field=models.ManyToManyField(blank=True, to='production.ProductionUser'),
+        ),
+    ]
diff --git a/production/migrations/0013_auto_20170914_2220.py b/production/migrations/0013_auto_20170914_2220.py
new file mode 100644
index 0000000000000000000000000000000000000000..8eaa1babf34e39c504ff3de4ad6ee7f6a0a7c3d8
--- /dev/null
+++ b/production/migrations/0013_auto_20170914_2220.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-14 20:20
+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 = [
+        ('production', '0012_productionstream_officers'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='productionevent',
+            old_name='noted_by',
+            new_name='noted_by_contributor',
+        ),
+        migrations.AlterField(
+            model_name='productionstream',
+            name='officers',
+            field=models.ManyToManyField(blank=True, related_name='streams', to='production.ProductionUser'),
+        ),
+        migrations.AlterField(
+            model_name='productionuser',
+            name='user',
+            field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='production_user', to=settings.AUTH_USER_MODEL),
+        ),
+    ]
diff --git a/production/migrations/0014_productionevent_noted_by.py b/production/migrations/0014_productionevent_noted_by.py
new file mode 100644
index 0000000000000000000000000000000000000000..1f728d34daf03dce9adce677fb976e2d91949bc8
--- /dev/null
+++ b/production/migrations/0014_productionevent_noted_by.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-14 20:20
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('production', '0013_auto_20170914_2220'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='productionevent',
+            name='noted_by',
+            field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='production.ProductionUser'),
+            preserve_default=False,
+        ),
+    ]
diff --git a/production/migrations/0015_auto_20170914_2237.py b/production/migrations/0015_auto_20170914_2237.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb9ffcc83c0d5eb059cebe7d315cbc44ba31dc36
--- /dev/null
+++ b/production/migrations/0015_auto_20170914_2237.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-14 20:37
+from __future__ import unicode_literals
+
+from django.contrib.auth.models import Group, User
+from django.db import migrations
+
+
+def contributor_to_officer(apps, schema_editor):
+    # Create ProductionUser for all current Officers
+    ProductionUser = apps.get_model('production', 'ProductionUser')
+    officers = Group.objects.get(name='Production Officers')
+    for user in officers.user_set.all():
+        ProductionUser.objects.get_or_create(user_id=user.id)
+    print('\n  - Production Officers transfered to ProductionUser')
+
+    # Transfer all Events
+    ProductionEvent = apps.get_model('production', 'ProductionEvent')
+    for event in ProductionEvent.objects.all():
+        user = User.objects.get(contributor__id=event.noted_by_contributor.id, production_user__isnull=False)
+        event.noted_by.id = user.production_user.id
+        event.save()
+    print('  - ProductionEvents updated')
+
+    return
+
+
+def officer_to_contributor(apps, schema_editor):
+    # Transfer all Events
+    ProductionEvent = apps.get_model('production', 'ProductionEvent')
+    for event in ProductionEvent.objects.all():
+        user = User.objects.get(production_user_id=event.noted_by.id)
+        event.noted_by_contributor.id = user.contributor.id
+        event.save()
+    print('\n  - ProductionEvents updated')
+
+    return
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('production', '0014_productionevent_noted_by'),
+    ]
+
+    operations = [
+        migrations.RunPython(contributor_to_officer, officer_to_contributor)
+    ]
diff --git a/production/migrations/0016_remove_productionevent_noted_by_contributor.py b/production/migrations/0016_remove_productionevent_noted_by_contributor.py
new file mode 100644
index 0000000000000000000000000000000000000000..d204f883e3d7bdbd7fe5a7cb4653a5cc0fde8501
--- /dev/null
+++ b/production/migrations/0016_remove_productionevent_noted_by_contributor.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-14 20:46
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('production', '0015_auto_20170914_2237'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='productionevent',
+            name='noted_by_contributor',
+            field=models.ForeignKey(default=1, null=True, on_delete=django.db.models.deletion.CASCADE, to='scipost.Contributor'),
+        ),
+        migrations.RemoveField(
+            model_name='productionevent',
+            name='noted_by_contributor',
+        ),
+    ]
diff --git a/production/migrations/0017_auto_20170914_2319.py b/production/migrations/0017_auto_20170914_2319.py
new file mode 100644
index 0000000000000000000000000000000000000000..95e2983d46fd0db386be12b5415cfd05520879ba
--- /dev/null
+++ b/production/migrations/0017_auto_20170914_2319.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-14 21:19
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('production', '0016_remove_productionevent_noted_by_contributor'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='productionevent',
+            name='stream',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to='production.ProductionStream'),
+        ),
+    ]
diff --git a/production/migrations/0018_auto_20170929_2234.py b/production/migrations/0018_auto_20170929_2234.py
new file mode 100644
index 0000000000000000000000000000000000000000..335424b7a30b80facd8a09e460e363f362afbf69
--- /dev/null
+++ b/production/migrations/0018_auto_20170929_2234.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-29 20:34
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('production', '0017_auto_20170914_2319'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='productionstream',
+            name='officers',
+        ),
+        migrations.AddField(
+            model_name='productionstream',
+            name='officer',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='streams', to='production.ProductionUser'),
+        ),
+        migrations.AddField(
+            model_name='productionstream',
+            name='supervisor',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='supervised_streams', to='production.ProductionUser'),
+        ),
+    ]
diff --git a/production/migrations/0019_auto_20170929_2310.py b/production/migrations/0019_auto_20170929_2310.py
new file mode 100644
index 0000000000000000000000000000000000000000..74565042d4b6788264ef4a0a49643d2ed0105aaf
--- /dev/null
+++ b/production/migrations/0019_auto_20170929_2310.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-29 21:10
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('production', '0018_auto_20170929_2234'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='productionstream',
+            options={'permissions': (('can_perform_supervisory_actions', 'Can perform supervisory actions'),)},
+        ),
+    ]
diff --git a/production/migrations/0020_auto_20170930_0156.py b/production/migrations/0020_auto_20170930_0156.py
new file mode 100644
index 0000000000000000000000000000000000000000..305d366b3f494fe473189539b92ec9c49c0b0bca
--- /dev/null
+++ b/production/migrations/0020_auto_20170930_0156.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-29 23:56
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('production', '0019_auto_20170929_2310'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='productionstream',
+            options={'permissions': (('can_work_for_stream', 'Can work for stream'), ('can_perform_supervisory_actions', 'Can perform supervisory actions'))},
+        ),
+        migrations.AlterField(
+            model_name='productionevent',
+            name='noted_by',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to='production.ProductionUser'),
+        ),
+    ]
diff --git a/production/models.py b/production/models.py
index 3d94ddaa295504fbb05aa1224937ee7436f2093b..17f2d73c427e11c0ebfa04d2f3d77a7fca235400 100644
--- a/production/models.py
+++ b/production/models.py
@@ -1,9 +1,24 @@
 from django.db import models
-from django.utils import timezone
 from django.core.urlresolvers import reverse
+from django.contrib.auth.models import User
+from django.utils import timezone
 
 from .constants import PRODUCTION_STREAM_STATUS, PRODUCTION_STREAM_ONGOING, PRODUCTION_EVENTS
-from .managers import ProductionStreamManager, ProductionEventManager
+from .managers import ProductionStreamQuerySet, ProductionEventManager
+
+
+class ProductionUser(models.Model):
+    """
+    Production Officers will have a ProductionUser object related to their account
+    to relate all production related actions to.
+    """
+    user = models.OneToOneField(User, on_delete=models.PROTECT, unique=True,
+                                related_name='production_user')
+
+    # objects = ProductionUserQuerySet.as_manager()  -- Not implemented yet
+
+    def __str__(self):
+        return '%s, %s' % (self.user.last_name, self.user.first_name)
 
 
 class ProductionStream(models.Model):
@@ -12,8 +27,18 @@ class ProductionStream(models.Model):
     closed = models.DateTimeField(default=timezone.now)
     status = models.CharField(max_length=32,
                               choices=PRODUCTION_STREAM_STATUS, default=PRODUCTION_STREAM_ONGOING)
+    officer = models.ForeignKey('production.ProductionUser', blank=True, null=True,
+                                related_name='streams')
+    supervisor = models.ForeignKey('production.ProductionUser', blank=True, null=True,
+                                   related_name='supervised_streams')
 
-    objects = ProductionStreamManager()
+    objects = ProductionStreamQuerySet.as_manager()
+
+    class Meta:
+        permissions = (
+            ('can_work_for_stream', 'Can work for stream'),
+            ('can_perform_supervisory_actions', 'Can perform supervisory actions'),
+        )
 
     def __str__(self):
         return '{arxiv}, {title}'.format(arxiv=self.submission.arxiv_identifier_w_vn_nr,
@@ -25,16 +50,17 @@ class ProductionStream(models.Model):
         return reverse('production:completed') + '#stream_' + str(self.id)
 
     def total_duration(self):
-        totdur = self.productionevent_set.aggregate(models.Sum('duration'))
+        totdur = self.events.aggregate(models.Sum('duration'))
         return totdur['duration__sum']
 
 
 class ProductionEvent(models.Model):
-    stream = models.ForeignKey(ProductionStream, on_delete=models.CASCADE)
+    stream = models.ForeignKey(ProductionStream, on_delete=models.CASCADE, related_name='events')
     event = models.CharField(max_length=64, choices=PRODUCTION_EVENTS)
     comments = models.TextField(blank=True, null=True)
     noted_on = models.DateTimeField(default=timezone.now)
-    noted_by = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE)
+    noted_by = models.ForeignKey('production.ProductionUser', on_delete=models.CASCADE,
+                                 related_name='events')
     duration = models.DurationField(blank=True, null=True)
 
     objects = ProductionEventManager()
diff --git a/production/permissions.py b/production/permissions.py
new file mode 100644
index 0000000000000000000000000000000000000000..54012de7d339d7367a33dc9e62187e45402fa1d1
--- /dev/null
+++ b/production/permissions.py
@@ -0,0 +1,11 @@
+from django.contrib.auth.decorators import user_passes_test
+
+
+def is_production_user():
+    """Requires user to be a ProductionUser."""
+    def test(u):
+        if u.is_authenticated():
+            if hasattr(u, 'production_user') and u.production_user:
+                return True
+        return False
+    return user_passes_test(test)
diff --git a/production/signals.py b/production/signals.py
index 6a3102f9249f4a5a71f1a9603974a7590b1b4a31..2d17c3a331cd97ce5d2547cd909b5188a472ee6e 100644
--- a/production/signals.py
+++ b/production/signals.py
@@ -1,17 +1,27 @@
-from django.contrib.auth.models import Group, User
+from django.contrib.auth.models import Group
 
 from notifications.signals import notify
 
 
 def notify_new_stream(sender, instance, created, **kwargs):
     """
-    Notify the production team about a new Production Stream created.
+    Notify the production supervisors about a new Production Stream that is created.
     """
     if created:
-        production_officers = User.objects.filter(groups__name='Production Officers')
         editorial_college = Group.objects.get(name='Editorial College')
-        for user in production_officers:
-            notify.send(sender=sender, recipient=user, actor=editorial_college, verb=' accepted a submission. A new productionstream has been started.', target=instance)
+        supervisors = Group.objects.get(name='Production Supervisor')
+        for recipient in supervisors.user_set.all():
+            notify.send(sender=sender, recipient=recipient, actor=editorial_college,
+                        verb=' accepted a Submission. A new Production Stream has started.',
+                        target=instance)
+
+
+def notify_new_stream_assignment(sender, instance, recipient, **kwargs):
+    """
+    Notify a production officer about its new Production Stream assignment.
+    """
+    notify.send(sender=sender, recipient=recipient, actor=sender,
+                verb=' assigned you to a Production Stream.', target=instance)
 
 
 def notify_new_event(sender, instance, created, **kwargs):
@@ -19,15 +29,26 @@ def notify_new_event(sender, instance, created, **kwargs):
     Notify the production team about a new Production Event created.
     """
     if created:
-        production_officers = User.objects.filter(groups__name='Production Officers')
-        for user in production_officers:
-            notify.send(sender=sender, recipient=user, actor=instance.noted_by.user, verb=' created a new Production Event ', target=instance)
+        stream = instance.stream
+
+        if stream.officer != instance.noted_by:
+            notify.send(sender=sender, recipient=stream.officer.user,
+                        actor=instance.noted_by.user,
+                        verb=' created a new Production Event.', target=instance)
+
+        if stream.supervisor != instance.noted_by:
+            notify.send(sender=sender, recipient=stream.supervisor.user,
+                        actor=instance.noted_by.user,
+                        verb=' created a new Production Event.', target=instance)
 
 
 def notify_stream_completed(sender, instance, **kwargs):
     """
     Notify the production team about a Production Stream being completed.
     """
-    production_officers = User.objects.filter(groups__name='Production Officers')
-    for user in production_officers:
-        notify.send(sender=sender, recipient=user, actor=sender, verb=' marked Production Stream as completed.', target=instance)
+    stream = instance.stream
+    notify.send(sender=sender, recipient=stream.officer.user,
+                actor=sender, verb=' marked Production Stream as completed.', target=instance)
+
+    notify.send(sender=sender, recipient=stream.supervisor.user,
+                actor=sender, verb=' marked Production Stream as completed.', target=instance)
diff --git a/production/templates/production/_production_stream_card.html b/production/templates/production/_production_stream_card.html
deleted file mode 100644
index 5e3f387e06cfe43c5626ff9496a9ac60a505cc87..0000000000000000000000000000000000000000
--- a/production/templates/production/_production_stream_card.html
+++ /dev/null
@@ -1,32 +0,0 @@
-{% load bootstrap %}
-{% load scipost_extras %}
-
-<div class="w-100" id="stream_{{stream.id}}">
-    {% include 'submissions/_submission_card_content_sparse.html' with submission=stream.submission %}
-</div>
-<div class="card-body">
-  <div class="row">
-    <div class="{% if form %}col-lg-7{% else %}col-12{% endif %}">
-      <h3>Events</h3>
-      {% include 'production/_production_events.html' with events=stream.productionevent_set.all %}
-      <br/>
-
-      {% if stream.total_duration %}
-          <h3>Total duration for this stream: {{ stream.total_duration|duration }}</h3>
-      {% endif %}
-      {% if perms.scipost.can_publish_accepted_submission %}
-          <h3><a href="{% url 'production:mark_as_completed' stream_id=stream.id %}">Mark this stream as completed</a></h3>
-      {% endif %}
-    </div>
-    {% if form %}
-        <div class="col-lg-5 mt-4 mt-lg-0">
-          <h3>Add an event to this production stream:</h3>
-          <form action="{% url 'production:add_event' stream_id=stream.id %}" method="post">
-        	{% csrf_token %}
-        	{{ form|bootstrap }}
-        	<input type="submit" class="btn btn-secondary" name="submit" value="Submit">
-          </form>
-        </div>
-    {% endif %}
-  </div>
-</div>
diff --git a/production/templates/production/base.html b/production/templates/production/base.html
new file mode 100644
index 0000000000000000000000000000000000000000..9dbe1e96d72f246f9e72efd84824244d9c2f11f5
--- /dev/null
+++ b/production/templates/production/base.html
@@ -0,0 +1,13 @@
+{% extends 'scipost/base.html' %}
+
+{% block breadcrumb %}
+    <nav class="breadcrumb py-md-2 px-0 hidden-sm-down">
+        <div class="container">
+            {% block breadcrumb_items %}
+                <a href="{% url 'production:production' %}" class="breadcrumb-item">Production page</a>
+            {% endblock %}
+        </div>
+    </nav>
+{% endblock %}
+
+{% block container_class %}{{block.super}} pb-5{% endblock container_class %}
diff --git a/production/templates/production/completed.html b/production/templates/production/completed.html
index 2e6fb2911d22a8c576c8e12d2b91b4619e93bf10..f5a80521b88400faa419fd7edbacbfe484066f03 100644
--- a/production/templates/production/completed.html
+++ b/production/templates/production/completed.html
@@ -1,4 +1,4 @@
-{% extends 'scipost/_personal_page_base.html' %}
+{% extends 'production/base.html' %}
 
 {% block breadcrumb_items %}
     {{block.super}}
@@ -21,11 +21,7 @@
     <ul class="list-group list-group-flush">
       {% for stream in streams %}
         <li class="list-group-item">
-            <div class="w-100" id="stream_{{stream.id}}">{% include 'submissions/_submission_card_content_sparse.html' with submission=stream.submission %}</div>
-            <div class="card-body">
-                <h3>Events</h3>
-                {% include 'production/_production_events.html' with events=stream.productionevent_set.all %}
-            </div>
+            {% include 'production/partials/production_stream_card_completed.html' with stream=stream %}
         </li>
       {% empty %}
         <li class="list-group-item">No completed production streams found.</li>
diff --git a/production/templates/production/_production_events.html b/production/templates/production/partials/production_events.html
similarity index 73%
rename from production/templates/production/_production_events.html
rename to production/templates/production/partials/production_events.html
index e7d168b13c52553b541c78e7768c03fb95d45049..4db2ab632d6bd8355d34b79b84577c94588651dc 100644
--- a/production/templates/production/_production_events.html
+++ b/production/templates/production/partials/production_events.html
@@ -4,10 +4,12 @@
   {% for event in events %}
         <li id="event_{{ event.id }}">
           <p class="mb-0 font-weight-bold">{{ event.get_event_display }}
-              {% if event.noted_by == request.user.contributor %}
+            {% if not non_editable %}
+              {% if event.noted_by == request.user.production_user %}
                   &middot; <a href="{% url 'production:update_event' event.id %}">Edit</a>
                   &middot; <a class="text-danger" href="{% url 'production:delete_event' event.id %}">Delete</a>
               {% endif %}
+            {% endif %}
           </p>
           <p class="text-muted mb-1">noted {{ event.noted_on }} by {{ event.noted_by }}</p>
           {% if event.duration %}
@@ -21,3 +23,8 @@
         <li>No events were found.</li>
     {% endfor %}
 </ul>
+
+{% if stream.total_duration %}
+    <hr class="sm">
+    <p class="pl-4 ml-3">Total duration for this stream: <strong>{{ stream.total_duration|duration }}</strong></p>
+{% endif %}
diff --git a/production/templates/production/partials/production_stream_card.html b/production/templates/production/partials/production_stream_card.html
new file mode 100644
index 0000000000000000000000000000000000000000..f1f88a5687e19c1fa867ca46cb2a9ab95de00372
--- /dev/null
+++ b/production/templates/production/partials/production_stream_card.html
@@ -0,0 +1,67 @@
+{% extends 'production/partials/production_stream_card_completed.html' %}
+
+{% load bootstrap %}
+{% load guardian_tags %}
+
+{% get_obj_perms request.user for stream as "sub_perms" %}
+
+{% block actions %}
+  <h3>Events</h3>
+  {% include 'production/partials/production_events.html' with events=stream.events.all %}
+
+  {% if perms.scipost.can_publish_accepted_submission or perms.scipost.can_assign_production_supervisor or "can_perform_supervisory_actions" in sub_perms %}
+      <h3>Actions</h3>
+      <ul>
+          {% if perms.scipost.can_assign_production_supervisor and assign_supervisor_form %}
+              <li>
+                  <a href="javascript:;" data-toggle="toggle" data-target="#add_supervisor_{{stream.id}}">Assign Production Supervisor to this stream</a>
+                  <div id="add_supervisor_{{stream.id}}" style="display: none;">
+                      <form class="my-3" action="{% url 'production:add_supervisor' stream_id=stream.id %}" method="post">
+                          {% csrf_token %}
+                          {{ assign_supervisor_form|bootstrap_inline }}
+                          <input type="submit" class="btn btn-outline-primary" name="submit" value="Add officer">
+                      </form>
+                  </div>
+              </li>
+          {% endif %}
+          {% if "can_perform_supervisory_actions" in sub_perms and assign_officer_form %}
+            <li>
+                <a href="javascript:;" data-toggle="toggle" data-target="#add_officer_{{stream.id}}">Assign Production Officer to this stream</a>
+                <div id="add_officer_{{stream.id}}" style="display: none;">
+                    <form class="my-3" action="{% url 'production:add_officer' stream_id=stream.id %}" method="post">
+                      	{% csrf_token %}
+                      	{{ assign_officer_form|bootstrap_inline }}
+                      	<input type="submit" class="btn btn-outline-primary" name="submit" value="Add officer">
+                    </form>
+                </div>
+            </li>
+          {% endif %}
+          {% if perms.scipost.can_publish_accepted_submission %}
+            <li><a href="{% url 'production:mark_as_completed' stream_id=stream.id %}">Mark this stream as completed</a></li>
+          {% endif %}
+      </ul>
+  {% endif %}
+{% endblock %}
+
+{% block officers %}
+    <li>Production Supervisor:
+          {% if stream.supervisor %}
+              <strong>{{ stream.supervisor }}</strong>
+              {% if perms.scipost.can_assign_production_supervisor %}
+                  &middot; <a href="{% url 'production:remove_supervisor' stream_id=stream.id officer_id=stream.supervisor.id %}" class="text-danger">Remove from stream</a>
+              {% endif %}
+          {% else %}
+              <em>No Supervisor assigned yet.</em>
+          {% endif %}
+    </li>
+    <li>Production Officer:
+          {% if stream.officer %}
+              <strong>{{ stream.officer }}</strong>
+              {% if "can_perform_supervisory_actions" in sub_perms %}
+                  &middot; <a href="{% url 'production:remove_officer' stream_id=stream.id officer_id=stream.officer.id %}" class="text-danger">Remove from stream</a>
+              {% endif %}
+          {% else %}
+              <em>No Officer assigned yet.</em>
+          {% endif %}
+    </li>
+{% endblock %}
diff --git a/production/templates/production/partials/production_stream_card_completed.html b/production/templates/production/partials/production_stream_card_completed.html
new file mode 100644
index 0000000000000000000000000000000000000000..f31b37b1a2d379c05a24c49019c45c0fc7f81d06
--- /dev/null
+++ b/production/templates/production/partials/production_stream_card_completed.html
@@ -0,0 +1,49 @@
+{% load bootstrap %}
+{% load guardian_tags %}
+
+{% get_obj_perms request.user for stream as "sub_perms" %}
+
+<div class="w-100" id="stream_{{stream.id}}">
+    {% include 'submissions/_submission_card_content_sparse.html' with submission=stream.submission %}
+</div>
+<div class="card-body">
+  <div class="row">
+    <div class="{% if prodevent_form %}col-lg-7{% else %}col-12{% endif %}">
+      <h3>Officers</h3>
+      <ul>
+          {% block officers %}
+              <li>Production Supervisor:
+                    {% if stream.supervisor %}
+                        <strong>{{ stream.supervisor }}</strong>
+                    {% else %}
+                        <em>No Supervisor assigned.</em>
+                    {% endif %}
+              </li>
+              <li>Production Officer:
+                    {% if stream.officer %}
+                        <strong>{{ stream.officer }}</strong>
+                    {% else %}
+                        <em>No Officer assigned.</em>
+                    {% endif %}
+              </li>
+          {% endblock %}
+      </ul>
+
+      {% block actions %}
+          <h3>Events</h3>
+          {% include 'production/partials/production_events.html' with events=stream.events.all non_editable=1 %}
+      {% endblock %}
+
+  </div>
+    {% if prodevent_form and "can_work_for_stream" in sub_perms %}
+        <div class="col-lg-5 mt-4 mt-lg-0">
+          <h3>Add an event to this production stream:</h3>
+          <form action="{% url 'production:add_event' stream_id=stream.id %}" method="post">
+        	{% csrf_token %}
+        	{{ prodevent_form|bootstrap }}
+        	<input type="submit" class="btn btn-secondary" name="submit" value="Submit">
+          </form>
+        </div>
+    {% endif %}
+  </div>
+</div>
diff --git a/production/templates/production/_production_timesheet_card.html b/production/templates/production/partials/production_timesheet_card.html
similarity index 96%
rename from production/templates/production/_production_timesheet_card.html
rename to production/templates/production/partials/production_timesheet_card.html
index 7feed2713930a1cd5a94419470b4580d73e9c933..462d0b2eb08b1dd2677c645fc80472db16a01c32 100644
--- a/production/templates/production/_production_timesheet_card.html
+++ b/production/templates/production/partials/production_timesheet_card.html
@@ -1,5 +1,3 @@
-{% load bootstrap %}
-
 <div class="card-body">
   <table class="table mb-5">
     <thead class="thead-default">
diff --git a/production/templates/production/production.html b/production/templates/production/production.html
index c748477f0602c7fa9752847ad328fc7915bb4869..f9a693d6e9f132a36a469f1e2e70d013c37e4f63 100644
--- a/production/templates/production/production.html
+++ b/production/templates/production/production.html
@@ -1,7 +1,6 @@
-{% extends 'scipost/_personal_page_base.html' %}
+{% extends 'production/base.html' %}
 
 {% block breadcrumb_items %}
-    {{block.super}}
     <span class="breadcrumb-item">Production page</span>
 {% endblock %}
 
@@ -24,16 +23,16 @@
       <div class="tab-nav-inner">
 	<ul class="nav btn-group personal-page-nav" role="tablist">
 	  <li class="nav-item btn btn-secondary">
-	    <a href="#streams" class="nav-link active" data-toggle="tab">Streams</a>
+	    <a href="#streams" class="nav-link active" data-toggle="tab">{{ perms.scipost.can_assign_production_officer|yesno:"Streams,My Streams" }}</a>
 	  </li>
 	  <li class="nav-item btn btn-secondary">
 	    <a href="#mytimesheet" class="nav-link" data-toggle="tab">My Timesheet</a>
 	  </li>
-	  {% if perms.scipost.can_view_timesheets %}
-	  <li class="nav-item btn btn-secondary">
-	    <a href="#teamtimesheets" class="nav-link" data-toggle="tab">Team Timesheets</a>
-	  </li>
-	  {% endif %}
+      {% if perms.scipost.can_promote_user_to_production_officer %}
+          <li class="nav-item btn btn-secondary">
+            <a href="#officers" class="nav-link" data-toggle="tab">Production Team</a>
+          </li>
+      {% endif %}
 	</ul>
       </div>
     </div>
@@ -45,7 +44,8 @@
   <div class="tab-pane active" id="streams" role="tabpanel">
     <div class="row">
       <div class="col-12">
-	<h2 class="highlight">Streams</h2>
+    	<h2 class="highlight">{{ perms.scipost.can_assign_production_officer|yesno:"Streams,My Streams" }}</h2>
+        <a href="{% url 'production:completed' %}">View completed streams</a>
       </div>
     </div>
 
@@ -61,24 +61,24 @@
       </thead>
 
       <tbody id="accordion" role="tablist" aria-multiselectable="true">
-	{% for stream in streams %}
-	<tr data-toggle="collapse" data-parent="#accordion" href="#collapse{{ stream.id }}" aria-expanded="true" aria-controls="collapse{{ stream.id }}" style="cursor: pointer;">
-	  <td>{{ stream.submission.author_list }}</td>
-	  <td>{{ stream.submission.title }}</td>
-	  <td>{{ stream.submission.acceptance_date|date:"Y-m-d" }}</td>
-	  <td>{{ stream.productionevent_set.last.get_event_display }}</td>
-	  <td>{{ stream.productionevent_set.last.noted_on }}</td>
-	</tr>
-	<tr id="collapse{{ stream.id }}" class="collapse" role="tabpanel" aria-labelledby="heading{{ stream.id }}" style="background-color: #fff;">
-	  <td colspan="5">
-            {% include 'production/_production_stream_card.html' with stream=stream form=prodevent_form %}
-	  </td>
-	</tr>
-	{% empty %}
-	<tr>
-	  <td colspan="5">No production streams found.</td>
-	</tr>
-	{% endfor %}
+    	{% for stream in streams %}
+        	<tr data-toggle="collapse" data-parent="#accordion" href="#collapse{{ stream.id }}" aria-expanded="true" aria-controls="collapse{{ stream.id }}" style="cursor: pointer;">
+        	  <td>{{ stream.submission.author_list }}</td>
+        	  <td>{{ stream.submission.title }}</td>
+        	  <td>{{ stream.submission.acceptance_date|date:"Y-m-d" }}</td>
+        	  <td>{{ stream.events.last.get_event_display }}</td>
+        	  <td>{{ stream.events.last.noted_on }}</td>
+        	</tr>
+        	<tr id="collapse{{ stream.id }}" class="collapse" role="tabpanel" aria-labelledby="heading{{ stream.id }}" style="background-color: #fff;">
+        	  <td colspan="5">
+                    {% include 'production/partials/production_stream_card.html' with stream=stream prodevent_form=prodevent_form assignment_form=assignment_form %}
+        	  </td>
+        	</tr>
+    	{% empty %}
+        	<tr>
+        	  <td colspan="5">No production streams found.</td>
+        	</tr>
+    	{% endfor %}
       </tbody>
     </table>
   </div>
@@ -87,7 +87,10 @@
   <div class="tab-pane" id="mytimesheet" role="tabpanel">
     <div class="row">
       <div class="col-12">
-	<h2 class="highlight">My Timesheet</h2>
+    	<h2 class="highlight">My Timesheet</h2>
+        {% if perms.scipost.can_view_timesheets %}
+            <a href="{% url 'finances:timesheets' %}">See team timesheets</a>
+        {% endif %}
       </div>
     </div>
 
@@ -118,40 +121,25 @@
     </table>
   </div>
 
-  {% if perms.scipost.can_view_timesheets %}
-  <div class="tab-pane" id="teamtimesheets" role="tabpanel">
-    <div class="row">
-      <div class="col-12">
-	<h2 class="highlight">Team Timesheets</h2>
+  {% if perms.scipost.can_promote_user_to_production_officer %}
+      <div class="tab-pane" id="officers" role="tabpanel">
+          <h2 class="highlight">Production Tream</h2>
+          <h3>Current Production Team</h3>
+          <ul>
+              {% for officer in production_officers %}
+                <li>{{ officer }}</li>
+              {% endfor %}
+          </ul>
+
+          {% if new_officer_form %}
+              <h3>Promote user to Production Officer</h3>
+              <form action="{% url 'production:user_to_officer' %}" method="post">
+                {% csrf_token %}
+                {{ new_officer_form|bootstrap }}
+                <input type="submit" class="btn btn-primary" value="Promote to Production Officer">
+            </form>
+          {% endif %}
       </div>
-    </div>
-
-    <table class="table table-hover mb-5">
-      <thead class="thead-default">
-	<tr>
-	  <th>Name</th>
-	</tr>
-      </thead>
-
-      <tbody id="accordion" role="tablist" aria-multiselectable="true">
-	{% for member in production_team.all %}
-	<tr data-toggle="collapse" data-parent="#accordion" href="#collapse{{ member.id }}" aria-expanded="true" aria-controls="collapse{{ member.id }}" style="cursor: pointer;">
-	  <td>{{ member }}</td>
-	</tr>
-	<tr id="collapse{{ member.id }}" class="collapse" role="tabpanel" aria-labelledby="heading{{ member.id }}" style="background-color: #fff;">
-	  <td>
-	    {% include 'production/_production_timesheet_card.html' with events=member.productionevent_set.all %}
-	  </td>
-	</tr>
-	{% empty %}
-	<tr>
-	  <td>No Team Member found.</td>
-	</tr>
-	{% endfor %}
-      </tbody>
-    </table>
-
-  </div>
   {% endif %}
 
 </div>
diff --git a/production/templates/production/productionevent_confirm_delete.html b/production/templates/production/productionevent_confirm_delete.html
index 75feabb00b889ffabc5af687a2040082ae57002a..c6cd4c05a4da812c0739cc41bab2f72103b4f4ae 100644
--- a/production/templates/production/productionevent_confirm_delete.html
+++ b/production/templates/production/productionevent_confirm_delete.html
@@ -1,8 +1,7 @@
-{% extends 'scipost/_personal_page_base.html' %}
+{% extends 'production/base.html' %}
 
 {% block breadcrumb_items %}
     {{block.super}}
-    <a href="{{object.get_absolute_url}}" class="breadcrumb-item">Production streams</a>
     <span class="breadcrumb-item">Delete production event</span>
 {% endblock %}
 
diff --git a/production/templates/production/productionevent_form.html b/production/templates/production/productionevent_form.html
index fc90e04c976d7d7315c0ee5f2e590cabf349d448..d520f1c75c2a200a9657e62dec024527fe0d1055 100644
--- a/production/templates/production/productionevent_form.html
+++ b/production/templates/production/productionevent_form.html
@@ -1,8 +1,7 @@
-{% extends 'scipost/_personal_page_base.html' %}
+{% extends 'production/base.html' %}
 
 {% block breadcrumb_items %}
     {{block.super}}
-    <a href="{{object.get_absolute_url}}" class="breadcrumb-item">Production streams</a>
     <span class="breadcrumb-item">Edit production event</span>
 {% endblock %}
 
diff --git a/production/urls.py b/production/urls.py
index cc5bf527b92c39690aabca17762514101ff57daf..8631da56cd28b1f9a99f50f85072d7477ba71204 100644
--- a/production/urls.py
+++ b/production/urls.py
@@ -5,8 +5,17 @@ from production import views as production_views
 urlpatterns = [
     url(r'^$', production_views.production, name='production'),
     url(r'^completed$', production_views.completed, name='completed'),
+    url(r'^officers/new$', production_views.user_to_officer, name='user_to_officer'),
     url(r'^streams/(?P<stream_id>[0-9]+)/events/add$',
         production_views.add_event, name='add_event'),
+    url(r'^streams/(?P<stream_id>[0-9]+)/officer/add$',
+        production_views.add_officer, name='add_officer'),
+    url(r'^streams/(?P<stream_id>[0-9]+)/officer/(?P<officer_id>[0-9]+)/remove$',
+        production_views.remove_officer, name='remove_officer'),
+    url(r'^streams/(?P<stream_id>[0-9]+)/supervisor/add$',
+        production_views.add_supervisor, name='add_supervisor'),
+    url(r'^streams/(?P<stream_id>[0-9]+)/supervisor/(?P<officer_id>[0-9]+)/remove$',
+        production_views.remove_supervisor, name='remove_supervisor'),
     url(r'^streams/(?P<stream_id>[0-9]+)/mark_completed$',
         production_views.mark_as_completed, name='mark_as_completed'),
     url(r'^events/(?P<event_id>[0-9]+)/edit',
diff --git a/production/views.py b/production/views.py
index 517c09c116ecdd90c20cc0dcdc5ba199f194a202..bcafcdbe0da5502211e0825a37054690ba9f205d 100644
--- a/production/views.py
+++ b/production/views.py
@@ -1,73 +1,185 @@
 import datetime
 
 from django.contrib import messages
+from django.contrib.auth.decorators import permission_required
 from django.contrib.auth.models import Group
 from django.core.urlresolvers import reverse
+from django.db import transaction
 from django.shortcuts import get_object_or_404, render, redirect
 from django.utils import timezone
 from django.utils.decorators import method_decorator
 from django.views.generic.edit import UpdateView, DeleteView
 
-from guardian.decorators import permission_required
+from guardian.core import ObjectPermissionChecker
+from guardian.shortcuts import assign_perm
 
 from .constants import PRODUCTION_STREAM_COMPLETED
-from .models import ProductionStream, ProductionEvent
-from .forms import ProductionEventForm
-from .signals import notify_stream_completed
-
-from scipost.models import Contributor
+from .models import ProductionUser, ProductionStream, ProductionEvent
+from .forms import ProductionEventForm, AssignOfficerForm, UserToOfficerForm, AssignSupervisorForm
+from .permissions import is_production_user
+from .signals import notify_stream_completed, notify_new_stream_assignment
 
 
 ######################
 # Production process #
 ######################
 
-@permission_required('scipost.can_view_production', return_403=True)
+@is_production_user()
+@permission_required('scipost.can_view_production', raise_exception=True)
 def production(request):
     """
     Overview page for the production process.
     All papers with accepted but not yet published status are included here.
     """
-    streams = ProductionStream.objects.ongoing().order_by('opened')
+    streams = ProductionStream.objects.ongoing()
+    if not request.user.has_perm('scipost.can_view_all_production_streams'):
+        # Restrict stream queryset if user is not supervisor
+        streams = streams.filter_for_user(request.user.production_user)
+    streams = streams.order_by('opened')
+
     prodevent_form = ProductionEventForm()
+    assign_officer_form = AssignOfficerForm()
+    assign_supervisor_form = AssignSupervisorForm()
     ownevents = ProductionEvent.objects.filter(
-        noted_by=request.user.contributor,
+        noted_by=request.user.production_user,
         duration__gte=datetime.timedelta(minutes=1)).order_by('-noted_on')
     context = {
         'streams': streams,
         'prodevent_form': prodevent_form,
+        'assign_officer_form': assign_officer_form,
+        'assign_supervisor_form': assign_supervisor_form,
         'ownevents': ownevents,
     }
     if request.user.has_perm('scipost.can_view_timesheets'):
-        context['production_team'] = Contributor.objects.filter(
-            user__groups__name='Production Officers').order_by('user__last_name')
+        context['production_team'] = ProductionUser.objects.all()
+
+    if request.user.has_perm('scipost.can_promote_to_production_team'):
+        context['production_officers'] = ProductionUser.objects.all()
+        context['new_officer_form'] = UserToOfficerForm()
     return render(request, 'production/production.html', context)
 
 
-@permission_required('scipost.can_view_production', return_403=True)
+@is_production_user()
+@permission_required('scipost.can_view_production', raise_exception=True)
 def completed(request):
     """
     Overview page for closed production streams.
     """
-    streams = ProductionStream.objects.completed().order_by('-opened')
+    streams = ProductionStream.objects.completed()
+    if not request.user.has_perm('scipost.can_view_all_production_streams'):
+        streams = streams.filter_for_user(request.user.production_user)
+    streams = streams.order_by('-opened')
+
     context = {'streams': streams}
     return render(request, 'production/completed.html', context)
 
 
-@permission_required('scipost.can_view_production', return_403=True)
+@is_production_user()
+@permission_required('scipost.can_promote_user_to_production_officer')
+def user_to_officer(request):
+    form = UserToOfficerForm(request.POST or None)
+    if form.is_valid():
+        officer = form.save()
+
+        # Add permission group
+        group = Group.objects.get(name='Production Officers')
+        officer.user.groups.add(group)
+        messages.success(request, '{user} promoted to Production Officer'.format(user=officer))
+    return redirect(reverse('production:production'))
+
+
+@is_production_user()
+@permission_required('scipost.can_view_production', raise_exception=True)
 def add_event(request, stream_id):
-    stream = get_object_or_404(ProductionStream.objects.ongoing(), pk=stream_id)
+    qs = ProductionStream.objects.ongoing()
+    if not request.user.has_perm('scipost.can_assign_production_officer'):
+        qs = qs.filter_for_user(request.user.production_user)
+
+    stream = get_object_or_404(qs, pk=stream_id)
     prodevent_form = ProductionEventForm(request.POST or None)
     if prodevent_form.is_valid():
         prodevent = prodevent_form.save(commit=False)
         prodevent.stream = stream
-        prodevent.noted_by = request.user.contributor
+        prodevent.noted_by = request.user.production_user
         prodevent.save()
     else:
         messages.warning(request, 'The form was invalidly filled.')
     return redirect(reverse('production:production'))
 
 
+@is_production_user()
+@permission_required('scipost.can_assign_production_officer', raise_exception=True)
+def add_officer(request, stream_id):
+    stream = get_object_or_404(ProductionStream.objects.ongoing(), pk=stream_id)
+    checker = ObjectPermissionChecker(request.user)
+    if not checker.has_perm('can_perform_supervisory_actions', stream):
+        return redirect(reverse('production:production'))
+
+    form = AssignOfficerForm(request.POST or None, instance=stream)
+    if form.is_valid():
+        form.save()
+        officer = form.cleaned_data.get('officer')
+        assign_perm('can_work_for_stream', officer.user, stream)
+        messages.success(request, 'Officer {officer} has been assigned.'.format(officer=officer))
+        notify_new_stream_assignment(request.user, stream, officer.user)
+    else:
+        for key, error in form.errors.items():
+            messages.warning(request, error[0])
+    return redirect(reverse('production:production'))
+
+
+@is_production_user()
+@permission_required('scipost.can_assign_production_officer', raise_exception=True)
+def remove_officer(request, stream_id, officer_id):
+    stream = get_object_or_404(ProductionStream.objects.ongoing(), pk=stream_id)
+    checker = ObjectPermissionChecker(request.user)
+    if not checker.has_perm('can_perform_supervisory_actions', stream):
+        return redirect(reverse('production:production'))
+
+    if getattr(stream.officer, 'id', 0) == int(officer_id):
+        officer = stream.officer
+        stream.officer = None
+        stream.save()
+        messages.success(request, 'Officer {officer} has been removed.'.format(officer=officer))
+
+    return redirect(reverse('production:production'))
+
+
+@is_production_user()
+@permission_required('scipost.can_assign_production_supervisor', raise_exception=True)
+@transaction.atomic
+def add_supervisor(request, stream_id):
+    stream = get_object_or_404(ProductionStream.objects.ongoing(), pk=stream_id)
+    form = AssignSupervisorForm(request.POST or None, instance=stream)
+    if form.is_valid():
+        form.save()
+        supervisor = form.cleaned_data.get('supervisor')
+        assign_perm('can_work_for_stream', supervisor.user, stream)
+        messages.success(request, 'Supervisor {supervisor} has been assigned.'.format(
+            supervisor=supervisor))
+        notify_new_stream_assignment(request.user, stream, supervisor.user)
+        assign_perm('can_perform_supervisory_actions', supervisor.user, stream)
+    else:
+        for key, error in form.errors.items():
+            messages.warning(request, error[0])
+    return redirect(reverse('production:production'))
+
+
+@is_production_user()
+@permission_required('scipost.can_assign_production_supervisor', raise_exception=True)
+def remove_supervisor(request, stream_id, officer_id):
+    stream = get_object_or_404(ProductionStream.objects.ongoing(), pk=stream_id)
+    if getattr(stream.supervisor, 'id', 0) == int(officer_id):
+        supervisor = stream.supervisor
+        stream.supervisor = None
+        stream.save()
+        messages.success(request, 'Supervisor {supervisor} has been removed.'.format(
+            supervisor=supervisor))
+
+    return redirect(reverse('production:production'))
+
+
+@method_decorator(is_production_user(), name='dispatch')
 @method_decorator(permission_required('scipost.can_view_production', raise_exception=True),
                   name='dispatch')
 class UpdateEventView(UpdateView):
@@ -77,13 +189,14 @@ class UpdateEventView(UpdateView):
     slug_url_kwarg = 'event_id'
 
     def get_queryset(self):
-        return self.model.objects.get_my_events(self.request.user.contributor)
+        return self.model.objects.get_my_events(self.request.user.production_user)
 
     def form_valid(self, form):
         messages.success(self.request, 'Event updated succesfully')
         return super().form_valid(form)
 
 
+@method_decorator(is_production_user(), name='dispatch')
 @method_decorator(permission_required('scipost.can_view_production', raise_exception=True),
                   name='dispatch')
 class DeleteEventView(DeleteView):
@@ -92,7 +205,7 @@ class DeleteEventView(DeleteView):
     slug_url_kwarg = 'event_id'
 
     def get_queryset(self):
-        return self.model.objects.get_my_events(self.request.user.contributor)
+        return self.model.objects.get_my_events(self.request.user.production_user)
 
     def form_valid(self, form):
         messages.success(self.request, 'Event deleted succesfully')
@@ -102,7 +215,8 @@ class DeleteEventView(DeleteView):
         return self.object.get_absolute_url()
 
 
-@permission_required('scipost.can_publish_accepted_submission', return_403=True)
+@is_production_user()
+@permission_required('scipost.can_publish_accepted_submission', raise_exception=True)
 def mark_as_completed(request, stream_id):
     stream = get_object_or_404(ProductionStream.objects.ongoing(), pk=stream_id)
     stream.status = PRODUCTION_STREAM_COMPLETED
diff --git a/scipost/admin.py b/scipost/admin.py
index c9c58862746e64ee41675f273db517b611b9dd2f..8cfaffcf2da4ef93af08a909d043e8164df872fe 100644
--- a/scipost/admin.py
+++ b/scipost/admin.py
@@ -13,6 +13,7 @@ from scipost.models import Contributor, Remark,\
 
 from journals.models import Publication
 from partners.admin import ContactToUserInline
+from production.admin import ProductionUserInline
 from submissions.models import Submission
 
 
@@ -38,6 +39,7 @@ class UserAdmin(UserAdmin):
     inlines = [
         ContributorInline,
         ContactToUserInline,
+        ProductionUserInline
         ]
     search_fields = ['last_name', 'email']
 
diff --git a/scipost/constants.py b/scipost/constants.py
index e3166d2f4bd8c9517447a913d9b732d8e8f57a7a..07c873c85863224471c0a4b8c839fd6295728176 100644
--- a/scipost/constants.py
+++ b/scipost/constants.py
@@ -136,7 +136,7 @@ CONTRIBUTOR_STATUS = (
     # -4: disabled account (deceased)
     (CONTRIBUTOR_NEWLY_REGISTERED, 'newly registered'),
     (CONTRIBUTOR_NORMAL, 'normal user'),
-    (-1, 'not a professional scientist'),
+    (-1, 'not a professional scientist'),  # Soon to be deprecated
     (-2, 'other account already exists'),
     (-3, 'barred from SciPost'),
     (-4, 'account disabled'),
diff --git a/scipost/management/commands/add_groups_and_permissions.py b/scipost/management/commands/add_groups_and_permissions.py
index 6070f1f785fb738d108bf0d9e0b3e9bf120175fe..638a67dfa9feefffa42216af275ff77ad80cd5f7 100644
--- a/scipost/management/commands/add_groups_and_permissions.py
+++ b/scipost/management/commands/add_groups_and_permissions.py
@@ -27,6 +27,7 @@ class Command(BaseCommand):
         Testers, created = Group.objects.get_or_create(name='Testers')
         Ambassadors, created = Group.objects.get_or_create(name='Ambassadors')
         JuniorAmbassadors, created = Group.objects.get_or_create(name='Junior Ambassadors')
+        ProductionSupervisors, created = Group.objects.get_or_create(name='Production Supervisor')
         ProductionOfficers, created = Group.objects.get_or_create(name='Production Officers')
 
         PartnersAdmin, created = Group.objects.get_or_create(name='Partners Administrators')
@@ -52,8 +53,8 @@ class Command(BaseCommand):
             codename='can_read_partner_page',
             name='Can read Prospective Partner personal page',
             content_type=content_type)
-        can_promote_prospect_to_partner, created = Permission.objects.get_or_create(
-            codename='can_promote_prospect_to_partner',
+        can_promote_to_production_team, created = Permission.objects.get_or_create(
+            codename='can_promote_to_production_team',
             name='Can promote Prospective Partner to Partner',
             content_type=content_type)
         can_view_partners, created = Permission.objects.get_or_create(
@@ -205,6 +206,22 @@ class Command(BaseCommand):
             content_type=content_type)
 
         # Production
+        can_promote_user_to_production_officer, created = Permission.objects.get_or_create(
+            codename='can_promote_user_to_production_officer',
+            name='Can promote user to production officer',
+            content_type=content_type)
+        can_assign_production_officer, created = Permission.objects.get_or_create(
+            codename='can_assign_production_officer',
+            name='Can assign production officer',
+            content_type=content_type)
+        can_view_all_production_streams, created = Permission.objects.get_or_create(
+            codename='can_view_all_production_streams',
+            name='Can view all production stream',
+            content_type=content_type)
+        can_assign_production_supervisor, created = Permission.objects.get_or_create(
+            codename='can_assign_production_supervisor',
+            name='Can assign production supervisor',
+            content_type=content_type)
         can_view_production, created = Permission.objects.get_or_create(
             codename='can_view_production',
             name='Can view production page',
@@ -250,10 +267,13 @@ class Command(BaseCommand):
             can_assign_submissions,
             can_prepare_recommendations_for_voting,
             can_fix_College_decision,
+            can_promote_user_to_production_officer,
             can_view_production,
             can_attend_VGMs,
             can_view_timesheets,
             can_manage_mailchimp,
+            can_view_all_production_streams,
+            can_promote_to_production_team,
         ])
 
         FinancialAdmin.permissions.set([
@@ -278,6 +298,8 @@ class Command(BaseCommand):
             can_publish_accepted_submission,
             can_attend_VGMs,
             can_manage_reports,
+            can_assign_production_supervisor,
+            can_view_all_production_streams,
         ])
 
         EditorialCollege.permissions.set([
@@ -316,6 +338,13 @@ class Command(BaseCommand):
             can_draft_registration_invitations,
         ])
 
+        ProductionSupervisors.permissions.set([
+            can_assign_production_officer,
+            can_view_all_production_streams,
+            can_view_docs_scipost,
+            can_view_production,
+        ])
+
         ProductionOfficers.permissions.set([
             can_view_docs_scipost,
             can_view_production,
@@ -325,7 +354,6 @@ class Command(BaseCommand):
             can_read_partner_page,
             can_view_own_partner_details,
             can_manage_SPB,
-            can_promote_prospect_to_partner,
             can_email_prospartner_contact,
             can_view_partners,
         ])
diff --git a/scipost/managers.py b/scipost/managers.py
index 11af2c2ed8ead11bb2932d4b4c0a9dcef7d1a36d..788aecb9a7773c31236423938c52945692f5fc1c 100644
--- a/scipost/managers.py
+++ b/scipost/managers.py
@@ -4,7 +4,7 @@ from django.db import models
 from django.db.models import Q
 
 from .constants import CONTRIBUTOR_NORMAL, INVITATION_EDITORIAL_FELLOW,\
-                       CONTRIBUTOR_NEWLY_REGISTERED
+                       CONTRIBUTOR_NEWLY_REGISTERED, AUTHORSHIP_CLAIM_PENDING
 
 
 class FellowManager(models.Manager):
@@ -25,6 +25,9 @@ class ContributorManager(models.Manager):
     def awaiting_validation(self):
         return self.filter(user__is_active=False, status=CONTRIBUTOR_NEWLY_REGISTERED)
 
+    def awaiting_vetting(self):
+        return self.filter(user__is_active=True, status=CONTRIBUTOR_NEWLY_REGISTERED)
+
     def fellows(self):
         return self.filter(user__groups__name='Editorial College')
 
@@ -46,3 +49,8 @@ class UnavailabilityPeriodManager(models.Manager):
     def today(self):
         today = datetime.date.today()
         return self.filter(start__lte=today, end__gte=today)
+
+
+class AuthorshipClaimQuerySet(models.QuerySet):
+    def awaiting_vetting(self):
+        return self.filter(status=AUTHORSHIP_CLAIM_PENDING)
diff --git a/scipost/models.py b/scipost/models.py
index fe7afc37b63adc4dae58d7aeeb6d57e9d42bc4dc..88a69d14e41057de35432fbb2e73192181a9d541 100644
--- a/scipost/models.py
+++ b/scipost/models.py
@@ -19,7 +19,7 @@ from .constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS,\
                        AUTHORSHIP_CLAIM_PENDING, AUTHORSHIP_CLAIM_STATUS
 from .fields import ChoiceArrayField
 from .managers import FellowManager, ContributorManager, RegistrationInvitationManager,\
-                      UnavailabilityPeriodManager
+                      UnavailabilityPeriodManager, AuthorshipClaimQuerySet
 
 
 def get_sentinel_user():
@@ -34,8 +34,7 @@ def get_sentinel_user():
 
 class Contributor(models.Model):
     """
-    All users of SciPost are Contributors.
-    Permissions determine the sub-types.
+    All *science* users of SciPost are Contributors.
     username, password, email, first_name and last_name are inherited from User.
     """
     user = models.OneToOneField(User, on_delete=models.PROTECT, unique=True)
@@ -265,6 +264,8 @@ class AuthorshipClaim(models.Model):
     status = models.SmallIntegerField(choices=AUTHORSHIP_CLAIM_STATUS,
                                       default=AUTHORSHIP_CLAIM_PENDING)
 
+    objects = AuthorshipClaimQuerySet.as_manager()
+
 
 class PrecookedEmail(models.Model):
     """
diff --git a/scipost/permissions.py b/scipost/permissions.py
new file mode 100644
index 0000000000000000000000000000000000000000..a9a936925fa6dc6560fc94c8f4d3340c2b9e6cff
--- /dev/null
+++ b/scipost/permissions.py
@@ -0,0 +1,6 @@
+
+def is_tester(user):
+    """
+    This method checks if user is member of the Test Group.
+    """
+    return user.groups.filter(name='Testers').exists()
diff --git a/scipost/static/scipost/assets/css/_pool.scss b/scipost/static/scipost/assets/css/_pool.scss
new file mode 100644
index 0000000000000000000000000000000000000000..5a59e0df5e3c27754ad7f0804bdc167be7f4c14e
--- /dev/null
+++ b/scipost/static/scipost/assets/css/_pool.scss
@@ -0,0 +1,39 @@
+$pool-icons-width: 40px;
+$pool-flex-width: calc(100% - 40px);
+
+
+.editorial-admin,
+.pool {
+    .pool-item {
+        .icons {
+            padding-left: 10px;
+            padding-right: 10px;
+            position: relative;
+            min-height: 1px;
+            flex: 0 0 $pool-icons-width;
+            max-width: $pool-icons-width;
+        }
+
+        .item {
+            flex: 0 0 $pool-flex-width;
+            width: $pool-flex-width;
+            max-width: none;
+        }
+    }
+
+    .card.submission-detail {
+        position: sticky;
+        top: 15px;
+    }
+
+    #details .loading {
+        position: sticky;
+        top: 15px;
+        padding: 5rem 0 3rem 0;
+        text-align: center;
+    }
+
+    li.active {
+        background-color: $gray-100;
+    }
+}
diff --git a/scipost/static/scipost/assets/css/_type.scss b/scipost/static/scipost/assets/css/_type.scss
index 9f21c44547325bbbf1055366f00574a18cc4a3b2..056fe6dcb5bb8c21f77aee7affb8a68a0cfec105 100644
--- a/scipost/static/scipost/assets/css/_type.scss
+++ b/scipost/static/scipost/assets/css/_type.scss
@@ -112,28 +112,6 @@ hr.hr12 {
     margin-bottom: 0;
 }
 
-.circle,
-.circle-clickable {
-    display: inline-block;
-    background: #fff;
-    border: 2px solid #333;
-    color: #333;
-    border-radius: 100%;
-    width: 17px;
-    height: 17px;
-    line-height: 16px;
-    text-align: center;
-    font-size: 9px;
-    transition: 0.1s;
-}
-
-.circle-clickable {
-    cursor: pointer;
-    color: #bbb;
-    border-color: #bbb;
-
-    &:hover {
-        border-color: #333;
-        color: #333;
-    }
+.fa[data-toggle="tooltip"] {
+    font-size: 1.5em;
 }
diff --git a/scipost/static/scipost/assets/css/style.scss b/scipost/static/scipost/assets/css/style.scss
index 5c8bb75eef61d1059c45fa6a2e6d1f86d20e8b1f..be68d319863f3b5d962c823aca10301be2f28b73 100644
--- a/scipost/static/scipost/assets/css/style.scss
+++ b/scipost/static/scipost/assets/css/style.scss
@@ -31,6 +31,7 @@
 @import "navbar";
 @import "nav";
 @import "page_header";
+@import "pool";
 @import "popover";
 @import "tables";
 @import "tooltip";
diff --git a/scipost/static/scipost/assets/js/notifications.js b/scipost/static/scipost/assets/js/notifications.js
index c50749a1fb74048544e60c39438e3075ba14076a..6f85c449bd19b4f917a6aee7affc17bdf1c267fc 100644
--- a/scipost/static/scipost/assets/js/notifications.js
+++ b/scipost/static/scipost/assets/js/notifications.js
@@ -2,7 +2,8 @@ var notify_badge_class = "live_notify_badge";
 var notify_menu_class = "live_notify_list";
 var notify_api_url_count = "/notifications/api/unread_count/";
 var notify_api_url_list = "/notifications/api/list/";
-var notify_api_url_toggle_read = "/notifications/mark-toggle";
+var notify_api_url_toggle_read = "/notifications/mark-toggle/";
+var notify_api_url_mark_all_read = "/notifications/mark-all-as-read/";
 var notify_fetch_count = "5";
 var notify_refresh_period = 15000;
 var consecutive_misfires = 0;
@@ -17,7 +18,7 @@ function initiate_popover(reinitiate) {
     var notification_template = '<div class="popover notifications" role="tooltip"><div class="arrow"></div><h3 class="popover-header h2"></h3><div class="popover-body"></div></div>';
 
     function get_notifications_title() {
-        return 'Latest notifications <div class="badge badge-warning badge-pill live_notify_badge"></div><div class="mt-1"><small><a href="/notifications">See all my notifications</a></small></div>';
+        return 'Latest notifications <div class="badge badge-warning badge-pill live_notify_badge"></div><div class="mt-1"><small><a href="/notifications">See all my notifications</a> &middot; <a href="javascript:;" class="mark_all_read">Mark all as read</a></small></div>';
     }
 
     function get_notifications() {
@@ -42,12 +43,16 @@ function initiate_popover(reinitiate) {
         setTimeout(function() {
             $('.popover [data-toggle="tooltip"]').tooltip({
                 animation: false,
+                delay: {"show": 500, "hide": 100},
                 fallbackPlacement: 'clockwise',
                 placement: 'bottom'
             });
             $('.popover .actions a').on('click', function() {
                 mark_toggle(this)
             })
+            $('.popover a.mark_all_read').on('click', function() {
+                mark_all_read(this)
+            })
         }, 1000);
     });
     if (reinitiate) {
@@ -55,8 +60,7 @@ function initiate_popover(reinitiate) {
     }
 }
 
-
-function mark_toggle(el) {
+function request_reinitiate(url) {
     var r = new XMLHttpRequest();
     r.addEventListener('readystatechange', function(event){
         if (this.readyState == 4 && this.status == 200) {
@@ -64,10 +68,18 @@ function mark_toggle(el) {
             initiate_popover(reinitiate=true)
         }
     })
-    r.open("GET", notify_api_url_toggle_read + '/' + $(el).data('slug') + '/?json=1', true);
+    r.open("GET", url, true);
     r.send();
 }
 
+function mark_all_read(el) {
+    request_reinitiate(notify_api_url_mark_all_read + '?json=1')
+}
+
+function mark_toggle(el) {
+    request_reinitiate(notify_api_url_toggle_read + $(el).data('slug') + '/?json=1')
+}
+
 
 function fill_notification_badge(data) {
     var badges = document.getElementsByClassName(notify_badge_class);
@@ -101,9 +113,9 @@ function get_notification_list() {
             }
 
             if(item.unread) {
-                var mark_as_read = '<div class="actions"><a href="#" data-slug="' + item.slug + '"><i class="fa fa-circle" data-toggle="tooltip" data-placement="auto" title="Mark as unread" aria-hidden="true"></i></a></div>';
+                var mark_as_read = '<div class="actions"><a href="javascript:;" data-slug="' + item.slug + '"><i class="fa fa-circle" data-toggle="tooltip" data-placement="auto" title="Mark as read" aria-hidden="true"></i></a></div>';
             } else {
-                var mark_as_read = '<div class="actions"><a href="#" data-slug="' + item.slug + '"><i class="fa fa-circle-o" data-toggle="tooltip" data-placement="auto" title="Mark as read" aria-hidden="true"></i></a></div>';
+                var mark_as_read = '<div class="actions"><a href="javascript:;" data-slug="' + item.slug + '"><i class="fa fa-circle-o" data-toggle="tooltip" data-placement="auto" title="Mark as unread" aria-hidden="true"></i></a></div>';
             }
             return '<li class="list-group-item ' + (item.unread ? ' active' : '') + '">' + mark_as_read + message + '</li>';
         }).join('');
diff --git a/scipost/static/scipost/assets/js/scripts.js b/scipost/static/scipost/assets/js/scripts.js
index e16263ae7d94b480e54096a08385c61e00e893ba..fcc6ddc4c8d8d56b05c1ad16940e917cccc6342c 100644
--- a/scipost/static/scipost/assets/js/scripts.js
+++ b/scipost/static/scipost/assets/js/scripts.js
@@ -20,6 +20,19 @@ var getUrlParameter = function getUrlParameter(sParam) {
     }
 };
 
+function init_page() {
+    // Show right tab if url contains `tab` GET request
+    var tab = getUrlParameter('tab')
+    if (tab) {
+        $('a[href="#' + tab + '"][data-toggle="tab"]').tab('show');
+    }
+
+    // Auto-submit hook for general form elements
+    $("form .auto-submit input, form.auto-submit input, form.auto-submit select").on('change', function(){
+        $(this).parents('form').submit()
+    });
+}
+
 $(function(){
     // Remove all alerts in screen automatically after 15sec.
     setTimeout(function() {hide_all_alerts()}, 15000);
@@ -29,20 +42,33 @@ $(function(){
         $($(this).attr('data-target')).toggle();
     });
 
-    // Show right tab if url contains `tab` GET request
-    var tab = getUrlParameter('tab')
-    if (tab) {
-        $('a[href="#' + tab + '"][data-toggle="tab"]').tab('show');
-    }
-
     // Change `tab` GET parameter for page-reload
     $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
         var tab_name = e.target.hash.substring(1)
         window.history.replaceState({}, null, '?tab=' + tab_name);
     });
 
-    // Auto-submit hook for general form elements
-    $("form .auto-submit input").on('change', function(){
-        $(this).parents('form').submit()
+    init_page();
+
+    // Simple simple Angular-like loading!
+    $('a[data-toggle="dynamic"]').on('click', function(event) {
+        event.preventDefault();
+        var self = this,
+            url = $(this).attr('href'),
+            target = $(this).attr('data-target');
+        // console.log('click', url, target);
+
+        $(target).html('<div class="loading"><i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i></div>');
+
+        $.get(url + '?json=1').done(function(data) {
+            // console.log('done', data);
+            $(target).html(data);
+            $('[data-target="active-list"]')
+                .find('> li')
+                .removeClass('active')
+            $(self).parents('[data-target="active-list"] > li')
+                .addClass('active');
+            init_page();
+        });
     });
 });
diff --git a/scipost/templates/scipost/navbar.html b/scipost/templates/scipost/navbar.html
index 2095054a8911f5e1770c891c825649bae7cd2bef..d946d267599f9f75c182318174de04f7b0222327 100644
--- a/scipost/templates/scipost/navbar.html
+++ b/scipost/templates/scipost/navbar.html
@@ -46,6 +46,11 @@
               <li class="nav-item">
                   <a class="nav-link" href="{% url 'scipost:logout' %}">Logout</a>
               </li>
+              {% if perms.scipost.can_view_production %}
+                  <li class="nav-item{% if '/production' in request.path %} active{% endif %}">
+                    <a class="nav-link" href="{% url 'production:production' %}">Production</a>
+                  </li>
+              {% endif %}
               {% if perms.scipost.can_oversee_refereeing %}
                   <li class="nav-item{% if '/submissions/admin' in request.path %} active{% endif %}">
                     <a class="nav-link" href="{% url 'submissions:admin' %}">Editorial Administration</a>
diff --git a/scipost/templates/scipost/personal_page.html b/scipost/templates/scipost/personal_page.html
index 0ff78b8eeff9914108b8d946cbc9e338cc1e7c15..ccdef253c64c9c545f4c960d931331a336ad1e7f 100644
--- a/scipost/templates/scipost/personal_page.html
+++ b/scipost/templates/scipost/personal_page.html
@@ -6,7 +6,7 @@
 
 {% block content %}
 
-{% if 'Registered Contributors' not in user_groups %}
+{% if needs_validation %}
 
     <div class="row">
         <div class="col-12">
@@ -38,38 +38,37 @@
                             <a href="#editorial-actions" class="nav-link" data-toggle="tab">Editorial Actions</a>
                           </li>
         		      {% endif %}
-        		      {% if perms.scipost.can_view_production %}
-            		      <li class="nav-item btn btn-secondary">
-                			<a href="#production" class="nav-link" data-toggle="tab">Production</a>
-            		      </li>
-        		      {% endif %}
                       {% if perms.scipost.can_referee %}
                           <li class="nav-item btn btn-secondary">
                             <a class="nav-link" data-toggle="tab" href="#refereeing">Refereeing {% if refereeing_tab_total_count %}({{refereeing_tab_total_count}}){% endif %}</a>
                           </li>
                       {% endif %}
-                      <li class="nav-item btn btn-secondary">
-                        <a class="nav-link" data-toggle="tab" href="#publications">Publications</a>
-                      </li>
-                      <li class="nav-item btn btn-secondary">
-                        <a class="nav-link" data-toggle="tab" href="#submissions">Submissions</a>
-                      </li>
-                      <li class="nav-item btn btn-secondary">
-                        <a class="nav-link" data-toggle="tab" href="#commentaries">Commentaries</a>
-                      </li>
-                      <li class="nav-item btn btn-secondary">
-                        <a class="nav-link" data-toggle="tab" href="#theses">Theses</a>
-                      </li>
-                      <li class="nav-item btn btn-secondary">
-                          {% with request.user.contributor.comments.regular_comments.awaiting_vetting.count as count %}
-                            <a class="nav-link" data-toggle="tab" href="#comments">Comments{% if count %} ({{count}} unvetted){% endif %}</a>
-                          {% endwith %}
-                      </li>
-                      <li class="nav-item btn btn-secondary">
-                          {% with request.user.contributor.comments.author_replies.awaiting_vetting.count as count %}
-                            <a class="nav-link" data-toggle="tab" href="#author-replies">Author Replies{% if count %} ({{count}} unvetted){% endif %}</a>
-                          {% endwith %}
-                      </li>
+                      {% if contributor %}
+                      {# If user is contributor #}
+                          <li class="nav-item btn btn-secondary">
+                            <a class="nav-link" data-toggle="tab" href="#publications">Publications</a>
+                          </li>
+                          <li class="nav-item btn btn-secondary">
+                            <a class="nav-link" data-toggle="tab" href="#submissions">Submissions</a>
+                          </li>
+                          <li class="nav-item btn btn-secondary">
+                            <a class="nav-link" data-toggle="tab" href="#commentaries">Commentaries</a>
+                          </li>
+                          <li class="nav-item btn btn-secondary">
+                            <a class="nav-link" data-toggle="tab" href="#theses">Theses</a>
+                          </li>
+                          <li class="nav-item btn btn-secondary">
+                              {% with contributor.comments.regular_comments.awaiting_vetting.count as count %}
+                                <a class="nav-link" data-toggle="tab" href="#comments">Comments{% if count %} ({{count}} unvetted){% endif %}</a>
+                              {% endwith %}
+                          </li>
+                          <li class="nav-item btn btn-secondary">
+                              {% with contributor.comments.author_replies.awaiting_vetting.count as count %}
+                                <a class="nav-link" data-toggle="tab" href="#author-replies">Author Replies{% if count %} ({{count}} unvetted){% endif %}</a>
+                              {% endwith %}
+                          </li>
+                      {# END: If user is contributor #}
+                      {% endif %}
                     </ul>
                 </div>
             </div>
@@ -93,24 +92,32 @@
                     <h3>Your personal details:</h3>
                     {% include "scipost/_private_info_as_table.html" with contributor=contributor %}
 
-                    <h3 class="mt-3">Your main discipline:</h3>
-                    <ul><li>{{ contributor.get_discipline_display }}</li></ul>
-
-                    <h3 class="mt-3">Your expertises:</h3>
-                    {% if contributor.expertises %}
-                        {% include "scipost/_expertises_as_ul.html" with contributor=contributor %}
-                    {% else %}
-                        <p>You haven't listed your expertise(s).<br/>
-                        Do so by <a href="{% url 'scipost:update_personal_data' %}">updating your personal data</a>
-                        </p>
+                    {% if contributor %}
+                    {# Scientist fields #}
+                        <h3 class="mt-3">Your main discipline:</h3>
+                        <ul><li>{{ contributor.get_discipline_display }}</li></ul>
+
+                        <h3 class="mt-3">Your expertises:</h3>
+                        {% if contributor.expertises %}
+                            {% include "scipost/_expertises_as_ul.html" with contributor=contributor %}
+                        {% else %}
+                            <p>You haven't listed your expertise(s).<br/>
+                            Do so by <a href="{% url 'scipost:update_personal_data' %}">updating your personal data</a>
+                            </p>
+                        {% endif %}
+                    {# END: Scientist fields #}
                     {% endif %}
                 </div>
                 <div class="col-md-6">
-                  {% if not request.user.contributor.is_currently_available %}
-                      <h3 class="text-warning">You are currently unavailable</h3>
-                      <p>Check your availability underneath if this should not be the case.</p>
-                      <hr>
-                  {% endif %}
+                    {% if contributor %}
+                    {# Scientist fields #}
+                        {% if not contributor.is_currently_available %}
+                          <h3 class="text-warning">You are currently unavailable</h3>
+                          <p>Check your availability underneath if this should not be the case.</p>
+                          <hr>
+                        {% endif %}
+                    {# END: Scientist fields #}
+                    {% endif %}
 
                   {% if 'SciPost Administrators' in user_groups %}
                       <h3>You are a SciPost Administrator.</h3>
@@ -152,49 +159,51 @@
                 </div>
             </div>
 
-            <hr>
-            <div class="row">
-                <div class="col">
-                    <h2 class="highlight">Your Availability</h2>
-                </div>
-            </div>
-            <div class="row justify-content-center">
-                <div class="col-md-4 mr-md-5">
-                    <p>To help with the editorial workflow, you can inform us of any periods during which you are unavailable. We will do our best to respect these.</p>
-                    <h3 class="mb-3">Mark a period as unavailable:</h3>
-                    <form action="{% url 'scipost:mark_unavailable_period' %}" method="post">
-                        {% csrf_token %}
-                	    {{ unavailability_form|bootstrap }}
-                    	<input class="btn btn-secondary" type="submit" value="Submit" />
-                    </form>
+            {% if unavailability_form %}
+                <hr>
+                <div class="row">
+                    <div class="col">
+                        <h2 class="highlight">Your Availability</h2>
+                    </div>
                 </div>
-                <div class="col-md-4 ml-md-5">
-                    {% if unavailabilities %}
-                        <h3>Your unavailability periods in our records</h3>
-                        <p class="text-muted">(YYYY-MM-DD)</p>
-                        <table class="table">
-                            <tr>
-                                <th>Start</th>
-                                <th colspan="2">End</th>
-                            </tr>
-                        {% for unav in unavailabilities %}
-                            <tr>
-                                <td>{{ unav.start }}</td>
-                                <td>{{ unav.end }}</td>
-                                <td>
-                                    <form action="{% url 'scipost:delete_unavailable_period' unav.id %}" method="post">
-                                        {% csrf_token %}
-                                        <input class="btn btn-danger" type="submit" value="Delete" />
-                                    </form>
-                                </td>
-                            </tr>
-                        {% endfor %}
-                        </table>
-                    {% else %}
-                        <p>You don't have any upcoming unavailability periods on record.</p>
-                    {% endif %}
+                <div class="row justify-content-center">
+                    <div class="col-md-4 mr-md-5">
+                        <p>To help with the editorial workflow, you can inform us of any periods during which you are unavailable. We will do our best to respect these.</p>
+                        <h3 class="mb-3">Mark a period as unavailable:</h3>
+                        <form action="{% url 'scipost:mark_unavailable_period' %}" method="post">
+                            {% csrf_token %}
+                    	    {{ unavailability_form|bootstrap }}
+                        	<input class="btn btn-secondary" type="submit" value="Submit" />
+                        </form>
+                    </div>
+                    <div class="col-md-4 ml-md-5">
+                        {% if unavailabilities %}
+                            <h3>Your unavailability periods in our records</h3>
+                            <p class="text-muted">(YYYY-MM-DD)</p>
+                            <table class="table">
+                                <tr>
+                                    <th>Start</th>
+                                    <th colspan="2">End</th>
+                                </tr>
+                            {% for unav in unavailabilities %}
+                                <tr>
+                                    <td>{{ unav.start }}</td>
+                                    <td>{{ unav.end }}</td>
+                                    <td>
+                                        <form action="{% url 'scipost:delete_unavailable_period' unav.id %}" method="post">
+                                            {% csrf_token %}
+                                            <input class="btn btn-danger" type="submit" value="Delete" />
+                                        </form>
+                                    </td>
+                                </tr>
+                            {% endfor %}
+                            </table>
+                        {% else %}
+                            <p>You don't have any upcoming unavailability periods on record.</p>
+                        {% endif %}
+                    </div>
                 </div>
-            </div>
+            {% endif %}
         </div><!-- End tab -->
 
         {% if 'SciPost Administrators' in user_groups or 'Editorial Administrators' in user_groups or 'Editorial College' in user_groups or 'Advisory Board' in user_groups or 'Vetting Editors' in user_groups or 'Ambassadors' in user_groups or 'Junior Ambassadors' in user_groups %}
@@ -251,6 +260,13 @@
                                 {% endif %}
                             </ul>
                         {% endif %}
+
+                        {% if perms.scipost.can_view_timesheets %}
+                            <h3>Finance</h3>
+                            <ul>
+                                <li><a href="{% url 'finances:timesheets' %}">Production Team Timesheets</a></li>
+                            </ul>
+                        {% endif %}
                     </div>
                     {% endif %}
 
@@ -334,346 +350,327 @@
                 </div>
 
                 {% if active_assignments %}
-                <div class="row">
-                    <div class="col-12">
-                        <h3 class="highlight">Submissions for which you are Editor-in-charge</h3>
-                    </div>
-                    <div class="col-12">
-                        <ul class="list-group list-group-flush">
-                            {% for assignment in active_assignments %}
-                                <li class="list-group-item">
-                                    {% include 'submissions/_submission_card_eic_content.html' with submission=assignment.submission %}
-                                </li>
-                            {% endfor %}
-                        </ul>
+                    <div class="row">
+                        <div class="col-12">
+                            <h3 class="highlight">Submissions for which you are Editor-in-charge</h3>
+                        </div>
+                        <div class="col-12">
+                            <ul class="list-group list-group-flush">
+                                {% for assignment in active_assignments %}
+                                    <li class="list-group-item">
+                                        {% include 'submissions/_submission_card_eic_content.html' with submission=assignment.submission %}
+                                    </li>
+                                {% endfor %}
+                            </ul>
+                        </div>
                     </div>
-                </div>
                 {% endif %}
             </div><!-- End tab -->
         {% endif %}
 
-	    {% if perms.scipost.can_view_production %}
-	    <!-- Tab: Production -->
-	    <div class="tab-pane" id="production" role="tabpanel">
-	      <div class="row">
-		<div class="col-12">
-		  <div class="card card-grey">
-		    <div class="card-body">
-		      <h2 class="card-title mb-0">Production Tasks</h2>
-		    </div>
-		  </div>
-		</div>
-	      </div>
-	      <div class="row">
-		<div class="col-md-4">
-		  <h3>Production workflow</h3>
-		  <ul>
-		    <li><a href="{% url 'production:production' %}">Go to the production page</a></li>
-		    <li><a href="{% url 'production:completed' %}">View completed streams</a></li>
-		  </ul>
-		</div>
-	      </div>
-	    </div>
-	    {% endif %}
-
-        <!-- Tab: Publications -->
-        <div class="tab-pane" id="publications" role="tabpanel">
-            <div class="row">
-                <div class="col-12">
-                    <div class="card card-grey">
-                        <div class="card-body">
-                            <h2 class="card-title">Publications</h2>
-                            <ul class="mb-0">
-                                {% if nr_publication_authorships_to_claim > 0 %}
-                                    <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_publication_authorships_to_claim}})</a></li>
-                                {% endif %}
-                            </ul>
-                        </div>
-                    </div>
-                </div>
-            </div>
-
-            {# {% if own_publications %}#}
-            <div class="row" id="mypublicationslist">
-                <div class="col-12">
-                    <h3 class="mb-3">Publications for which you are identified as an author:</h3>
-                </div>
-                <div class="col-12">
-                    <ul class="list-unstyled">
-                        {% for pub in own_publications %}
-                            <li>
-                                <div class="card card-grey card-publication" id="{{pub.doi_label}}">
-                                    {% include 'journals/_publication_card_content.html' with publication=pub current_user=request.user %}
-                                </div>
-                            </li>
-                        {% empty %}
-                            <li>
-                                <em>No Publications found</em>
-                            </li>
-                        {% endfor %}
-                    </ul>
-                </div>
-            </div>
-            {# {% endif %}#}
-        </div><!-- End tab -->
-
-
-            {% if perms.scipost.can_referee %}
-            <!-- Tab: Refereeing -->
-            <div class="tab-pane" id="refereeing" role="tabpanel">
+        {% if contributor %}
+            {# If user is contributor #}
+            <!-- Tab: Publications -->
+            <div class="tab-pane" id="publications" role="tabpanel">
                 <div class="row">
                     <div class="col-12">
                         <div class="card card-grey">
                             <div class="card-body">
-                                <h2 class="card-title">Refereeing Tasks</h2>
+                                <h2 class="card-title">Publications</h2>
                                 <ul class="mb-0">
-                                    <li><a href="{% url 'submissions:accept_or_decline_ref_invitations' %}">Accept/decline refereeing invitations</a> ({{ nr_ref_inv_to_consider }})</li>
+                                    {% if nr_publication_authorships_to_claim > 0 %}
+                                        <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_publication_authorships_to_claim}})</a></li>
+                                    {% endif %}
                                 </ul>
                             </div>
                         </div>
                     </div>
                 </div>
 
-                <div class="row">
+                {# {% if own_publications %}#}
+                <div class="row" id="mypublicationslist">
                     <div class="col-12">
-                        <h3>Pending Refereeing Tasks:</h3>
+                        <h3 class="mb-3">Publications for which you are identified as an author:</h3>
                     </div>
                     <div class="col-12">
-                        <ul class="list-group list-group-flush">
-                        {% for task in pending_ref_tasks %}
-                            <li class="list-group-item">
-                                {% include 'submissions/_refereeing_invitation_card_content.html' with invitation=task %}
-                            </li>
-                        {% empty %}
-                            <li class="list-group-item"><em>You do not have any pending refereeing task</em></li>
-                        {% endfor %}
+                        <ul class="list-unstyled">
+                            {% for pub in own_publications %}
+                                <li>
+                                    <div class="card card-grey card-publication" id="{{pub.doi_label}}">
+                                        {% include 'journals/_publication_card_content.html' with publication=pub current_user=request.user %}
+                                    </div>
+                                </li>
+                            {% empty %}
+                                <li>
+                                    <em>No Publications found</em>
+                                </li>
+                            {% endfor %}
                         </ul>
                     </div>
                 </div>
+                {# {% endif %}#}
+            </div><!-- End tab -->
+
 
-                {% if contributor.reports.in_draft.exists %}
+                {% if perms.scipost.can_referee %}
+                <!-- Tab: Refereeing -->
+                <div class="tab-pane" id="refereeing" role="tabpanel">
                     <div class="row">
                         <div class="col-12">
-                            <h3>Unfinished reports:</h3>
-                        </div>
-                        <div class="col-12">
-                            <ul class="list-group list-group-flush">
-                            {% for report in contributor.reports.in_draft.all %}
-                                <li class="list-group-item">
-                                    <div class="w-100">{% include 'submissions/_submission_card_content.html' with submission=report.submission %}</div>
-                                    <div class="px-2 mb-2"><a class="px-1" href="{% url 'submissions:submit_report' report.submission.arxiv_identifier_w_vn_nr %}">Finish report</a></div>
-                                </li>
-                            {% endfor %}
-                            </ul>
+                            <div class="card card-grey">
+                                <div class="card-body">
+                                    <h2 class="card-title">Refereeing Tasks</h2>
+                                    <ul class="mb-0">
+                                        <li><a href="{% url 'submissions:accept_or_decline_ref_invitations' %}">Accept/decline refereeing invitations</a> ({{ nr_ref_inv_to_consider }})</li>
+                                    </ul>
+                                </div>
+                            </div>
                         </div>
                     </div>
-                {% endif %}
 
-                {% if contributor.reports.non_draft.exists %}
                     <div class="row">
                         <div class="col-12">
-                            <h3>Finished reports:</h3>
+                            <h3>Pending Refereeing Tasks:</h3>
                         </div>
                         <div class="col-12">
                             <ul class="list-group list-group-flush">
-                            {% for report in contributor.reports.non_draft.all %}
+                            {% for task in pending_ref_tasks %}
                                 <li class="list-group-item">
-                                    {% comment %}
-                                        Temporary: There is already a template for a "Report summary" in a parallel (unmerged) branch. Awaiting merge to use that template.
-                                    {% endcomment %}
-                                    <div class="card-body {% block cardblock_class_block %}{% endblock %}">
-                                        <h3>Report on Submission <a href="{{report.submission.get_absolute_url}}">{{report.submission.title}}</a></h3>
-                                        <table>
-                                            <tr>
-                                                <th style='min-width: 100px;'>Received:</th><td>{{ report.date_submitted|date:'Y-n-j' }}<td>
-                                            </tr>
-                                            <tr>
-                                                <th>Status:</th><td {% if report.status == 'vetted' %}class="text-success"{% elif report.status == 'unvetted' %}class="text-danger"{% endif %}>{{report.get_status_display}}</td>
-                                            </tr>
-					    {% if report.doi_label %}
-					    <tr>
-					      <th>DOI:</th><td>{{ report.doi_string }}</td></th>
-{% endif %}
-                                            <tr>
-                                                <th>Anonymous:</th><td>{{report.anonymous|yesno:'Yes,No'}}</td>{% if report.anonymous %}<td>You can <a href="{% url 'journals:sign_existing_report' report_id=report.id %}">click here to sign this Report</a> (leads to confirmation page){% endif %}</td>
-                                            </tr>
-                                        </table>
-                                    </div>
+                                    {% include 'submissions/_refereeing_invitation_card_content.html' with invitation=task %}
                                 </li>
+                            {% empty %}
+                                <li class="list-group-item"><em>You do not have any pending refereeing task</em></li>
                             {% endfor %}
                             </ul>
                         </div>
                     </div>
-                {% endif %}
-            </div><!-- End tab -->
-        {% endif %}
 
-        <!-- Tab: Submissions -->
-        <div class="tab-pane" id="submissions" role="tabpanel">
-            <div class="row">
-                <div class="col-12">
-                    <div class="card card-grey">
-                        <div class="card-body">
-                            <h2 class="card-title">Submissions</h2>
-                            <ul class="mb-0">
-                                {% if nr_submission_authorships_to_claim > 0 %}
-                                    <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_submission_authorships_to_claim}})</a></li>
-                                {% endif %}
-                                <li><a href="{% url 'submissions:submit_manuscript' %}">Submit an arXiv preprint to a SciPost Journal</a></li>
-                            </ul>
+                    {% if contributor.reports.in_draft.exists %}
+                        <div class="row">
+                            <div class="col-12">
+                                <h3>Unfinished reports:</h3>
+                            </div>
+                            <div class="col-12">
+                                <ul class="list-group list-group-flush">
+                                {% for report in contributor.reports.in_draft.all %}
+                                    <li class="list-group-item">
+                                        <div class="w-100">{% include 'submissions/_submission_card_content.html' with submission=report.submission %}</div>
+                                        <div class="px-2 mb-2"><a class="px-1" href="{% url 'submissions:submit_report' report.submission.arxiv_identifier_w_vn_nr %}">Finish report</a></div>
+                                    </li>
+                                {% endfor %}
+                                </ul>
+                            </div>
+                        </div>
+                    {% endif %}
+
+                    {% if contributor.reports.non_draft.exists %}
+                        <div class="row">
+                            <div class="col-12">
+                                <h3>Finished reports:</h3>
+                            </div>
+                            <div class="col-12">
+                                <ul class="list-group list-group-flush">
+                                {% for report in contributor.reports.non_draft.all %}
+                                    <li class="list-group-item">
+                                        {% comment %}
+                                            Temporary: There is already a template for a "Report summary" in a parallel (unmerged) branch. Awaiting merge to use that template.
+                                        {% endcomment %}
+                                        <div class="card-body {% block cardblock_class_block %}{% endblock %}">
+                                            <h3>Report on Submission <a href="{{report.submission.get_absolute_url}}">{{report.submission.title}}</a></h3>
+                                            <table>
+                                                <tr>
+                                                    <th style='min-width: 100px;'>Received:</th><td>{{ report.date_submitted|date:'Y-n-j' }}<td>
+                                                </tr>
+                                                <tr>
+                                                    <th>Status:</th><td {% if report.status == 'vetted' %}class="text-success"{% elif report.status == 'unvetted' %}class="text-danger"{% endif %}>{{report.get_status_display}}</td>
+                                                </tr>
+    					    {% if report.doi_label %}
+    					    <tr>
+    					      <th>DOI:</th><td>{{ report.doi_string }}</td></th>
+    {% endif %}
+                                                <tr>
+                                                    <th>Anonymous:</th><td>{{report.anonymous|yesno:'Yes,No'}}</td>{% if report.anonymous %}<td>You can <a href="{% url 'journals:sign_existing_report' report_id=report.id %}">click here to sign this Report</a> (leads to confirmation page){% endif %}</td>
+                                                </tr>
+                                            </table>
+                                        </div>
+                                    </li>
+                                {% endfor %}
+                                </ul>
+                            </div>
+                        </div>
+                    {% endif %}
+                </div><!-- End tab -->
+            {% endif %}
+
+            <!-- Tab: Submissions -->
+            <div class="tab-pane" id="submissions" role="tabpanel">
+                <div class="row">
+                    <div class="col-12">
+                        <div class="card card-grey">
+                            <div class="card-body">
+                                <h2 class="card-title">Submissions</h2>
+                                <ul class="mb-0">
+                                    {% if nr_submission_authorships_to_claim > 0 %}
+                                        <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_submission_authorships_to_claim}})</a></li>
+                                    {% endif %}
+                                    <li><a href="{% url 'submissions:submit_manuscript' %}">Submit an arXiv preprint to a SciPost Journal</a></li>
+                                </ul>
+                            </div>
                         </div>
                     </div>
                 </div>
-            </div>
 
-            {# {% if own_submissions %}#}
-            <div class="row" id="mysubmissionslist">
-                <div class="col-12">
-                    <h3>Submissions for which you are identified as an author:</h3>
-                </div>
-                <div class="col-12">
-                    <ul class="list-group list-group-flush">
-                        {% for sub in own_submissions %}
-                            <li class="list-group-item">
-                                {% include 'submissions/_submission_card_author_content.html' with submission=sub current_user=request.user %}
-                            </li>
-                        {% empty %}
-                            <li class="list-group-item">
-                                <em>No Submissions found</em>
-                            </li>
-                        {% endfor %}
-                    </ul>
+                {# {% if own_submissions %}#}
+                <div class="row" id="mysubmissionslist">
+                    <div class="col-12">
+                        <h3>Submissions for which you are identified as an author:</h3>
+                    </div>
+                    <div class="col-12">
+                        <ul class="list-group list-group-flush">
+                            {% for sub in own_submissions %}
+                                <li class="list-group-item">
+                                    {% include 'submissions/_submission_card_author_content.html' with submission=sub current_user=request.user %}
+                                </li>
+                            {% empty %}
+                                <li class="list-group-item">
+                                    <em>No Submissions found</em>
+                                </li>
+                            {% endfor %}
+                        </ul>
+                    </div>
                 </div>
-            </div>
-            {# {% endif %}#}
-        </div><!-- End tab -->
+                {# {% endif %}#}
+            </div><!-- End tab -->
 
-        <!-- Tab: Commentaries -->
-        <div class="tab-pane" id="commentaries" role="tabpanel">
-            <div class="row">
-                <div class="col-12">
-                    <div class="card card-grey">
-                        <div class="card-body">
-                            <h2 class="card-title">Commentaries</h2>
-                            <ul class="mb-0">
-                                {% if nr_commentary_authorships_to_claim > 0 %}
-                                    <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_commentary_authorships_to_claim}})</a></li>
-                                {% endif %}
-                                <li><a href="{% url 'commentaries:request_commentary' %}">Request opening a SciPost Commentary Page</a></li>
-                            </ul>
+            <!-- Tab: Commentaries -->
+            <div class="tab-pane" id="commentaries" role="tabpanel">
+                <div class="row">
+                    <div class="col-12">
+                        <div class="card card-grey">
+                            <div class="card-body">
+                                <h2 class="card-title">Commentaries</h2>
+                                <ul class="mb-0">
+                                    {% if nr_commentary_authorships_to_claim > 0 %}
+                                        <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_commentary_authorships_to_claim}})</a></li>
+                                    {% endif %}
+                                    <li><a href="{% url 'commentaries:request_commentary' %}">Request opening a SciPost Commentary Page</a></li>
+                                </ul>
+                            </div>
                         </div>
                     </div>
                 </div>
-            </div>
 
-            <div class="row" id="mycommentarieslist">
-                <div class="col-12">
-                    <h3>Commentaries for which you are identified as an author:</h3>
-                </div>
-                <div class="col-12">
-                    <ul class="list-group list-group-flush">
-                        {% for com in own_commentaries %}
-                            <li class="list-group-item">
-                                {% include 'commentaries/_commentary_card_content.html' with commentary=com %}
-                            </li>
-                        {% empty %}
-                            <li class="list-group-item"><em>No Commentaries found</em></li>
-                        {% endfor %}
-                    </ul>
+                <div class="row" id="mycommentarieslist">
+                    <div class="col-12">
+                        <h3>Commentaries for which you are identified as an author:</h3>
+                    </div>
+                    <div class="col-12">
+                        <ul class="list-group list-group-flush">
+                            {% for com in own_commentaries %}
+                                <li class="list-group-item">
+                                    {% include 'commentaries/_commentary_card_content.html' with commentary=com %}
+                                </li>
+                            {% empty %}
+                                <li class="list-group-item"><em>No Commentaries found</em></li>
+                            {% endfor %}
+                        </ul>
+                    </div>
                 </div>
-            </div>
-        </div><!-- End tab -->
+            </div><!-- End tab -->
 
-        <!-- Tab: Theses -->
-        <div class="tab-pane" id="theses" role="tabpanel">
-            <div class="row">
-                <div class="col-12">
-                    <div class="card card-grey">
-                        <div class="card-body">
-                            <h2 class="card-title">Theses</h2>
-                            <ul class="mb-0">
-                                {% if nr_thesis_authorships_to_claim > 0 %}
-                                    <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_thesis_authorships_to_claim}})</a></li>
-                                {% endif %}
-                                <li><a href="{% url 'theses:request_thesislink' %}">Request a SciPost ThesisLink</a></li>
-                            </ul>
+            <!-- Tab: Theses -->
+            <div class="tab-pane" id="theses" role="tabpanel">
+                <div class="row">
+                    <div class="col-12">
+                        <div class="card card-grey">
+                            <div class="card-body">
+                                <h2 class="card-title">Theses</h2>
+                                <ul class="mb-0">
+                                    {% if nr_thesis_authorships_to_claim > 0 %}
+                                        <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_thesis_authorships_to_claim}})</a></li>
+                                    {% endif %}
+                                    <li><a href="{% url 'theses:request_thesislink' %}">Request a SciPost ThesisLink</a></li>
+                                </ul>
+                            </div>
                         </div>
                     </div>
                 </div>
-            </div>
 
-            <div class="row" id="mytheseslist">
-                <div class="col-12">
-                    <h3>Theses for which you are identified as an author:</h3>
-                </div>
-                <div class="col-12">
-                    <ul class="list-group list-group-flush">
-                        {% for thesis in own_thesislinks %}
-                            <li class="list-group-item">
-                                {% include 'theses/_thesislink_card_content.html' with thesislink=thesis %}
-                            </li>
-                        {% empty %}
-                            <li class="list-group-item"><em>No Theses found</em></li>
-                        {% endfor %}
-                    </ul>
+                <div class="row" id="mytheseslist">
+                    <div class="col-12">
+                        <h3>Theses for which you are identified as an author:</h3>
+                    </div>
+                    <div class="col-12">
+                        <ul class="list-group list-group-flush">
+                            {% for thesis in own_thesislinks %}
+                                <li class="list-group-item">
+                                    {% include 'theses/_thesislink_card_content.html' with thesislink=thesis %}
+                                </li>
+                            {% empty %}
+                                <li class="list-group-item"><em>No Theses found</em></li>
+                            {% endfor %}
+                        </ul>
+                    </div>
                 </div>
-            </div>
 
-        </div><!-- End tab -->
+            </div><!-- End tab -->
 
-        <!-- Tab: Comments -->
-        <div class="tab-pane" id="comments" role="tabpanel">
-            <div class="row">
-                <div class="col-12">
-                    <div class="card card-grey">
-                        <div class="card-body">
-                            <h2 class="card-title mb-0">Your Comments</h2>
+            <!-- Tab: Comments -->
+            <div class="tab-pane" id="comments" role="tabpanel">
+                <div class="row">
+                    <div class="col-12">
+                        <div class="card card-grey">
+                            <div class="card-body">
+                                <h2 class="card-title mb-0">Your Comments</h2>
+                            </div>
                         </div>
                     </div>
                 </div>
-            </div>
 
-            <div class="row" id="mycommentslist">
-                <div class="col-12">
-                    <ul class="list-group list-group-flush">
-                        {% for own_comment in own_comments %}
-                            <li class="list-group-item">
-                                {% include 'comments/_comment_card_extended_for_author.html' with comment=own_comment %}
-                            </li>
-                        {% empty %}
-                            <li class="list-group-item"><em>You have not commented yet.</em></li>
-                        {% endfor %}
-                    </ul>
+                <div class="row" id="mycommentslist">
+                    <div class="col-12">
+                        <ul class="list-group list-group-flush">
+                            {% for own_comment in own_comments %}
+                                <li class="list-group-item">
+                                    {% include 'comments/_comment_card_extended_for_author.html' with comment=own_comment %}
+                                </li>
+                            {% empty %}
+                                <li class="list-group-item"><em>You have not commented yet.</em></li>
+                            {% endfor %}
+                        </ul>
+                    </div>
                 </div>
-            </div>
-        </div><!-- End tab -->
+            </div><!-- End tab -->
 
-        <!-- Tab: Author Replies -->
-        <div class="tab-pane" id="author-replies" role="tabpanel">
-            <div class="row">
-                <div class="col-12">
-                    <div class="card card-grey">
-                        <div class="card-body">
-                            <h2 class="card-title mb-0">Your Author Replies</h2>
+            <!-- Tab: Author Replies -->
+            <div class="tab-pane" id="author-replies" role="tabpanel">
+                <div class="row">
+                    <div class="col-12">
+                        <div class="card card-grey">
+                            <div class="card-body">
+                                <h2 class="card-title mb-0">Your Author Replies</h2>
+                            </div>
                         </div>
                     </div>
                 </div>
-            </div>
 
-            <div class="row" id="myauthorreplieslist">
-                <div class="col-12">
-                    <ul class="list-group list-group-flush">
-                      {% for own_reply in own_authorreplies %}
-                          <li class="list-group-item">
-                              {% include 'comments/_comment_card_extended_for_author.html' with comment=own_reply %}
-                          </li>
-                      {% empty %}
-                          <li class="list-group-item"><em>You do not have Author Replies yet.</em></li>
-                      {% endfor %}
-                    </ul>
+                <div class="row" id="myauthorreplieslist">
+                    <div class="col-12">
+                        <ul class="list-group list-group-flush">
+                          {% for own_reply in own_authorreplies %}
+                              <li class="list-group-item">
+                                  {% include 'comments/_comment_card_extended_for_author.html' with comment=own_reply %}
+                              </li>
+                          {% empty %}
+                              <li class="list-group-item"><em>You do not have Author Replies yet.</em></li>
+                          {% endfor %}
+                        </ul>
+                    </div>
                 </div>
-            </div>
-        </div><!-- End tab -->
+            </div><!-- End tab -->
+
+        {# END: If user is contributor #}
+        {% endif %}
     </div>
 
 {% endif %}
diff --git a/scipost/templatetags/scipost_extras.py b/scipost/templatetags/scipost_extras.py
index 25c81e2b02c48f6bed015b8762147284b36d828e..a378cf31277cdda85e8874504559044eeb7d42a1 100644
--- a/scipost/templatetags/scipost_extras.py
+++ b/scipost/templatetags/scipost_extras.py
@@ -12,7 +12,9 @@ register = template.Library()
 
 @register.filter(name='sort_by')
 def sort_by(queryset, order):
-    return queryset.order_by(order)
+    if queryset:
+        return queryset.order_by(order)
+    return None
 
 
 @register.filter(name='duration')
diff --git a/scipost/urls.py b/scipost/urls.py
index f3af0c4a67bc30f8a0c836d7f4692467359db08a..fe4aaefa27501031192cb6ce51fddc74cbe10a87 100644
--- a/scipost/urls.py
+++ b/scipost/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.conf.urls import url
 from django.views.generic import TemplateView
 
 from . import views
@@ -14,6 +14,7 @@ JOURNAL_REGEX = '(?P<doi_label>%s)' % REGEX_CHOICES
 
 urlpatterns = [
     url(r'^$', views.index, name='index'),
+    url(r'^files/secure/(?P<path>.*)$', views.protected_serve, name='secure_file'),
 
     # General use pages
     url(r'^error$', TemplateView.as_view(template_name='scipost/error.html'), name='error'),
diff --git a/scipost/views.py b/scipost/views.py
index 5c09fe3e60b3b05544df1ba5244b9039ef2286a0..b6c67e3297e4c11354988483ab9225e43acf08be 100644
--- a/scipost/views.py
+++ b/scipost/views.py
@@ -1,5 +1,6 @@
 from django.utils import timezone
 from django.shortcuts import get_object_or_404, render
+from django.conf import settings
 from django.contrib import messages
 from django.contrib.auth import login, logout, update_session_auth_hash
 from django.contrib.auth.decorators import login_required, user_passes_test
@@ -10,16 +11,19 @@ from django.core.mail import EmailMessage, EmailMultiAlternatives
 from django.core.paginator import Paginator
 from django.core.urlresolvers import reverse
 from django.db.models import Prefetch
+from django.http import Http404
 from django.shortcuts import redirect
 from django.template import Context, Template
 from django.views.decorators.http import require_POST
 from django.views.generic.list import ListView
+from django.views.static import serve
 
 from guardian.decorators import permission_required
 from guardian.shortcuts import assign_perm, get_objects_for_user
 from haystack.generic_views import SearchView
 
-from .constants import SCIPOST_SUBJECT_AREAS, subject_areas_raw_dict, SciPost_from_addresses_dict
+from .constants import SCIPOST_SUBJECT_AREAS, subject_areas_raw_dict, SciPost_from_addresses_dict,\
+                       CONTRIBUTOR_NORMAL
 from .decorators import has_contributor
 from .models import Contributor, CitationNotification, UnavailabilityPeriod,\
                     DraftInvitation, RegistrationInvitation,\
@@ -85,6 +89,18 @@ def index(request):
     return render(request, 'scipost/index.html', context)
 
 
+def protected_serve(request, path, show_indexes=False):
+    """
+    Serve files that are saved outside the default MEDIA_ROOT folder for superusers only!
+    This will be usefull eg. in the admin pages.
+    """
+    if not request.user.is_authenticated or not request.user.is_superuser:
+        # Only superusers may get to see secure files without an explicit serve method!
+        raise Http404
+    document_root = settings.MEDIA_ROOT_SECURE
+    return serve(request, path, document_root, show_indexes)
+
+
 ###############
 # Information
 ###############
@@ -691,137 +707,136 @@ def delete_unavailable_period(request, period_id):
 
 
 @login_required
-@user_passes_test(has_contributor)
 def personal_page(request):
     """
     The Personal Page is the main view for accessing user functions.
     """
-    contributor = Contributor.objects.select_related('user').get(user=request.user)
-    user_groups = contributor.user.groups.values_list('name', flat=True)
-
-    # Compile the unavailability periods:
-    now = timezone.now()
-    unavailabilities = UnavailabilityPeriod.objects.filter(
-        contributor=contributor).exclude(end__lt=now).order_by('start')
-    unavailability_form = UnavailabilityPeriodForm()
-
-    # if an editor, count the number of actions required:
-    nr_reg_to_vet = 0
-    nr_reg_awaiting_validation = 0
-    nr_submissions_to_assign = 0
-    nr_recommendations_to_prepare_for_voting = 0
-    if contributor.is_SP_Admin():
-        # count the number of pending registration requests
-        nr_reg_to_vet = Contributor.objects.filter(user__is_active=True, status=0).count()
-        nr_reg_awaiting_validation = (Contributor.objects.awaiting_validation()
-                                    #   .filter(key_expires__gte=now, key_expires__lte=intwodays)
-                                      .count())
-        nr_submissions_to_assign = Submission.objects.filter(status__in=['unassigned']).count()
-        nr_recommendations_to_prepare_for_voting = EICRecommendation.objects.filter(
-            submission__status__in=['voting_in_preparation']).count()
-
-    nr_assignments_to_consider = 0
-    active_assignments = None
-    nr_reports_to_vet = 0
-    if contributor.is_MEC():
-        nr_assignments_to_consider = (EditorialAssignment.objects
-                                      .filter(to=contributor, accepted=None, deprecated=False)
-                                      .count())
-        active_assignments = EditorialAssignment.objects.filter(
-            to=contributor, accepted=True, completed=False)
-        nr_reports_to_vet = (Report.objects.awaiting_vetting()
-                             .filter(submission__editor_in_charge=contributor).count())
-    nr_commentary_page_requests_to_vet = 0
-    nr_comments_to_vet = 0
-    nr_thesislink_requests_to_vet = 0
-    nr_authorship_claims_to_vet = 0
-    if contributor.is_VE():
-        nr_commentary_page_requests_to_vet = (Commentary.objects.awaiting_vetting()
-                                              .exclude(requested_by=contributor).count())
-        nr_comments_to_vet = Comment.objects.awaiting_vetting().count()
-        nr_thesislink_requests_to_vet = ThesisLink.objects.filter(vetted=False).count()
-        nr_authorship_claims_to_vet = AuthorshipClaim.objects.filter(status='0').count()
-
-    # Refereeing
-    nr_ref_inv_to_consider = RefereeInvitation.objects.filter(
-        referee=contributor, accepted=None, cancelled=False).count()
-    pending_ref_tasks = RefereeInvitation.objects.filter(
-        referee=contributor, accepted=True, fulfilled=False)
-    refereeing_tab_total_count = nr_ref_inv_to_consider + len(pending_ref_tasks)
-    refereeing_tab_total_count += Report.objects.in_draft().filter(author=contributor).count()
-
-    # Verify if there exist objects authored by this contributor,
-    # whose authorship hasn't been claimed yet
-    own_publications = (Publication.objects
-                       .filter(authors__in=[contributor])
-                       .order_by('-publication_date'))
-    own_submissions = (Submission.objects
-                       .filter(authors__in=[contributor], is_current=True)
-                       .order_by('-submission_date'))
-    own_commentaries = Commentary.objects.filter(authors=contributor).order_by('-latest_activity')
-    own_thesislinks = ThesisLink.objects.filter(author_as_cont__in=[contributor])
-    nr_publication_authorships_to_claim = (Publication.objects.filter(
-        author_list__contains=contributor.user.last_name)
-                                          .exclude(authors__in=[contributor])
-                                          .exclude(authors_claims__in=[contributor])
-                                          .exclude(authors_false_claims__in=[contributor])
-                                          .count())
-    nr_submission_authorships_to_claim = (Submission.objects.filter(
-        author_list__contains=contributor.user.last_name)
-                                          .exclude(authors__in=[contributor])
-                                          .exclude(authors_claims__in=[contributor])
-                                          .exclude(authors_false_claims__in=[contributor])
-                                          .count())
-    nr_commentary_authorships_to_claim = (Commentary.objects.filter(
-        author_list__contains=contributor.user.last_name)
-                                          .exclude(authors__in=[contributor])
-                                          .exclude(authors_claims__in=[contributor])
-                                          .exclude(authors_false_claims__in=[contributor])
-                                          .count())
-    nr_thesis_authorships_to_claim = (ThesisLink.objects.filter(
-        author__contains=contributor.user.last_name)
-                                      .exclude(author_as_cont__in=[contributor])
-                                      .exclude(author_claims__in=[contributor])
-                                      .exclude(author_false_claims__in=[contributor])
-                                      .count())
-    own_comments = (Comment.objects.filter(author=contributor, is_author_reply=False)
-                    .select_related('author', 'submission')
-                    .order_by('-date_submitted'))
-    own_authorreplies = (Comment.objects.filter(author=contributor, is_author_reply=True)
-                         .order_by('-date_submitted'))
-
-    appellation = contributor.get_title_display() + ' ' + contributor.user.last_name
     context = {
-        'contributor': contributor,
-        'user_groups': user_groups,
-        'appellation': appellation,
-        'unavailabilities': unavailabilities,
-        'unavailability_form': unavailability_form,
-        'nr_reg_to_vet': nr_reg_to_vet,
-        'nr_reg_awaiting_validation': nr_reg_awaiting_validation,
-        'nr_commentary_page_requests_to_vet': nr_commentary_page_requests_to_vet,
-        'nr_comments_to_vet': nr_comments_to_vet,
-        'nr_thesislink_requests_to_vet': nr_thesislink_requests_to_vet,
-        'nr_authorship_claims_to_vet': nr_authorship_claims_to_vet,
-        'nr_reports_to_vet': nr_reports_to_vet,
-        'nr_submissions_to_assign': nr_submissions_to_assign,
-        'nr_recommendations_to_prepare_for_voting': nr_recommendations_to_prepare_for_voting,
-        'nr_assignments_to_consider': nr_assignments_to_consider,
-        'active_assignments': active_assignments,
-        'nr_publication_authorships_to_claim': nr_publication_authorships_to_claim,
-        'nr_submission_authorships_to_claim': nr_submission_authorships_to_claim,
-        'nr_commentary_authorships_to_claim': nr_commentary_authorships_to_claim,
-        'nr_thesis_authorships_to_claim': nr_thesis_authorships_to_claim,
-        'nr_ref_inv_to_consider': nr_ref_inv_to_consider,
-        'pending_ref_tasks': pending_ref_tasks,
-        'refereeing_tab_total_count': refereeing_tab_total_count,
-        'own_publications': own_publications,
-        'own_submissions': own_submissions,
-        'own_commentaries': own_commentaries,
-        'own_thesislinks': own_thesislinks,
-        'own_comments': own_comments,
-        'own_authorreplies': own_authorreplies,
+        'appellation': str(request.user),
+        'needs_validation': False,
     }
+    try:
+        contributor = Contributor.objects.select_related('user').get(user=request.user)
+        context['needs_validation'] = contributor.status != CONTRIBUTOR_NORMAL
+    except Contributor.DoesNotExist:
+        contributor = None
+    context['user_groups'] = request.user.groups.values_list('name', flat=True)
+
+    if contributor:
+        # Compile the unavailability periods:
+        now = timezone.now()
+        unavailabilities = contributor.unavailability_periods.exclude(end__lt=now).order_by('start')
+        unavailability_form = UnavailabilityPeriodForm()
+
+        # if an editor, count the number of actions required:
+        nr_reg_to_vet = 0
+        nr_reg_awaiting_validation = 0
+        nr_submissions_to_assign = 0
+        nr_recommendations_to_prepare_for_voting = 0
+        if contributor.is_SP_Admin():
+            # count the number of pending registration requests
+            nr_reg_to_vet = Contributor.objects.awaiting_vetting().count()
+            nr_reg_awaiting_validation = (Contributor.objects.awaiting_validation()
+                                          .count())
+            nr_submissions_to_assign = Submission.objects.prescreening().count()
+            nr_recommendations_to_prepare_for_voting = EICRecommendation.objects.filter(
+                submission__status='voting_in_preparation').count()
+
+        nr_assignments_to_consider = 0
+        active_assignments = None
+        nr_reports_to_vet = 0
+        if contributor.is_MEC():
+            nr_assignments_to_consider = (contributor.editorial_assignments
+                                          .open().count())
+            active_assignments = contributor.editorial_assignments.ongoing()
+            nr_reports_to_vet = (Report.objects.awaiting_vetting()
+                                 .filter(submission__editor_in_charge=contributor).count())
+
+        nr_commentary_page_requests_to_vet = 0
+        nr_comments_to_vet = 0
+        nr_thesislink_requests_to_vet = 0
+        nr_authorship_claims_to_vet = 0
+        if contributor.is_VE():
+            nr_commentary_page_requests_to_vet = (Commentary.objects.awaiting_vetting()
+                                                  .exclude(requested_by=contributor).count())
+            nr_comments_to_vet = Comment.objects.awaiting_vetting().count()
+            nr_thesislink_requests_to_vet = ThesisLink.objects.awaiting_vetting().count()
+            nr_authorship_claims_to_vet = AuthorshipClaim.objects.awaiting_vetting().count()
+
+        # Refereeing
+        nr_ref_inv_to_consider = contributor.referee_invitations.open().count()
+        pending_ref_tasks = contributor.referee_invitations.in_process()
+        refereeing_tab_total_count = nr_ref_inv_to_consider + len(pending_ref_tasks)
+        refereeing_tab_total_count += contributor.reports.in_draft().count()
+
+        # Verify if there exist objects authored by this contributor,
+        # whose authorship hasn't been claimed yet
+        own_publications = contributor.publications.order_by('-publication_date')
+        own_submissions = contributor.submissions.filter(is_current=True).order_by('-submission_date')
+        own_commentaries = contributor.commentaries.order_by('-latest_activity')
+        own_thesislinks = contributor.theses.all()
+        nr_publication_authorships_to_claim = (Publication.objects.filter(
+            author_list__contains=contributor.user.last_name)
+                                              .exclude(authors=contributor)
+                                              .exclude(authors_claims=contributor)
+                                              .exclude(authors_false_claims=contributor)
+                                              .count())
+        nr_submission_authorships_to_claim = (Submission.objects.filter(
+            author_list__contains=contributor.user.last_name)
+                                              .exclude(authors=contributor)
+                                              .exclude(authors_claims=contributor)
+                                              .exclude(authors_false_claims=contributor)
+                                              .count())
+        nr_commentary_authorships_to_claim = (Commentary.objects.filter(
+            author_list__contains=contributor.user.last_name)
+                                              .exclude(authors=contributor)
+                                              .exclude(authors_claims=contributor)
+                                              .exclude(authors_false_claims=contributor)
+                                              .count())
+        nr_thesis_authorships_to_claim = (ThesisLink.objects.filter(
+            author__contains=contributor.user.last_name)
+                                          .exclude(author_as_cont=contributor)
+                                          .exclude(author_claims=contributor)
+                                          .exclude(author_false_claims=contributor)
+                                          .count())
+        own_comments = (contributor.comments.regular_comments()
+                        .select_related('author', 'submission')
+                        .order_by('-date_submitted'))
+        own_authorreplies = (contributor.comments.author_replies()
+                             .order_by('-date_submitted'))
+
+        appellation = contributor.get_title_display() + ' ' + contributor.user.last_name
+
+        context.update({
+            'contributor': contributor,
+            'appellation': appellation,
+            'unavailabilities': unavailabilities,
+            'unavailability_form': unavailability_form,
+            'nr_reg_to_vet': nr_reg_to_vet,
+            'nr_reg_awaiting_validation': nr_reg_awaiting_validation,
+            'nr_commentary_page_requests_to_vet': nr_commentary_page_requests_to_vet,
+            'nr_comments_to_vet': nr_comments_to_vet,
+            'nr_thesislink_requests_to_vet': nr_thesislink_requests_to_vet,
+            'nr_authorship_claims_to_vet': nr_authorship_claims_to_vet,
+            'nr_reports_to_vet': nr_reports_to_vet,
+            'nr_submissions_to_assign': nr_submissions_to_assign,
+            'nr_recommendations_to_prepare_for_voting': nr_recommendations_to_prepare_for_voting,
+            'nr_assignments_to_consider': nr_assignments_to_consider,
+            'active_assignments': active_assignments,
+            'nr_publication_authorships_to_claim': nr_publication_authorships_to_claim,
+            'nr_submission_authorships_to_claim': nr_submission_authorships_to_claim,
+            'nr_commentary_authorships_to_claim': nr_commentary_authorships_to_claim,
+            'nr_thesis_authorships_to_claim': nr_thesis_authorships_to_claim,
+            'nr_ref_inv_to_consider': nr_ref_inv_to_consider,
+            'pending_ref_tasks': pending_ref_tasks,
+            'refereeing_tab_total_count': refereeing_tab_total_count,
+            'own_publications': own_publications,
+            'own_submissions': own_submissions,
+            'own_commentaries': own_commentaries,
+            'own_thesislinks': own_thesislinks,
+            'own_comments': own_comments,
+            'own_authorreplies': own_authorreplies,
+        })
 
     # Only add variables if user has right permission
     if request.user.has_perm('scipost.can_manage_reports'):
diff --git a/submissions/__init__.py b/submissions/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1c2ca927d5cf740e7bfc6703a73f1e0f550ea623 100644
--- a/submissions/__init__.py
+++ b/submissions/__init__.py
@@ -0,0 +1 @@
+default_app_config = 'submissions.apps.SubmissionsConfig'
diff --git a/submissions/apps.py b/submissions/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..51d7411cf0f3b4c3d4c41624e4b11733d3bded4f
--- /dev/null
+++ b/submissions/apps.py
@@ -0,0 +1,19 @@
+from django.apps import AppConfig
+from django.db.models.signals import post_save
+
+
+class SubmissionsConfig(AppConfig):
+    name = 'submissions'
+
+    def ready(self):
+        super().ready()
+
+        from . import models, signals
+        post_save.connect(signals.notify_new_manuscript_submitted,
+                          sender=models.Submission)
+        post_save.connect(signals.notify_new_editorial_recommendation,
+                          sender=models.EICRecommendation)
+        post_save.connect(signals.notify_new_editorial_assignment,
+                          sender=models.EditorialAssignment)
+        post_save.connect(signals.notify_new_referee_invitation,
+                          sender=models.RefereeInvitation)
diff --git a/submissions/forms.py b/submissions/forms.py
index fe47475e57d4c1f80e52bd8bb1c246dddab27ba0..1fd5527db82fa9c742d3dc13888280e6852e2e85 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -12,7 +12,7 @@ from .constants import ASSIGNMENT_BOOL, ASSIGNMENT_REFUSAL_REASONS, STATUS_RESUB
                        REPORT_ACTION_CHOICES, REPORT_REFUSAL_CHOICES, STATUS_REVISION_REQUESTED,\
                        STATUS_REJECTED, STATUS_REJECTED_VISIBLE, STATUS_RESUBMISSION_INCOMING,\
                        STATUS_DRAFT, STATUS_UNVETTED, REPORT_ACTION_ACCEPT, REPORT_ACTION_REFUSE,\
-                       STATUS_VETTED, EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS
+                       STATUS_VETTED, EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS, SUBMISSION_STATUS
 from . import exceptions, helpers
 from .models import Submission, RefereeInvitation, Report, EICRecommendation, EditorialAssignment,\
                     iThenticateReport
@@ -42,6 +42,22 @@ class SubmissionSearchForm(forms.Form):
         )
 
 
+class SubmissionPoolFilterForm(forms.Form):
+    status = forms.ChoiceField(choices=((None, 'All statuses'),) + SUBMISSION_STATUS,
+                               required=False)
+    editor_in_charge = forms.BooleanField(label='Show only Submissions for which I am editor in charge.', required=False)
+
+    def search(self, queryset, current_contributor=None):
+        if self.cleaned_data.get('status'):
+            # Do extra check on non-required field to never show errors on template
+            queryset = queryset.filter(status=self.cleaned_data['status'])
+
+        if self.cleaned_data.get('editor_in_charge') and current_contributor:
+            queryset = queryset.filter(editor_in_charge=current_contributor)
+
+        return queryset
+
+
 ###############################
 # Submission and resubmission #
 ###############################
@@ -55,6 +71,7 @@ class SubmissionChecks:
     last_submission = None
 
     def __init__(self, *args, **kwargs):
+        self.requested_by = kwargs.pop('requested_by', None)
         super().__init__(*args, **kwargs)
         # Prefill `is_resubmission` property if data is coming from initial data
         if kwargs.get('initial', None):
@@ -105,6 +122,11 @@ class SubmissionChecks:
             self.last_submission = submission
             if submission.status == STATUS_REVISION_REQUESTED:
                 self.is_resubmission = True
+                if self.requested_by.contributor not in submission.authors.all():
+                    error_message = ('There exists a preprint with this arXiv identifier '
+                                     'but an earlier version number. Resubmission is only possible'
+                                     ' if you are a registered author of this manuscript.')
+                    raise forms.ValidationError(error_message)
             elif submission.status in [STATUS_REJECTED, STATUS_REJECTED_VISIBLE]:
                 error_message = ('This arXiv preprint has previously undergone refereeing '
                                  'and has been rejected. Resubmission is only possible '
@@ -222,7 +244,6 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
         }
 
     def __init__(self, *args, **kwargs):
-        self.requested_by = kwargs.pop('requested_by', None)
         super().__init__(*args, **kwargs)
 
         if not self.submission_is_resubmission():
diff --git a/submissions/managers.py b/submissions/managers.py
index ca6bf98c7215811cffda6278abe18d7aa54fb85b..e3e15f6c51d24452110bbf3add0da166f5118642 100644
--- a/submissions/managers.py
+++ b/submissions/managers.py
@@ -199,6 +199,9 @@ class EditorialAssignmentQuerySet(models.QuerySet):
     def ongoing(self):
         return self.filter(completed=False).accepted()
 
+    def open(self):
+        return self.filter(accepted=None, deprecated=False)
+
 
 class EICRecommendationManager(models.Manager):
     def get_for_user_in_pool(self, user):
@@ -260,3 +263,9 @@ class RefereeInvitationQuerySet(models.QuerySet):
 
     def declined(self):
         return self.filter(accepted=False)
+
+    def open(self):
+        return self.pending().filter(cancelled=False)
+
+    def in_process(self):
+        return self.accepted().filter(fulfilled=False)
diff --git a/submissions/migrations/0061_auto_20170727_1012.py b/submissions/migrations/0061_auto_20170727_1012.py
index af6a59d02f96680652df95d98b9354de9c0fd5fd..68ee18e4cbec33f3ad1ac06f40af4c36c704bbe9 100644
--- a/submissions/migrations/0061_auto_20170727_1012.py
+++ b/submissions/migrations/0061_auto_20170727_1012.py
@@ -6,8 +6,6 @@ from django.db import migrations
 
 from guardian.shortcuts import assign_perm
 
-from ..models import Report
-
 
 def do_nothing(apps, schema_editor):
     return
@@ -18,7 +16,7 @@ def update_eic_permissions(apps, schema_editor):
     Grant EIC of submission related to unvetted Reports
     permission to vet his submission's Report.
     """
-    # Report = apps.get_model('submissions', 'Report')  -- This doesn't work due to shitty imports
+    Report = apps.get_model('submissions', 'Report')
     count = 0
     for rep in Report.objects.filter(status='unvetted'):
         eic_user = rep.submission.editor_in_charge
diff --git a/submissions/migrations/0070_auto_20170925_2124.py b/submissions/migrations/0070_auto_20170925_2124.py
new file mode 100644
index 0000000000000000000000000000000000000000..05381bc93ffe513e901c2074ad32db6938b26b58
--- /dev/null
+++ b/submissions/migrations/0070_auto_20170925_2124.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-25 19:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0069_report_doideposit_needs_updating'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='submission',
+            name='author_comments',
+            field=models.TextField(blank=True, default=''),
+            preserve_default=False,
+        ),
+    ]
diff --git a/submissions/migrations/0071_auto_20170928_2022.py b/submissions/migrations/0071_auto_20170928_2022.py
new file mode 100644
index 0000000000000000000000000000000000000000..9cd9b9535cf0885adcbb6ada625ad17a5e19be0b
--- /dev/null
+++ b/submissions/migrations/0071_auto_20170928_2022.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-28 18:22
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0070_auto_20170925_2124'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='refereeinvitation',
+            name='referee',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='referee_invitations', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='submission',
+            name='submitted_by',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='submitted_submissions', to='scipost.Contributor'),
+        ),
+    ]
diff --git a/submissions/migrations/0072_auto_20170928_2022.py b/submissions/migrations/0072_auto_20170928_2022.py
new file mode 100644
index 0000000000000000000000000000000000000000..e3b3b36fe8a4731e2fe187e8455c65a1c6fe799c
--- /dev/null
+++ b/submissions/migrations/0072_auto_20170928_2022.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-28 18:22
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0071_auto_20170928_2022'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='submission',
+            name='list_of_changes',
+            field=models.TextField(blank=True, default=''),
+            preserve_default=False,
+        ),
+    ]
diff --git a/submissions/migrations/0073_auto_20170928_2023.py b/submissions/migrations/0073_auto_20170928_2023.py
new file mode 100644
index 0000000000000000000000000000000000000000..bae204d2343331a0bc0b0cd8358dc6ed97f98064
--- /dev/null
+++ b/submissions/migrations/0073_auto_20170928_2023.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-28 18:23
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0072_auto_20170928_2022'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='submission',
+            name='authors',
+            field=models.ManyToManyField(blank=True, related_name='submissions', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='submission',
+            name='authors_claims',
+            field=models.ManyToManyField(blank=True, related_name='claimed_submissions', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='submission',
+            name='authors_false_claims',
+            field=models.ManyToManyField(blank=True, related_name='false_claimed_submissions', to='scipost.Contributor'),
+        ),
+    ]
diff --git a/submissions/migrations/0074_auto_20170928_2024.py b/submissions/migrations/0074_auto_20170928_2024.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c958fd639af3c8254b039c7a60b50a6da95e2c1
--- /dev/null
+++ b/submissions/migrations/0074_auto_20170928_2024.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-28 18:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0073_auto_20170928_2023'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='submission',
+            name='referees_flagged',
+            field=models.TextField(blank=True, default=''),
+            preserve_default=False,
+        ),
+    ]
diff --git a/submissions/migrations/0075_auto_20170928_2024.py b/submissions/migrations/0075_auto_20170928_2024.py
new file mode 100644
index 0000000000000000000000000000000000000000..235763bdb328990da21bad47c2ae879ce9a44288
--- /dev/null
+++ b/submissions/migrations/0075_auto_20170928_2024.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-28 18:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0074_auto_20170928_2024'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='submission',
+            name='referees_suggested',
+            field=models.TextField(blank=True, default=''),
+            preserve_default=False,
+        ),
+    ]
diff --git a/submissions/migrations/0076_auto_20170928_2024.py b/submissions/migrations/0076_auto_20170928_2024.py
new file mode 100644
index 0000000000000000000000000000000000000000..4ea15d274d0a9188c99c4668a754956d9abaf65b
--- /dev/null
+++ b/submissions/migrations/0076_auto_20170928_2024.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-28 18:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0075_auto_20170928_2024'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='submission',
+            name='remarks_for_editors',
+            field=models.TextField(blank=True, default=''),
+            preserve_default=False,
+        ),
+    ]
diff --git a/submissions/models.py b/submissions/models.py
index 65896271ea5b02c93bb43f65b0508f129c934139..401e6caef049192a906ea7e12a4d7cf2d41c4fa7 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -35,7 +35,7 @@ from journals.models import Publication
 ###############
 class Submission(models.Model):
     # Main submission fields
-    author_comments = models.TextField(blank=True, null=True)
+    author_comments = models.TextField(blank=True)
     author_list = models.CharField(max_length=1000, verbose_name="author list")
     discipline = models.CharField(max_length=20, choices=SCIPOST_DISCIPLINES, default='physics')
     domain = models.CharField(max_length=3, choices=SCIPOST_JOURNALS_DOMAINS)
@@ -43,12 +43,12 @@ class Submission(models.Model):
                                          null=True, on_delete=models.CASCADE)
     is_current = models.BooleanField(default=True)
     is_resubmission = models.BooleanField(default=False)
-    list_of_changes = models.TextField(blank=True, null=True)
+    list_of_changes = models.TextField(blank=True)
     open_for_commenting = models.BooleanField(default=False)
     open_for_reporting = models.BooleanField(default=False)
-    referees_flagged = models.TextField(blank=True, null=True)
-    referees_suggested = models.TextField(blank=True, null=True)
-    remarks_for_editors = models.TextField(blank=True, null=True)
+    referees_flagged = models.TextField(blank=True)
+    referees_suggested = models.TextField(blank=True)
+    remarks_for_editors = models.TextField(blank=True)
     reporting_deadline = models.DateTimeField(default=timezone.now)
     secondary_areas = ChoiceArrayField(
         models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS),
@@ -62,7 +62,8 @@ class Submission(models.Model):
                                     verbose_name='Primary subject area', default='Phys:QP')
     submission_type = models.CharField(max_length=10, choices=SUBMISSION_TYPE,
                                        blank=True, null=True, default=None)
-    submitted_by = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE)
+    submitted_by = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE,
+                                     related_name='submitted_submissions')
 
     # Replace this by foreignkey?
     submitted_to_journal = models.CharField(max_length=30, choices=SCIPOST_JOURNALS_SUBMIT,
@@ -70,11 +71,11 @@ class Submission(models.Model):
     title = models.CharField(max_length=300)
 
     # Authors which have been mapped to contributors:
-    authors = models.ManyToManyField('scipost.Contributor', blank=True, related_name='authors_sub')
+    authors = models.ManyToManyField('scipost.Contributor', blank=True, related_name='submissions')
     authors_claims = models.ManyToManyField('scipost.Contributor', blank=True,
-                                            related_name='authors_sub_claims')
+                                            related_name='claimed_submissions')
     authors_false_claims = models.ManyToManyField('scipost.Contributor', blank=True,
-                                                  related_name='authors_sub_false_claims')
+                                                  related_name='false_claimed_submissions')
     abstract = models.TextField()
 
     # Comments can be added to a Submission
@@ -275,12 +276,15 @@ class EditorialAssignment(SubmissionRelatedObjectMixin, models.Model):
                 self.submission.title[:30] + ' by ' + self.submission.author_list[:30] +
                 ', requested on ' + self.date_created.strftime('%Y-%m-%d'))
 
+    def get_absolute_url(self):
+        return reverse('submissions:assignment_request', args=(self.id,))
+
 
 class RefereeInvitation(SubmissionRelatedObjectMixin, models.Model):
     submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE,
                                    related_name='referee_invitations')
-    referee = models.ForeignKey('scipost.Contributor', related_name='referee', blank=True,
-                                null=True, on_delete=models.CASCADE)  # Why is this blank/null=True
+    referee = models.ForeignKey('scipost.Contributor', related_name='referee_invitations',
+                                blank=True, null=True, on_delete=models.CASCADE)
     title = models.CharField(max_length=4, choices=TITLE_CHOICES)
     first_name = models.CharField(max_length=30, default='')
     last_name = models.CharField(max_length=30, default='')
@@ -353,7 +357,8 @@ class Report(SubmissionRelatedObjectMixin, models.Model):
     # `flagged' if author of report has been flagged by submission authors (surname check only)
     flagged = models.BooleanField(default=False)
     date_submitted = models.DateTimeField('date submitted')
-    author = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE)
+    author = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE,
+                               related_name='reports')
     qualification = models.PositiveSmallIntegerField(
         choices=REFEREE_QUALIFICATION,
         verbose_name="Qualification to referee this: I am")
@@ -502,9 +507,11 @@ class EICRecommendation(SubmissionRelatedObjectMixin, models.Model):
     # Editorial Fellows who have assessed this recommendation:
     eligible_to_vote = models.ManyToManyField('scipost.Contributor', blank=True,
                                               related_name='eligible_to_vote')
-    voted_for = models.ManyToManyField(Contributor, blank=True, related_name='voted_for')
-    voted_against = models.ManyToManyField(Contributor, blank=True, related_name='voted_against')
-    voted_abstain = models.ManyToManyField(Contributor, blank=True, related_name='voted_abstain')
+    voted_for = models.ManyToManyField('scipost.Contributor', blank=True, related_name='voted_for')
+    voted_against = models.ManyToManyField('scipost.Contributor', blank=True,
+                                           related_name='voted_against')
+    voted_abstain = models.ManyToManyField('scipost.Contributor', blank=True,
+                                           related_name='voted_abstain')
     voting_deadline = models.DateTimeField('date submitted', default=timezone.now)
 
     objects = EICRecommendationManager()
@@ -513,6 +520,10 @@ class EICRecommendation(SubmissionRelatedObjectMixin, models.Model):
         return (self.submission.title[:20] + ' by ' + self.submission.author_list[:30] +
                 ', ' + self.get_recommendation_display())
 
+    def get_absolute_url(self):
+        # TODO: Fix this weird redirect, but it's neccesary for the notifications to have one.
+        return self.submission.get_absolute_url()
+
     @property
     def nr_for(self):
         return self.voted_for.count()
diff --git a/submissions/signals.py b/submissions/signals.py
new file mode 100644
index 0000000000000000000000000000000000000000..664ff585d5255a68d32b3ef6c949d79ab58edda3
--- /dev/null
+++ b/submissions/signals.py
@@ -0,0 +1,51 @@
+from django.contrib.auth.models import User, Group
+
+from notifications.signals import notify
+
+
+def notify_new_manuscript_submitted(sender, instance, created, **kwargs):
+    """
+    Notify the Editorial Administration about a new Submission submitted.
+    """
+    if created:
+        administrators = User.objects.filter(groups__name='Editorial Administrators')
+        for user in administrators:
+            notify.send(sender=sender, recipient=user, actor=instance.submitted_by,
+                        verb=' submitted a new manuscript.', target=instance)
+
+
+def notify_new_editorial_recommendation(sender, instance, created, **kwargs):
+    """
+    Notify the Editorial Recommendation about a new Submission submitted.
+    """
+    if created:
+        administrators = User.objects.filter(groups__name='Editorial Administrators')
+        editor_in_charge = instance.submission.editor_in_charge
+        for user in administrators:
+            notify.send(sender=sender, recipient=user, actor=editor_in_charge,
+                        verb=' formulated a new Editorial Recommendation.', target=instance)
+
+
+def notify_new_editorial_assignment(sender, instance, created, **kwargs):
+    """
+    Notify a College Fellow about a new EIC invitation.
+    """
+    if created:
+        administration = Group.objects.get(name='Editorial Administrators')
+        if instance.accepted:
+            # A new assignment is auto-accepted if user assigned himself or on resubmission.
+            text = ' assigned you Editor-in-charge.'
+        else:
+            text = ' invited you to become Editor-in-charge.'
+        notify.send(sender=sender, recipient=instance.to.user, actor=administration,
+                    verb=text, target=instance)
+
+
+def notify_new_referee_invitation(sender, instance, created, **kwargs):
+    """
+    Notify a Referee about a new refereeing invitation.
+    """
+    if created:
+        notify.send(sender=sender, recipient=instance.referee.user,
+                    actor=instance.submission.editor_in_charge,
+                    verb=' would like to invite you to referee a Submission.', target=instance)
diff --git a/submissions/templates/partials/submissions/admin/editorial_admin_summary.html b/submissions/templates/partials/submissions/admin/editorial_admin_summary.html
deleted file mode 100644
index 65fdf4c9c44de594f708607afe66a71fbed717ca..0000000000000000000000000000000000000000
--- a/submissions/templates/partials/submissions/admin/editorial_admin_summary.html
+++ /dev/null
@@ -1,144 +0,0 @@
-{% load guardian_tags %}
-{% load scipost_extras %}
-{% load submissions_extras %}
-
-
-<h5 class="pb-0">{{submission.get_subject_area_display}}</h5>
-<h3 class="card-title">
-    <a href="{{submission.get_absolute_url}}">{{submission.title}}</a>
-</h3>
-
-<p class="card-text mb-3">by {{submission.author_list}}</p>
-<h3>Info</h3>
-<table class="text-muted w-100 mb-1">
-    <tr>
-        <td style="min-width: 40%;">Version</td>
-        <td>{{submission.arxiv_vn_nr}} ({% if submission.is_current %}current version{% else %}deprecated version {{submission.arxiv_vn_nr}}{% endif %})</td>
-    </tr>
-    <tr>
-        <td>Submitted</td>
-        <td>{{submission.submission_date}} to {{submission.get_submitted_to_journal_display}}</td>
-    </tr>
-
-    {% if submission.acceptance_date %}
-        <tr>
-            <td>Accepted</td>
-            <td>{{submission.acceptance_date}}</td>
-        </tr>
-    {% endif %}
-
-    <tr>
-        <td>Latest activity</td>
-        <td>{{submission.latest_activity}}</td>
-    </tr>
-    <tr>
-        <td>Editor-in-charge</td>
-        <td>
-            {% if submission.editor_in_charge %}
-                {{ submission.editor_in_charge }}
-            {% elif perms.scipost.can_assign_submissions %}
-                <a href="{% url 'submissions:assign_submission' submission.arxiv_identifier_w_vn_nr %}">Send a new assignment request</a>
-            {% else %}
-                -
-            {% endif %}
-        </td>
-    </tr>
-    <tr>
-        <td>Status</td>
-        <td>{{ submission.get_status_display }}</td>
-    </tr>
-    <tr>
-        <td>Refereeing cycle</td>
-        <td>{{ submission.get_refereeing_cycle_display }}</td>
-    </tr>
-
-    {% include 'partials/submissions/refereeing_status_as_tr.html' with submission=submission %}
-
-    <tr>
-        <td>Comments</td>
-        <td>
-            {{submission.comments.vetted.count}}
-            <span class="circle-clickable" data-toggle="tooltip" data-placement='bottom' data-html="true" title="{{submission.comments.regular_comments.vetted.count}} comments<br>{{submission.comments.author_replies.vetted.count}} author replies<hr>{{submission.comments.awaiting_vetting.count}} awaiting vetting">?</span>
-        </td>
-    </tr>
-
-    <tr>
-        <td>Reporting deadline</td>
-        <td>
-            {% if submission.reporting_deadline > now %}
-                in {{submission.reporting_deadline|timeuntil}}
-            {% else %}
-                {{submission.reporting_deadline|timesince}} ago
-            {% endif %}
-        </td>
-    </tr>
-
-    <tr>
-        <td>Plagiarism score</td>
-        <td>
-            {% if submission.plagiarism_report %}
-                {{ submission.plagiarism_report.score }}%
-            {% else %}
-                <a href="{% url 'submissions:plagiarism' submission.arxiv_identifier_w_vn_nr %}">Run plagiarism check</a>
-            {% endif %}
-        </td>
-    </tr>
-
-</table>
-<a href="{% url 'submissions:editorial_page' submission.arxiv_identifier_w_vn_nr %}" class="d-inline-block mb-3">Go to Editorial Page</a>
-
-<h3>Actions</h3>
-
-<ul class="pl-4 mb-3">
-    {# EIC Assignments #}
-    {% if perms.scipost.can_assign_submissions %}
-        {% if not submission.editor_in_charge %}
-            <li>EIC Assignment requests:</li>
-            <ul>
-                {% for assignment in submission.editorial_assignments.all %}
-                    {% include 'submissions/_assignment_info.html' with assignment=assignment %}
-                {% empty %}
-                    <li>None found. <a href="{% url 'submissions:assign_submission' submission.arxiv_identifier_w_vn_nr %}">Send a first assignment request</a></li>
-                {% endfor %}
-            </ul>
-            <li><a href="{% url 'submissions:assign_submission' submission.arxiv_identifier_w_vn_nr %}">Send a new assignment request</a></li>
-            <li><a href="{% url 'submissions:assignment_failed' submission.arxiv_identifier_w_vn_nr %}">Close pre-screening: failure to find EIC</a></li>
-        {% endif %}
-    {% endif %}
-
-    {# Plagiarism #}
-    <li><a href="{% url 'submissions:plagiarism' submission.arxiv_identifier_w_vn_nr %}">Manage plagiarism report</a></li>
-
-    {# Compile pdfs #}
-    {% if submission.reports.accepted.exists %}
-        <li><a href="{% url 'submissions:reports_accepted_list' %}?submission={{submission.arxiv_identifier_w_vn_nr}}">Compile accepted reports</a></li>
-    {% endif %}
-
-    {# Communication #}
-    {% if submission.editor_in_charge %}
-        <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='StoE' %}">Send a communication to the Editor-in-charge</a></li>
-    {% endif %}
-
-    {# EIC Recommendations #}
-    {% if submission.eicrecommendations.exists %}
-        <li>See Editorial Recommendations:</li>
-        <ul>
-            {% for rec in submission.eicrecommendations.all %}
-                <li><a href="{% url 'submissions:eic_recommendation_detail' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr rec_id=rec.id %}">{{rec.get_recommendation_display}}</a></li>
-            {% endfor %}
-        </ul>
-    {% endif %}
-
-    {# Accepted submission actions #}
-    {% if submission.status == 'accepted' %}
-        <li><a href="{% url 'submissions:treated_submission_pdf_compile' submission.arxiv_identifier_w_vn_nr %}">Update the Refereeing Package pdf</a></li>
-        <li>After proofs have been accepted, you can <a href="{% url 'journals:initiate_publication' %}">initiate the publication process</a> (leads to the validation page)</li>
-    {% endif %}
-</ul>
-
-
-<h3>Events</h3>
-<a href="javascript:;" data-toggle="toggle" data-target="#eventslist">Show/hide events</a>
-<div id="eventslist">
-    {% include 'submissions/submission_event_list.html' with events=submission.events.for_eic %}
-</div>
diff --git a/submissions/templates/partials/submissions/admin/recommendation_tooltip.html b/submissions/templates/partials/submissions/admin/recommendation_tooltip.html
new file mode 100644
index 0000000000000000000000000000000000000000..79e47405ebb8b2c351e301b36784232fccf40907
--- /dev/null
+++ b/submissions/templates/partials/submissions/admin/recommendation_tooltip.html
@@ -0,0 +1,9 @@
+<i class="fa fa-info-circle {{ classes }}" data-toggle="tooltip" data-html="true" title="
+    Eligible to vote ({{ recommendation.eligible_to_vote.count }})
+    <hr>
+    Agreed ({{ recommendation.voted_for.count }})
+    <br>
+    Disagreed ({{ recommendation.voted_against.count }})
+    <br>
+    Abstained ({{ recommendation.voted_abstain.count }})
+"></i>
diff --git a/submissions/templates/partials/submissions/admin/submission_details.html b/submissions/templates/partials/submissions/admin/submission_details.html
new file mode 100644
index 0000000000000000000000000000000000000000..39969bdc536c7e7dc0974c1fdb5ceaf89b2bd093
--- /dev/null
+++ b/submissions/templates/partials/submissions/admin/submission_details.html
@@ -0,0 +1,147 @@
+{% load guardian_tags %}
+{% load scipost_extras %}
+{% load submissions_extras %}
+
+
+<div class="card border-secondary mt-2 submission-detail">
+    <div class="card-body">
+        <h5 class="pb-0">{{submission.get_subject_area_display}}</h5>
+        <h3 class="card-title">
+            <a href="{{submission.get_absolute_url}}">{{submission.title}}</a>
+        </h3>
+
+        <p class="card-text mb-3">by {{submission.author_list}}</p>
+        <h3>Info</h3>
+        <table class="text-muted w-100 mb-1">
+            <tr>
+                <td style="min-width: 40%;">Version</td>
+                <td>{{submission.arxiv_vn_nr}} ({% if submission.is_current %}current version{% else %}deprecated version {{submission.arxiv_vn_nr}}{% endif %})</td>
+            </tr>
+            <tr>
+                <td>Submitted</td>
+                <td>{{submission.submission_date}} to {{submission.get_submitted_to_journal_display}}</td>
+            </tr>
+
+            {% if submission.acceptance_date %}
+                <tr>
+                    <td>Accepted</td>
+                    <td>{{submission.acceptance_date}}</td>
+                </tr>
+            {% endif %}
+
+            <tr>
+                <td>Latest activity</td>
+                <td>{{submission.latest_activity}}</td>
+            </tr>
+            <tr>
+                <td>Editor-in-charge</td>
+                <td>
+                    {% if submission.editor_in_charge %}
+                        {{ submission.editor_in_charge }}
+                    {% elif perms.scipost.can_assign_submissions %}
+                        <a href="{% url 'submissions:assign_submission' submission.arxiv_identifier_w_vn_nr %}">Send a new assignment request</a>
+                    {% else %}
+                        -
+                    {% endif %}
+                </td>
+            </tr>
+            <tr>
+                <td>Status</td>
+                <td>{{ submission.get_status_display }}</td>
+            </tr>
+            <tr>
+                <td>Refereeing cycle</td>
+                <td>{{ submission.get_refereeing_cycle_display }}</td>
+            </tr>
+
+            {% include 'partials/submissions/refereeing_status_as_tr.html' with submission=submission %}
+
+            <tr>
+                <td>Comments</td>
+                <td>
+                    {{submission.comments.vetted.count}}
+                    <span class="circle-clickable" data-toggle="tooltip" data-placement='bottom' data-html="true" title="{{submission.comments.regular_comments.vetted.count}} comments<br>{{submission.comments.author_replies.vetted.count}} author replies<hr>{{submission.comments.awaiting_vetting.count}} awaiting vetting">?</span>
+                </td>
+            </tr>
+
+            <tr>
+                <td>Reporting deadline</td>
+                <td>
+                    {% if submission.reporting_deadline > now %}
+                        in {{submission.reporting_deadline|timeuntil}}
+                    {% else %}
+                        {{submission.reporting_deadline|timesince}} ago
+                    {% endif %}
+                </td>
+            </tr>
+
+            <tr>
+                <td>Plagiarism score</td>
+                <td>
+                    {% if submission.plagiarism_report %}
+                        {{ submission.plagiarism_report.score }}%
+                    {% else %}
+                        <a href="{% url 'submissions:plagiarism' submission.arxiv_identifier_w_vn_nr %}">Run plagiarism check</a>
+                    {% endif %}
+                </td>
+            </tr>
+
+        </table>
+        <a href="{% url 'submissions:editorial_page' submission.arxiv_identifier_w_vn_nr %}" class="d-inline-block mb-3">Go to Editorial Page</a>
+
+        <h3>Actions</h3>
+
+        <ul class="pl-4 mb-3">
+            {# EIC Assignments #}
+            {% if perms.scipost.can_assign_submissions %}
+                {% if not submission.editor_in_charge %}
+                    <li>EIC Assignment requests:</li>
+                    <ul>
+                        {% for assignment in submission.editorial_assignments.all %}
+                            {% include 'submissions/_assignment_info.html' with assignment=assignment %}
+                        {% empty %}
+                            <li>None found. <a href="{% url 'submissions:assign_submission' submission.arxiv_identifier_w_vn_nr %}">Send a first assignment request</a></li>
+                        {% endfor %}
+                    </ul>
+                    <li><a href="{% url 'submissions:assign_submission' submission.arxiv_identifier_w_vn_nr %}">Send a new assignment request</a></li>
+                    <li><a href="{% url 'submissions:assignment_failed' submission.arxiv_identifier_w_vn_nr %}">Close pre-screening: failure to find EIC</a></li>
+                {% endif %}
+            {% endif %}
+
+            {# Plagiarism #}
+            <li><a href="{% url 'submissions:plagiarism' submission.arxiv_identifier_w_vn_nr %}">Manage plagiarism report</a></li>
+
+            {# Compile pdfs #}
+            {% if submission.reports.accepted.exists %}
+                <li><a href="{% url 'submissions:reports_accepted_list' %}?submission={{submission.arxiv_identifier_w_vn_nr}}">Compile accepted reports</a></li>
+            {% endif %}
+
+            {# Communication #}
+            {% if submission.editor_in_charge %}
+                <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='StoE' %}">Send a communication to the Editor-in-charge</a></li>
+            {% endif %}
+
+            {# EIC Recommendations #}
+            {% if submission.eicrecommendations.exists %}
+                <li>See Editorial Recommendations:</li>
+                <ul>
+                    {% for rec in submission.eicrecommendations.all %}
+                        <li><a href="{% url 'submissions:eic_recommendation_detail' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr rec_id=rec.id %}">{{rec.get_recommendation_display}}</a></li>
+                    {% endfor %}
+                </ul>
+            {% endif %}
+
+            {# Accepted submission actions #}
+            {% if submission.status == 'accepted' %}
+                <li><a href="{% url 'submissions:treated_submission_pdf_compile' submission.arxiv_identifier_w_vn_nr %}">Update the Refereeing Package pdf</a></li>
+                <li>After proofs have been accepted, you can <a href="{% url 'journals:initiate_publication' %}">initiate the publication process</a> (leads to the validation page)</li>
+            {% endif %}
+        </ul>
+
+
+        <h3>Events</h3>
+        <div id="eventslist">
+            {% include 'submissions/submission_event_list.html' with events=submission.events.for_eic %}
+        </div>
+    </div>
+</div>
diff --git a/submissions/templates/partials/submissions/admin/submission_li.html b/submissions/templates/partials/submissions/admin/submission_li.html
new file mode 100644
index 0000000000000000000000000000000000000000..0581df05cb3f822992a09b38bb1357069bc57e87
--- /dev/null
+++ b/submissions/templates/partials/submissions/admin/submission_li.html
@@ -0,0 +1,24 @@
+<div class="row pool-item mb-0">
+    <div class="icons{% if is_current %} text-info{% endif %}">
+        {% include 'partials/submissions/admin/submission_tooltip.html' with submission=submission %}
+
+        {% if submission.status == 'unassigned' %}
+            <i class="fa fa-exclamation mt-1 px-1 text-danger" data-toggle="tooltip" data-html="true" title="This Submission does not have a Editor-in-charge"></i>
+        {% endif %}
+    </div>
+    <div class="item col-auto">
+        <p class="mb-1">
+            <a href="{% url 'submissions:admin' submission.arxiv_identifier_w_vn_nr %}">{{ submission.title }}</a><br>
+            <em>by {{ submission.author_list }}</em>
+        </p>
+
+        <p class="card-text mb-2">
+            <a href="{% url 'submissions:admin' submission.arxiv_identifier_w_vn_nr %}" data-toggle="dynamic" data-target="#details" data-toggle="dynamic" data-target="">See details</a>
+            {% if submission.editor_in_charge == request.user.contributor %}
+                &middot; <a href="{% url 'submissions:editorial_page' submission.arxiv_identifier_w_vn_nr %}">Go directly to editorial page</a>
+            {% endif %}
+        </p>
+
+        <p class="label label-{% if submission.status == 'unassigned' %}outline-danger{% else %}secondary{% endif %} label-sm">{{ submission.get_status_display }}</p>
+    </div>
+</div>
diff --git a/submissions/templates/partials/submissions/admin/submission_tooltip.html b/submissions/templates/partials/submissions/admin/submission_tooltip.html
index c2968b9a79145bbd96ea69ada144e497ee8f85a3..bdd541b910663d2361fb20b7bf4c1e85aa1ad565 100644
--- a/submissions/templates/partials/submissions/admin/submission_tooltip.html
+++ b/submissions/templates/partials/submissions/admin/submission_tooltip.html
@@ -1,4 +1,4 @@
-<span class="circle-clickable no-break" data-toggle="tooltip" data-html="true"
+<i class="fa fa-info-circle" data-toggle="tooltip" data-html="true"
     title="
         {{submission.arxiv_identifier_w_vn_nr}}<hr>Status: {{submission.get_status_display}}<br>Latest activity: {{submission.latest_activity}}
-">?</span>
+"></i>
diff --git a/submissions/templates/partials/submissions/pool/required_actions_tooltip.html b/submissions/templates/partials/submissions/pool/required_actions_tooltip.html
new file mode 100644
index 0000000000000000000000000000000000000000..1e9ce2a7234240d0a5ef96e121cb45c37f694b06
--- /dev/null
+++ b/submissions/templates/partials/submissions/pool/required_actions_tooltip.html
@@ -0,0 +1,10 @@
+{% if submission.cycle.has_required_actions and submission.cycle.get_required_actions %}
+    <i class="fa fa-exclamation-circle {{ classes }}" data-toggle="tooltip" data-html="true" title="
+        Required Actions:
+        <ul class='mb-0 pl-3 text-left'>
+            {% for action in submission.cycle.get_required_actions %}
+                <li>{{action.1}}</li>
+            {% endfor %}
+        </ul>
+    "></i>
+{% endif %}
diff --git a/submissions/templates/partials/submissions/pool/submission_details.html b/submissions/templates/partials/submissions/pool/submission_details.html
new file mode 100644
index 0000000000000000000000000000000000000000..4b45732367b38ee70410bf1231deabbc75c5fc9e
--- /dev/null
+++ b/submissions/templates/partials/submissions/pool/submission_details.html
@@ -0,0 +1,60 @@
+{% load guardian_tags %}
+{% load scipost_extras %}
+{% load submissions_extras %}
+
+
+<div class="card submission-detail">
+    {% include 'submissions/_submission_card_fellow_content.html' with submission=submission %}
+
+    <div class="card-body">
+        <h3>Remarks on this submission:</h3>
+        {% if remark_form %}
+            {% include 'submissions/_remark_add_form.html' with submission=submission form=remark_form auto_show=1 %}
+        {% endif %}
+        <p class="mb-1">Current remarks:</p>
+        <ul>
+          {% for rem in submission.remarks.all %}
+              {% include 'scipost/_remark_li.html' with remark=rem %}
+          {% empty %}
+              <li>No Remarks found.</li>
+          {% endfor %}
+        </ul>
+
+
+
+        {% get_obj_perms request.user for submission as "sub_perms" %}
+        {% if "can_take_editorial_actions" in sub_perms or is_ECAdmin %}
+            {% include 'submissions/_required_actions_block.html' with submission=submission %}
+            <h4>
+                <a href="{% url 'submissions:editorial_page' submission.arxiv_identifier_w_vn_nr %}">Go to this Submission's Editorial Page</a>
+            </h4>
+        {% endif %}
+
+        {% if perms.scipost.can_assign_submissions %}
+            {% if submission.editorial_assignments.exists %}
+                <h4>EIC Assignment requests:</h4>
+                <ul>
+                  {% for assignment in submission.editorial_assignments.all %}
+                      {% include 'submissions/_assignment_info.html' with assignment=assignment %}
+                  {% endfor %}
+                </ul>
+            {% endif %}
+            {% if submission.editor_in_charge == None %}
+                <h4>Actions:</h4>
+                <ul>
+                  <li><a href="{% url 'submissions:assign_submission' submission.arxiv_identifier_w_vn_nr %}">Send a new assignment request</a></li>
+                  <li><a href="{% url 'submissions:assignment_failed' submission.arxiv_identifier_w_vn_nr %}">Close pre-screening: failure to find EIC</a></li>
+                </ul>
+            {% endif %}
+        {% endif %}
+
+        {% if is_ECAdmin %}
+            <h4>
+                <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='StoE' %}">Send a communication to the Editor-in-charge</a>
+            </h4>
+            {% if submission.status == 'accepted' %}
+                <h4>After proofs have been accepted, you can <a href="{% url 'journals:initiate_publication' %}">initiate the publication process</a> (leads to the validation page)</h4>
+            {% endif %}
+        {% endif %}
+    </div>
+</div>
diff --git a/submissions/templates/partials/submissions/pool/submission_li.html b/submissions/templates/partials/submissions/pool/submission_li.html
new file mode 100644
index 0000000000000000000000000000000000000000..73bc7fa516e69125906942aef32ac11b5fbac287
--- /dev/null
+++ b/submissions/templates/partials/submissions/pool/submission_li.html
@@ -0,0 +1,37 @@
+<div class="row pool-item mb-0">
+    <div class="icons{% if is_current %} text-info{% endif %}">
+        {% include 'partials/submissions/admin/submission_tooltip.html' with submission=submission %}
+
+        {% if submission.status == 'unassigned' %}
+            <i class="fa fa-exclamation mt-1 px-1 text-danger" data-toggle="tooltip" data-html="true" title="You can volunteer to become Editor-in-charge"></i>
+        {% endif %}
+    </div>
+    <div class="item col-auto">
+        <p class="mb-1">
+            <a href="{% url 'submissions:pool' submission.arxiv_identifier_w_vn_nr %}">{{ submission.title }}</a><br>
+            <em>by {{ submission.author_list }}</em>
+        </p>
+
+        <p class="card-text mb-3">
+            <a href="{% url 'submissions:pool' submission.arxiv_identifier_w_vn_nr %}" data-toggle="dynamic" data-target="#details">See details</a>
+            {% if submission.editor_in_charge == request.user.contributor %}
+                &middot; <a href="{% url 'submissions:editorial_page' submission.arxiv_identifier_w_vn_nr %}">Go directly to editorial page</a>
+            {% endif %}
+        </p>
+
+        {% if submission.cycle.has_required_actions and submission.cycle.get_required_actions %}
+            <p class="card-text bg-danger text-white p-1 px-2">This Submission contains required actions, <a href="{% url 'submissions:pool' submission.arxiv_identifier_w_vn_nr %}" class="text-white" data-toggle="dynamic" data-target="#details">click to see details.</a> {% include 'partials/submissions/pool/required_actions_tooltip.html' with submission=submission classes='text-white' %}</p>
+        {% endif %}
+
+        {% if submission.status == 'unassigned' %}
+            <p class="card-text text-danger">You can volunteer to become Editor-in-charge by <a href="{% url 'submissions:volunteer_as_EIC' submission.arxiv_identifier_w_vn_nr %}">clicking here</a>.</p>
+        {% elif submission.editor_in_charge == request.user.contributor %}
+            <p class="card-text"><strong>You are Editor-in-charge</strong></p>
+        {% else %}
+            <p class="card-text">Editor-in-charge: <em>{{ submission.editor_in_charge }}</em></p>
+        {% endif %}
+
+        <p class="label label-{% if submission.status == 'unassigned' %}outline-danger{% else %}secondary{% endif %} label-sm">{{ submission.get_status_display }}</p>
+
+    </div>
+</div>
diff --git a/submissions/templates/submissions/_remark_add_form.html b/submissions/templates/submissions/_remark_add_form.html
index 1541145e29fca3ec142bae5ec2d6fde733a54bea..f2872b2a19755ab5d12e5f230171d049ad97a865 100644
--- a/submissions/templates/submissions/_remark_add_form.html
+++ b/submissions/templates/submissions/_remark_add_form.html
@@ -16,11 +16,19 @@ $(document).ready(function(){
   });
 </script>
 
-<button class="btn btn-secondary mb-2" data-toggle="toggle" data-target="#remarkForm{{ submission.id }}" id="remarkButton{{ submission.id }}">Add a remark on this Submission</button>
-<div class="submitRemarkForm pb-2" id="remarkForm{{ submission.id }}" style="display:none;">
-    <form action="{% url 'submissions:add_remark' submission.arxiv_identifier_w_vn_nr %}" method="post">
+{% if auto_show %}
+    <form action="{% url 'submissions:add_remark' submission.arxiv_identifier_w_vn_nr %}" method="post" class="pb-2">
         {% csrf_token %}
         {{ form|bootstrap:'0,12' }}
         <input class="btn btn-secondary" type="submit" value="Submit" />
     </form>
-</div>
+{% else %}
+    <button class="btn btn-secondary mb-2" data-toggle="toggle" data-target="#remarkForm{{ submission.id }}" id="remarkButton{{ submission.id }}">Add a remark on this Submission</button>
+    <div class="submitRemarkForm pb-2" id="remarkForm{{ submission.id }}" style="display:none;">
+        <form action="{% url 'submissions:add_remark' submission.arxiv_identifier_w_vn_nr %}" method="post">
+            {% csrf_token %}
+            {{ form|bootstrap:'0,12' }}
+            <input class="btn btn-secondary" type="submit" value="Submit" />
+        </form>
+    </div>
+{% endif %}
diff --git a/submissions/templates/submissions/_submission_assignment_request.html b/submissions/templates/submissions/_submission_assignment_request.html
index cceb540850b6a489ae5161372e3c018177ad76dd..4f274474ef169f87858842bf39fdadcec8618868 100644
--- a/submissions/templates/submissions/_submission_assignment_request.html
+++ b/submissions/templates/submissions/_submission_assignment_request.html
@@ -8,7 +8,7 @@
     <h1>Accept or Decline this Assignment</h1>
     <h3 class="mb-2">By accepting, you will be required to start a refereeing round on the next screen.</h3>
 
-    <form action="{% url 'submissions:accept_or_decline_assignment_ack' assignment_id=assignment.id %}" method="post">
+    <form action="{% url 'submissions:assignment_request' assignment_id=assignment.id %}" method="post">
         {% csrf_token %}
         <div class="form-group row">
             <div class="col-12">
diff --git a/submissions/templates/submissions/accept_or_decline_assignment_ack.html b/submissions/templates/submissions/accept_or_decline_assignment_ack.html
deleted file mode 100644
index 67a7551cca06e5c12e852c533d727220874f89e1..0000000000000000000000000000000000000000
--- a/submissions/templates/submissions/accept_or_decline_assignment_ack.html
+++ /dev/null
@@ -1,20 +0,0 @@
-{% extends 'scipost/base.html' %}
-
-{% block pagetitle %}: accept or decline assignment (ack){% endblock pagetitle %}
-
-{% block content %}
-
-
-  {% if errormessage %}
-      <p>{{ errormessage }}</p>
-      <p>Return to the <a href="{% url 'submissions:pool' %}">Submissions Pool</a>.</p>
-
-  {% elif assignment.accepted %}
-      <h1>Thank you for becoming Editor-in-charge of this submission.</h1>
-      <p>Please go to the <a href="{% url 'submissions:editorial_page' arxiv_identifier_w_vn_nr=assignment.submission.arxiv_identifier_w_vn_nr %}">Submission's editorial page</a> and select referees now.</p>
-  {% else %}
-      <h1>Thank you for considering.</h1>
-      <p>Return to the <a href="{% url 'submissions:pool' %}">Submissions Pool</a>.</p>
-  {% endif %}
-
-{% endblock content %}
diff --git a/submissions/templates/submissions/admin/base.html b/submissions/templates/submissions/admin/base.html
new file mode 100644
index 0000000000000000000000000000000000000000..e238b581c8e1952ae403c814db783bf57f98f4ea
--- /dev/null
+++ b/submissions/templates/submissions/admin/base.html
@@ -0,0 +1,13 @@
+{% extends 'scipost/base.html' %}
+
+{% block breadcrumb %}
+    <nav class="breadcrumb py-md-2 px-0 hidden-sm-down">
+        <div class="container">
+            {% block breadcrumb_items %}
+                <a href="{% url 'submissions:admin' %}" class="breadcrumb-item">Editorial Administration</a>
+            {% endblock %}
+        </div>
+    </nav>
+{% endblock %}
+
+{% block container_class %}{{block.super}} pb-5{% endblock container_class %}
diff --git a/submissions/templates/submissions/admin/editorial_admin.html b/submissions/templates/submissions/admin/editorial_admin.html
index f4daca1875640058f3f10369785d8e4747bdc7ab..8c23d6beb54f3791e2f0fda8b08b3590c74bd77d 100644
--- a/submissions/templates/submissions/admin/editorial_admin.html
+++ b/submissions/templates/submissions/admin/editorial_admin.html
@@ -1,12 +1,15 @@
-{% extends 'scipost/_personal_page_base.html' %}
+{% extends 'submissions/admin/base.html' %}
+
+{% load scipost_extras %}
 
 {% block pagetitle %}: Editorial Administration{% endblock pagetitle %}
 
 {% block breadcrumb_items %}
-    {{block.super}}
-    <span class="breadcrumb-item">Editorial Administration</span>
+    {{ block.super }}
+    <span class="breadcrumb-item">{% if submission %}{{ submission.arxiv_identifier_w_vn_nr }}{% else %}All events in the last 24 hours{% endif %}</span>
 {% endblock %}
 
+{% block body_class %}{{ block.super }} editorial-admin{% endblock %}
 
 {% block content %}
 <div class="row">
@@ -20,26 +23,38 @@
             <a href="{% url 'submissions:pool' %}">Go to the pool</a>
         </p>
 
+        {% if recommendations_to_prepare_for_voting %}
+            <h3>Recommendations to prepare for voting <i class="fa fa-exclamation-circle text-warning"></i></h3>
+            <ul>
+                {% for recommendation in recommendations_to_prepare_for_voting %}
+                    <li>On Editorial Recommendation: {{ recommendation }}<br>
+                        <a href="{% url 'submissions:prepare_for_voting' rec_id=recommendation.id %}">Prepare for voting</a>
+                    </li>
+                {% endfor %}
+            </ul>
+        {% endif %}
+
+        {% if recommendations_undergoing_voting %}
+            <h3>Recommendations undergoing voting <i class="fa fa-exclamation-circle text-warning"></i></h3>
+            <ul class="fa-ul">
+                {% for recommendation in recommendations_undergoing_voting %}
+                    <li>{% include 'partials/submissions/admin/recommendation_tooltip.html' with classes='fa-li' recommendation=recommendation %}
+                        On Editorial Recommendation: {{ recommendation }}<br>
+                        <a href="{% url 'submissions:admin_recommendation' recommendation.submission.arxiv_identifier_w_vn_nr %}">See Editorial Recommendation</a>
+                    </li>
+                {% endfor %}
+            </ul>
+        {% endif %}
+
+        {% if recommendations_to_prepare_for_voting or recommendations_undergoing_voting %}
+            <hr>
+        {% endif %}
+
         <h3>Submissions currently in pre-screening</h3>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled" data-target="active-list">
             {% for sub in submission_list.prescreening %}
-                <li>
-                    {% include 'partials/submissions/admin/submission_tooltip.html' with submission=sub %}
-                    {% if sub == submission %}
-                        <strong>
-                            <a href="?submission={{sub.arxiv_identifier_w_vn_nr}}">{{sub.title}}</a>
-                            <div class="pl-md-4">
-                                <em>by {{sub.author_list}}</em><br>
-                                latest activity: {{sub.latest_activity|timesince}} ago
-                            </div>
-                        </strong>
-                    {% else %}
-                        <a href="?submission={{sub.arxiv_identifier_w_vn_nr}}">{{sub.title}}</a>
-                        <div class="pl-md-4">
-                            <em>by {{sub.author_list}}</em><br>
-                            latest activity: {{sub.latest_activity|timesince}} ago
-                        </div>
-                    {% endif %}
+                <li class="p-2{% if sub == submission %} active{% endif %}">
+                    {% include 'partials/submissions/admin/submission_li.html' with submission=sub %}
                 </li>
             {% empty %}
                 <li>No Submissions are currently in pre-screening</li>
@@ -47,25 +62,10 @@
         </ul>
 
         <h3>Submissions currently in refereeing round</h3>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled" data-target="active-list">
             {% for sub in submission_list.actively_refereeing %}
-                <li>
-                    {% include 'partials/submissions/admin/submission_tooltip.html' with submission=sub %}
-                    {% if sub == submission %}
-                        <strong>
-                            <a href="?submission={{sub.arxiv_identifier_w_vn_nr}}">{{sub.title}}</a>
-                            <div class="pl-md-4">
-                                <em>by {{sub.author_list}}</em><br>
-                                latest activity: {{sub.latest_activity|timesince}} ago
-                            </div>
-                        </strong>
-                    {% else %}
-                        <a href="?submission={{sub.arxiv_identifier_w_vn_nr}}">{{sub.title}}</a>
-                        <div class="pl-md-4">
-                            <em>by {{sub.author_list}}</em><br>
-                            latest activity: {{sub.latest_activity|timesince}} ago
-                        </div>
-                    {% endif %}
+                <li class="p-2{% if sub == submission %} active{% endif %}">
+                    {% include 'partials/submissions/admin/submission_li.html' with submission=sub %}
                 </li>
             {% empty %}
                 <li>No Submissions are currently in refereeing round</li>
@@ -73,25 +73,10 @@
         </ul>
 
         <h3>Submissions accepted</h3>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled" data-target="active-list">
             {% for sub in submission_list.accepted %}
-                <li>
-                    {% include 'partials/submissions/admin/submission_tooltip.html' with submission=sub %}
-                    {% if sub == submission %}
-                        <strong>
-                            <a href="?submission={{sub.arxiv_identifier_w_vn_nr}}">{{sub.title}}</a>
-                            <div class="pl-md-4">
-                                <em>by {{sub.author_list}}</em><br>
-                                latest activity: {{sub.latest_activity|timesince}} ago
-                            </div>
-                        </strong>
-                    {% else %}
-                        <a href="?submission={{sub.arxiv_identifier_w_vn_nr}}">{{sub.title}}</a>
-                        <div class="pl-md-4">
-                            <em>by {{sub.author_list}}</em><br>
-                            latest activity: {{sub.latest_activity|timesince}} ago
-                        </div>
-                    {% endif %}
+                <li class="p-2{% if sub == submission %} active{% endif %}">
+                    {% include 'partials/submissions/admin/submission_li.html' with submission=sub %}
                 </li>
             {% empty %}
                 <li>All accepted Submissions are published</li>
@@ -99,13 +84,9 @@
         </ul>
     </div>
 
-    <div class="col-md-5">
+    <div class="col-md-5" id="details">
         {% if submission %}
-            <div class="card border-secondary mt-2">
-                <div class="card-body">
-                    {% include 'partials/submissions/admin/editorial_admin_summary.html' with submission=submission %}
-                </div>
-            </div>
+            {% include 'partials/submissions/admin/submission_details.html' with submission=submission %}
         {% else %}
             <h3><em>Click on a submission to see its summary and actions</em></h3>
             <h2>All events in the last 24 hours</h2>
diff --git a/submissions/templates/submissions/admin/eic_recommendation_detail.html b/submissions/templates/submissions/admin/eic_recommendation_detail.html
index e453c3dc64de64d4d7a1ae07d45b33b4dc8532eb..f23a39ca8801f4f05d342ea65aab60d0368eaa4e 100644
--- a/submissions/templates/submissions/admin/eic_recommendation_detail.html
+++ b/submissions/templates/submissions/admin/eic_recommendation_detail.html
@@ -1,4 +1,4 @@
-{% extends 'submissions/_pool_base.html' %}
+{% extends 'submissions/admin/base.html' %}
 
 {% block pagetitle %}: editorial recommendation for submission{% endblock pagetitle %}
 
@@ -7,7 +7,6 @@
 
 {% block breadcrumb_items %}
     {{block.super}}
-    <a href="{% url 'submissions:admin' %}?submission={{submission.arxiv_identifier_w_vn_nr}}" class="breadcrumb-item">Editorial Administration</a>
     <span class="breadcrumb-item">Editorial Recommendation</span>
 {% endblock %}
 
diff --git a/submissions/templates/submissions/admin/plagiarism_report.html b/submissions/templates/submissions/admin/plagiarism_report.html
index 2b13c4fb62ec96eb757ffee4a64fbf7416a45963..8aa8d6f2d491233a829d57123779d107ae7038d4 100644
--- a/submissions/templates/submissions/admin/plagiarism_report.html
+++ b/submissions/templates/submissions/admin/plagiarism_report.html
@@ -1,4 +1,4 @@
-{% extends 'scipost/_personal_page_base.html' %}
+{% extends 'submissions/admin/base.html' %}
 
 {% load bootstrap %}
 
@@ -6,7 +6,6 @@
 
 {% block breadcrumb_items %}
     {{block.super}}
-    <a href="{% url 'submissions:admin' %}?submission={{submission.arxiv_identifier_w_vn_nr}}" class="breadcrumb-item">Editorial Administration</a>
     <span class="breadcrumb-item">Plagiarism Report ({{ submission.arxiv_identifier_w_vn_nr }})</span>
 {% endblock %}
 
diff --git a/submissions/templates/submissions/admin/recommendation.html b/submissions/templates/submissions/admin/recommendation.html
new file mode 100644
index 0000000000000000000000000000000000000000..a4eed96cbcd805ad7f90cddf7655bfa75873fdae
--- /dev/null
+++ b/submissions/templates/submissions/admin/recommendation.html
@@ -0,0 +1,84 @@
+{% extends 'submissions/pool/base.html' %}
+
+{% load bootstrap %}
+{% load scipost_extras %}
+
+{% block breadcrumb_items %}
+    <a href="{% url 'submissions:admin' %}" class="breadcrumb-item">Editorial Administration</a>
+    <span class="breadcrumb-item">Editorial Recommendation</span>
+{% endblock %}
+
+{% block pagetitle %}: Editorial Recommendation{% endblock pagetitle %}
+
+{% block content %}
+    <h1 class="highlight">Editorial Recommendation</h1>
+
+    <div class="card card-outline-secondary">
+        {% include 'submissions/_submission_card_fellow_content_sparse.html' with submission=object.submission %}
+    </div>
+
+    <div class="card card-outline-secondary">
+        {% include 'submissions/_recommendation_fellow_content.html' with recommendation=object %}
+        <div class="card-body">
+            {% if object.remarks.exists %}
+                <h3 class="card-title">Remarks by Fellows:</h3>
+                <ul>
+                  {% for remark in object.remarks.all|sort_by:'date' %}
+                      {% include 'partials/submissions/remark_as_li.html' with remark=remark %}
+                  {% endfor %}
+                </ul>
+            {% endif %}
+
+            <h3 class="card-title">Fellows eligible to vote:</h3>
+            <ul>
+              <li>
+                  {% for eligible in object.eligible_to_vote.all|sort_by:'user__last_name' %}
+                      {{ eligible.user.last_name }},&nbsp;
+                  {% endfor %}
+                </li>
+            </ul>
+
+            <h3 class="card-title">Voting results up to now:</h3>
+            <ul>
+                <li>
+                    Agreed:&nbsp;({{ object.voted_for.all.count }})
+                    {% for agreed in object.voted_for.all|sort_by:'user__last_name' %}
+                        {{ agreed.user.last_name }},&nbsp;
+                    {% endfor %}
+                </li>
+                <li>
+                    Disagreed:&nbsp;({{ object.voted_against.all.count }})
+                    {% for disagreed in object.voted_against.all|sort_by:'user__last_name' %}
+                        {{ disagreed.user.last_name }},&nbsp;
+                    {% endfor %}
+                </li>
+                <li>
+                    Abstained:&nbsp;({{ object.voted_abstain.all.count }})
+                    {% for abstained in object.voted_abstain.all|sort_by:'user__last_name' %}
+                        {{ abstained.user.last_name }},&nbsp;
+                    {% endfor %}
+                </li>
+            </ul>
+
+            {% if object.remarks.exists %}
+                <h3 class="card-title">Remarks:</h3>
+                <ul>
+                  {% for rem in object.remarks.all %}
+                      <li>{{ rem }}</li>
+                 {% empty %}
+                     <li><em>No remarks</em></li>
+                  {% endfor %}
+                </ul>
+            {% endif %}
+        </div>
+        <div class="card-footer">
+            <h3 class="card-title">Administrative actions on recommendations undergoing voting:</h3>
+            <ul>
+                <li>To send an email reminder to each Fellow with at least one voting duty: <a href="{% url 'submissions:remind_Fellows_to_vote' %}">click here</a></li>
+                <li>To fix the College decision and follow the Editorial Recommendation as is: <a href="{% url 'submissions:fix_College_decision' rec_id=object.id %}">click here</a></li>
+                <li>To request a modification of the Recommendation to request for revision: click here</li>
+            </ul>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/submissions/templates/submissions/pool/assignment_request.html b/submissions/templates/submissions/pool/assignment_request.html
new file mode 100644
index 0000000000000000000000000000000000000000..2f0b46cde76c735220de426c609285ce8f891ef8
--- /dev/null
+++ b/submissions/templates/submissions/pool/assignment_request.html
@@ -0,0 +1,20 @@
+{% extends 'submissions/pool/base.html' %}
+
+{% load bootstrap %}
+{% load guardian_tags %}
+{% load scipost_extras %}
+{% load submissions_extras %}
+
+{% block breadcrumb_items %}
+    {{ block.super }}
+    <span class="breadcrumb-item">Assignment Request</span>
+{% endblock %}
+
+{% block pagetitle %}: Assignment Request{% endblock pagetitle %}
+
+{% block content %}
+    <h1 class="highlight">Assignment request</h1>
+    <h3>Can you act as Editor-in-charge? (see below to accept/decline)</h3>
+
+    {% include 'submissions/_submission_assignment_request.html' with assignment=assignment consider_assignment_form=form %}
+{% endblock %}
diff --git a/submissions/templates/submissions/pool/base.html b/submissions/templates/submissions/pool/base.html
new file mode 100644
index 0000000000000000000000000000000000000000..ca638eb5ab558e81c5911ad27e2788d812086d5a
--- /dev/null
+++ b/submissions/templates/submissions/pool/base.html
@@ -0,0 +1,13 @@
+{% extends 'scipost/base.html' %}
+
+{% block body_class %}{{ block.super }} pool{% endblock %}
+
+{% block breadcrumb %}
+    <nav class="breadcrumb py-md-2 px-0">
+        <div class="container">
+            {% block breadcrumb_items %}
+                <a href="{% url 'submissions:pool' %}" class="breadcrumb-item">Pool</a>
+            {% endblock %}
+        </div>
+    </nav>
+{% endblock %}
diff --git a/submissions/templates/submissions/pool/pool.html b/submissions/templates/submissions/pool/pool.html
new file mode 100644
index 0000000000000000000000000000000000000000..f304a5068691ef1752024a24e507eb474d131f58
--- /dev/null
+++ b/submissions/templates/submissions/pool/pool.html
@@ -0,0 +1,90 @@
+{% extends 'submissions/pool/base.html' %}
+
+{% load bootstrap %}
+{% load guardian_tags %}
+{% load scipost_extras %}
+{% load submissions_extras %}
+
+{% block breadcrumb_items %}
+    <a href="{% url 'scipost:personal_page' %}" class="breadcrumb-item">Personal Page</a>
+    {% if submission %}
+        <a href="{% url 'submissions:pool' %}" class="breadcrumb-item">Pool</a>
+        <span class="breadcrumb-item">{{ submission.arxiv_identifier_w_vn_nr }}</span>
+    {% else %}
+        <span class="breadcrumb-item">Pool</span>
+    {% endif %}
+{% endblock %}
+
+{% block pagetitle %}: Submissions Pool{% endblock pagetitle %}
+
+{% block content %}
+    {% with is_ECAdmin=request.user|is_in_group:'Editorial Administrators' %}
+        <a href="{% url 'submissions:pool' %}?test=1">See old pool layout</a>
+        <div class="row">
+            <div class="col-md-7">
+                <h1>SciPost Submissions Pool</h1>
+                {% if is_ECAdmin %}
+                    <a href="{% url 'submissions:admin' %}">Go to the Editorial Administration</a>
+                {% endif %}
+
+                {% if assignments_to_consider %}
+                    <h3>Your open Assignment Requests <i class="fa fa-exclamation-circle text-warning"></i></h3>
+                    <ul>
+                        {% for assignment in assignments_to_consider %}
+                            <li>On submission: {{ assignment.submission }}<br>
+                                <a href="{% url 'submissions:assignment_request' assignment.id %}">Accept or decline here</a>
+                            </li>
+                        {% endfor %}
+                    </ul>
+                {% endif %}
+
+                {% if recs_to_vote_on %}
+                    <h3>Recommendations to vote on <i class="fa fa-exclamation-circle text-warning"></i></h3>
+                    <ul>
+                        {% for recommendation in recs_to_vote_on %}
+                            <li>On Editorial Recommendation of: {{ recommendation.submission }}<br>
+                                <a href="{% url 'submissions:vote_on_rec' rec_id=recommendation.id %}">See the Editorial Recommendation</a>
+                            </li>
+                        {% endfor %}
+                    </ul>
+                {% endif %}
+
+                {% if assignments_to_consider or recs_to_vote_on %}
+                    <hr>
+                {% endif %}
+
+                {% if search_form %}
+                    <h3>Filter by status</h3>
+                    <form method="get" class="auto-submit mb-3">
+                        {{ search_form|bootstrap:'12,12' }}
+                    </form>
+                {% endif %}
+
+                <ul class="list-unstyled" data-target="active-list">
+                    <!-- Submissions list -->
+                    {% for sub in submissions_in_pool %}
+                        <li class="p-2{% if sub == submission %} active{% endif %}">
+                            {% if sub == submission %}
+                                {% include 'partials/submissions/pool/submission_li.html' with submission=sub is_current=1 %}
+                            {% else %}
+                                {% include 'partials/submissions/pool/submission_li.html' with submission=sub is_current=0 %}
+                            {% endif %}
+                        </li>
+                    {% empty %}
+                        <li>
+                            <h3 class="text-center"><i class="fa fa-question fa-2x"></i><br>No Submissions found.</h3>
+                        </li>
+                    {% endfor %}
+                </ul>
+            </div><!-- End page content -->
+
+            <div class="col-md-5" id="details">
+                {% if submission %}
+                    {% include 'partials/submissions/pool/submission_details.html' with submission=submission remark_form=remark_form is_ECAdmin=is_ECAdmin user=request.user %}
+                {% else %}
+                    <h3><em>Click on a submission to see its summary and actions</em></h3>
+                {% endif %}
+            </div>
+        </div>
+    {% endwith %}
+{% endblock %}
diff --git a/submissions/templates/submissions/pool/recommendation.html b/submissions/templates/submissions/pool/recommendation.html
new file mode 100644
index 0000000000000000000000000000000000000000..d2c050bbb0c1b3090e5f8c6d83a35bb2c81c6b24
--- /dev/null
+++ b/submissions/templates/submissions/pool/recommendation.html
@@ -0,0 +1,29 @@
+{% extends 'submissions/pool/base.html' %}
+
+{% load bootstrap %}
+
+{% block breadcrumb_items %}
+    {{ block.super }}
+    <span class="breadcrumb-item">Editorial Recommendation</span>
+{% endblock %}
+
+{% block pagetitle %}: Editorial Recommendation{% endblock pagetitle %}
+
+{% block content %}
+    <h1>Editorial Recommendation to vote on</h1>
+
+    {% include 'submissions/_submission_card_fellow_content.html' with submission=recommendation.submission %}
+
+    {# <div class="card card-outline-secondary">#}
+        {% include 'submissions/_recommendation_fellow_content.html' with recommendation=recommendation %}
+        <div class="card-footer">
+            <h3>Your position on this recommendation</h3>
+            <form action="{% url 'submissions:vote_on_rec' rec_id=recommendation.id %}" method="post">
+                {% csrf_token %}
+                {{ form|bootstrap:'0,12' }}
+                <input type="submit" name="submit" value="Cast your vote" class="btn btn-primary submitButton" id="submit-id-submit">
+            </form>
+        </div>
+    {# </div>#}
+
+{% endblock %}
diff --git a/submissions/urls.py b/submissions/urls.py
index c1f46c9ab3839e1758c764de519a0ae91a24eecf..6cd83e4ec6d855ebde05931aa76a0cafb7b863b5 100644
--- a/submissions/urls.py
+++ b/submissions/urls.py
@@ -26,6 +26,8 @@ urlpatterns = [
 
     # Editorial Administration
     url(r'^admin$', views.EditorialSummaryView.as_view(), name='admin'),
+    url(r'^admin/{regex}$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
+        views.EditorialSummaryView.as_view(), name='admin'),
     url(r'^admin/treated$', views.treated_submissions_list, name='treated_submissions_list'),
     url(r'^admin/{regex}/reports/compile$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
         views.treated_submission_pdf_compile, name='treated_submission_pdf_compile'),
@@ -40,13 +42,16 @@ urlpatterns = [
         views.report_pdf_compile, name='report_pdf_compile'),
     url(r'^admin/reports/(?P<report_id>[0-9]+)/compile$',
         views.report_pdf_compile, name='report_pdf_compile'),
+    url(r'^admin/{regex}/recommendation$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
+        views.AdminRecommendationView.as_view(), name='admin_recommendation'),
 
     url(r'^submit_manuscript$', views.RequestSubmission.as_view(), name='submit_manuscript'),
     url(r'^submit_manuscript/prefill$', views.prefill_using_arxiv_identifier,
         name='prefill_using_identifier'),
-    url(r'^pool$', views.pool, name='pool'),
+    url(r'^pool/$', views.pool, name='pool'),
+    url(r'^pool/{regex}/$'.format(regex=SUBMISSIONS_COMPLETE_REGEX), views.pool, name='pool'),
     url(r'^submissions_by_status/(?P<status>[a-zA-Z_]+)$',
-        views.submissions_by_status, name='submissions_by_status'),
+        views.submissions_by_status, name='submissions_by_status'),  # DEPRECATED
     url(r'^add_remark/{regex}$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
         views.add_remark, name='add_remark'),
 
@@ -55,8 +60,8 @@ urlpatterns = [
         views.assign_submission, name='assign_submission'),
     url(r'^assign_submission_ack/{regex}$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
         views.assign_submission_ack, name='assign_submission_ack'),
-    url(r'^accept_or_decline_assignment_ack/(?P<assignment_id>[0-9]+)$',
-        views.accept_or_decline_assignment_ack, name='accept_or_decline_assignment_ack'),
+    url(r'^pool/assignment_request/(?P<assignment_id>[0-9]+)$',
+        views.assignment_request, name='assignment_request'),
     url(r'^volunteer_as_EIC/{regex}$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
         views.volunteer_as_EIC, name='volunteer_as_EIC'),
     url(r'^assignment_failed/{regex}$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
diff --git a/submissions/views.py b/submissions/views.py
index fa5058d73c28450e2ecb096ecf2a806cbb636b03..7007d5d231c2a9af3164314afbd0f38d241bee4b 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -31,13 +31,14 @@ from .forms import SubmissionIdentifierForm, RequestSubmissionForm, SubmissionSe
                    ConsiderRefereeInvitationForm, EditorialCommunicationForm,\
                    EICRecommendationForm, ReportForm, VetReportForm, VotingEligibilityForm,\
                    SubmissionCycleChoiceForm, ReportPDFForm, SubmissionReportsForm,\
-                   iThenticateReportForm
+                   iThenticateReportForm, SubmissionPoolFilterForm
 from .utils import SubmissionUtils
 
 from mails.views import MailEditingSubView
 from scipost.forms import ModifyPersonalMessageForm, RemarkForm
 from scipost.models import Contributor, Remark, RegistrationInvitation
 from scipost.utils import Utils
+from scipost.permissions import is_tester
 
 from comments.forms import CommentForm
 from production.models import ProductionStream
@@ -95,10 +96,11 @@ class RequestSubmission(CreateView):
 @login_required
 @permission_required('scipost.can_submit_manuscript', raise_exception=True)
 def prefill_using_arxiv_identifier(request):
-    query_form = SubmissionIdentifierForm(request.POST or None, initial=request.GET or None)
+    query_form = SubmissionIdentifierForm(request.POST or None, initial=request.GET or None,
+                                          requested_by=request.user)
     if query_form.is_valid():
         prefill_data = query_form.request_arxiv_preprint_form_prefill_data()
-        form = RequestSubmissionForm(initial=prefill_data)
+        form = RequestSubmissionForm(initial=prefill_data, requested_by=request.user)
 
         # Submit message to user
         if query_form.submission_is_resubmission():
@@ -324,7 +326,7 @@ def editorial_workflow(request):
 
 @login_required
 @permission_required('scipost.can_view_pool', raise_exception=True)
-def pool(request):
+def pool(request, arxiv_identifier_w_vn_nr=None):
     """
     The Submissions pool contains all submissions which are undergoing
     the editorial process, from submission
@@ -335,14 +337,13 @@ def pool(request):
                            .prefetch_related('referee_invitations', 'remarks', 'comments'))
     recommendations_undergoing_voting = (EICRecommendation.objects
                                          .get_for_user_in_pool(request.user)
-                                         .filter(submission__status__in=['put_to_EC_voting']))
+                                         .filter(submission__status='put_to_EC_voting'))
     recommendations_to_prepare_for_voting = (EICRecommendation.objects
                                              .get_for_user_in_pool(request.user)
                                              .filter(
-                                                submission__status__in=['voting_in_preparation']))
+                                                submission__status='voting_in_preparation'))
     contributor = Contributor.objects.get(user=request.user)
-    assignments_to_consider = EditorialAssignment.objects.filter(
-        to=contributor, accepted=None, deprecated=False)
+    assignments_to_consider = EditorialAssignment.objects.open().filter(to=contributor)
     consider_assignment_form = ConsiderAssignmentForm()
     recs_to_vote_on = (EICRecommendation.objects.get_for_user_in_pool(request.user)
                        .filter(eligible_to_vote=contributor)
@@ -353,21 +354,53 @@ def pool(request):
                        .exclude(submission__status__in=SUBMISSION_STATUS_VOTING_DEPRECATED))
     rec_vote_form = RecommendationVoteForm()
     remark_form = RemarkForm()
-    context = {'submissions_in_pool': submissions_in_pool,
-               'submission_status': SUBMISSION_STATUS,
-               'recommendations_undergoing_voting': recommendations_undergoing_voting,
-               'recommendations_to_prepare_for_voting': recommendations_to_prepare_for_voting,
-               'assignments_to_consider': assignments_to_consider,
-               'consider_assignment_form': consider_assignment_form,
-               'recs_to_vote_on': recs_to_vote_on,
-               'rec_vote_form': rec_vote_form,
-               'remark_form': remark_form, }
-    return render(request, 'submissions/pool.html', context)
+    context = {
+        'submissions_in_pool': submissions_in_pool,
+        'submission_status': SUBMISSION_STATUS,
+        'recommendations_undergoing_voting': recommendations_undergoing_voting,
+        'recommendations_to_prepare_for_voting': recommendations_to_prepare_for_voting,
+        'assignments_to_consider': assignments_to_consider,
+        'consider_assignment_form': consider_assignment_form,
+        'recs_to_vote_on': recs_to_vote_on,
+        'rec_vote_form': rec_vote_form,
+        'remark_form': remark_form,
+        'submission': None
+    }
+
+    # The following is in test phase. Update if test is done
+    # --
+
+    # Search
+    search_form = SubmissionPoolFilterForm(request.GET or None)
+    if search_form.is_valid():
+        context['submissions_in_pool'] = search_form.search(context['submissions_in_pool'],
+                                                            request.user.contributor)
+    context['search_form'] = search_form
+
+    # Show specific submission in the pool
+    if arxiv_identifier_w_vn_nr:
+        try:
+            context['submission'] = context['submissions_in_pool'].get(
+                arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
+        except Submission.DoesNotExist:
+            pass
+
+    # Temporary test logic: only testers see the new Pool
+    if context['submission'] and request.GET.get('json'):
+        template = 'partials/submissions/pool/submission_details.html'
+    elif is_tester(request.user) and not request.GET.get('test'):
+        template = 'submissions/pool/pool.html'
+    else:
+        template = 'submissions/pool.html'
+    return render(request, template, context)
 
 
 @login_required
 @permission_required('scipost.can_view_pool', raise_exception=True)
 def submissions_by_status(request, status):
+    # ---
+    # DEPRECATED AS PER NEW POOL
+    # ---
     status_dict = dict(SUBMISSION_STATUS)
     if status not in status_dict.keys():
         errormessage = 'Unknown status.'
@@ -403,7 +436,7 @@ def add_remark(request, arxiv_identifier_w_vn_nr):
         messages.success(request, 'Your remark has succesfully been posted')
     else:
         messages.warning(request, 'The form was invalidly filled.')
-    return redirect(reverse('submissions:pool'))
+    return redirect(reverse('submissions:pool', args=(arxiv_identifier_w_vn_nr,)))
 
 
 @login_required
@@ -448,56 +481,76 @@ def assign_submission_ack(request, arxiv_identifier_w_vn_nr):
 @login_required
 @permission_required('scipost.can_take_charge_of_submissions', raise_exception=True)
 @transaction.atomic
-def accept_or_decline_assignment_ack(request, assignment_id):
-    contributor = Contributor.objects.get(user=request.user)
-    assignment = get_object_or_404(EditorialAssignment, pk=assignment_id)
+def assignment_request(request, assignment_id):
+    """
+    Process EditorialAssignment acceptance/denial form or show if not submitted.
+    """
+    assignment = get_object_or_404(EditorialAssignment.objects.open(),
+                                   to=request.user.contributor, pk=assignment_id)
+
     errormessage = None
     if assignment.submission.status == 'assignment_failed':
         errormessage = 'This Submission has failed pre-screening and has been rejected.'
-        context = {'errormessage': errormessage}
-        return render(request, 'submissions/accept_or_decline_assignment_ack.html', context)
-    if assignment.submission.editor_in_charge:
+
+    elif assignment.submission.editor_in_charge:
         errormessage = (assignment.submission.editor_in_charge.get_title_display() + ' ' +
                         assignment.submission.editor_in_charge.user.last_name +
                         ' has already agreed to be Editor-in-charge of this Submission.')
-        context = {'errormessage': errormessage}
-        return render(request, 'submissions/accept_or_decline_assignment_ack.html', context)
-    if request.method == 'POST':
-        form = ConsiderAssignmentForm(request.POST)
-        if form.is_valid():
-            assignment.date_answered = timezone.now()
-            if form.cleaned_data['accept'] == 'True':
-                assignment.accepted = True
-                assignment.to = contributor
-                assignment.submission.status = 'EICassigned'
-                assignment.submission.editor_in_charge = contributor
-                assignment.submission.open_for_reporting = True
-                deadline = timezone.now() + datetime.timedelta(days=28)  # for papers
-                if assignment.submission.submitted_to_journal == 'SciPost Physics Lecture Notes':
-                    deadline += datetime.timedelta(days=28)
-                assignment.submission.reporting_deadline = deadline
-                assignment.submission.open_for_commenting = True
-                assignment.submission.latest_activity = timezone.now()
-
-                SubmissionUtils.load({'assignment': assignment})
-                SubmissionUtils.deprecate_other_assignments()
-                assign_perm('can_take_editorial_actions', contributor.user, assignment.submission)
-                ed_admins = Group.objects.get(name='Editorial Administrators')
-                assign_perm('can_take_editorial_actions', ed_admins, assignment.submission)
-                SubmissionUtils.send_EIC_appointment_email()
-                SubmissionUtils.send_author_prescreening_passed_email()
-
-                # Add SubmissionEvents
-                assignment.submission.add_general_event('The Editor-in-charge has been assigned.')
-            else:
-                assignment.accepted = False
-                assignment.refusal_reason = form.cleaned_data['refusal_reason']
-                assignment.submission.status = 'unassigned'
-            assignment.save()
-            assignment.submission.save()
-
-    context = {'assignment': assignment}
-    return render(request, 'submissions/accept_or_decline_assignment_ack.html', context)
+
+    if errormessage:
+        # Assignments can get stuck here,
+        # if errormessage is given the contributor can't close the assignment!!
+        messages.warning(request, errormessage)
+        return redirect(reverse('submissions:pool'))
+
+    form = ConsiderAssignmentForm(request.POST or None)
+    if form.is_valid():
+        assignment.date_answered = timezone.now()
+        if form.cleaned_data['accept'] == 'True':
+            assignment.accepted = True
+            assignment.to = request.user.contributor
+            assignment.submission.status = 'EICassigned'
+            assignment.submission.editor_in_charge = request.user.contributor
+            assignment.submission.open_for_reporting = True
+            deadline = timezone.now() + datetime.timedelta(days=28)  # for papers
+            if assignment.submission.submitted_to_journal == 'SciPost Physics Lecture Notes':
+                deadline += datetime.timedelta(days=28)
+            assignment.submission.reporting_deadline = deadline
+            assignment.submission.open_for_commenting = True
+            assignment.submission.latest_activity = timezone.now()
+
+            SubmissionUtils.load({'assignment': assignment})
+            SubmissionUtils.deprecate_other_assignments()
+            assign_perm('can_take_editorial_actions', request.user, assignment.submission)
+            ed_admins = Group.objects.get(name='Editorial Administrators')
+            assign_perm('can_take_editorial_actions', ed_admins, assignment.submission)
+            SubmissionUtils.send_EIC_appointment_email()
+            SubmissionUtils.send_author_prescreening_passed_email()
+
+            # Add SubmissionEvents
+            assignment.submission.add_general_event('The Editor-in-charge has been assigned.')
+            msg = 'Thank you for becoming Editor-in-charge of this submission.'
+            url = reverse('submissions:editorial_page',
+                          args=(assignment.submission.arxiv_identifier_w_vn_nr,))
+        else:
+            assignment.accepted = False
+            assignment.refusal_reason = form.cleaned_data['refusal_reason']
+            assignment.submission.status = 'unassigned'
+            msg = 'Thank you for considering'
+            url = reverse('submissions:pool')
+        # Save assignment and submission
+        assignment.save()
+        assignment.submission.save()
+
+        # Form submitted, redirect user
+        messages.success(request, msg)
+        return redirect(url)
+
+    context = {
+        'assignment': assignment,
+        'form': form
+    }
+    return render(request, 'submissions/pool/assignment_request.html', context)
 
 
 @login_required
@@ -506,7 +559,7 @@ def accept_or_decline_assignment_ack(request, assignment_id):
 def volunteer_as_EIC(request, arxiv_identifier_w_vn_nr):
     """
     Called when a Fellow volunteers while perusing the submissions pool.
-    This is an adapted version of the accept_or_decline_assignment_ack method.
+    This is an adapted version of the assignment_request method.
     """
     submission = get_object_or_404(Submission.objects.get_pool(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
@@ -1071,6 +1124,16 @@ def eic_recommendation(request, arxiv_identifier_w_vn_nr):
         return redirect(reverse('submissions:editorial_page',
                                 args=[submission.arxiv_identifier_w_vn_nr]))
 
+    # Find EditorialAssignment for user
+    try:
+        assignment = submission.editorial_assignments.get(submission=submission,
+                                                          to=request.user.contributor)
+    except EditorialAssignment.DoesNotExist:
+        messages.warning(request, ('You cannot formulate an Editorial Recommendation,'
+                                   ' because you are not assigned as editor-in-charge.'))
+        return redirect(reverse('submissions:editorial_page',
+                                args=[submission.arxiv_identifier_w_vn_nr]))
+
     form = EICRecommendationForm(request.POST or None)
     if form.is_valid():
         # Create new EICRecommendation
@@ -1107,8 +1170,6 @@ def eic_recommendation(request, arxiv_identifier_w_vn_nr):
         submission.save()
 
         # The EIC has fulfilled this editorial assignment.
-        assignment = get_object_or_404(EditorialAssignment,
-                                       submission=submission, to=request.user.contributor)
         assignment.completed = True
         assignment.save()
         messages.success(request, 'Your Editorial Recommendation has been succesfully submitted')
@@ -1366,9 +1427,14 @@ def vote_on_rec(request, rec_id):
                             remark=form.cleaned_data['remark'])
             remark.save()
         recommendation.save()
+        messages.success(request, 'Thank you for your vote.')
         return redirect(reverse('submissions:pool'))
 
-    return redirect(reverse('submissions:pool'))
+    context = {
+        'recommendation': recommendation,
+        'form': form
+    }
+    return render(request, 'submissions/pool/recommendation.html', context)
 
 
 @permission_required('scipost.can_prepare_recommendations_for_voting', raise_exception=True)
@@ -1423,6 +1489,9 @@ def fix_College_decision(request, rec_id):
         # Create a ProductionStream object
         prodstream = ProductionStream(submission=submission)
         prodstream.save()
+        ed_admins = Group.objects.get(name='Editorial Administrators')
+        assign_perm('can_perform_supervisory_actions', ed_admins, prodstream)
+        assign_perm('can_work_for_stream', ed_admins, prodstream)
 
         # Add SubmissionEvent for authors
         # Do not write a new event for minor/major modification: already done at moment of
@@ -1478,16 +1547,30 @@ class EditorialSummaryView(SubmissionAdminViewMixin, ListView):
         context = super().get_context_data(*args, **kwargs)
 
         # Pick submission from `submission_list` to include proper filters such as author filters.
-        try:
-            arxiv_id = self.request.GET.get('submission')
-            assert arxiv_id
-            context['submission'] = (context['submission_list']
-                                     .get(arxiv_identifier_w_vn_nr=arxiv_id))
-        except (AssertionError, Submission.DoesNotExist):
-            context['submission'] = None
+        if self.kwargs.get('arxiv_identifier_w_vn_nr'):
+            try:
+                context['submission'] = context['submission_list'].get(
+                    arxiv_identifier_w_vn_nr=self.kwargs['arxiv_identifier_w_vn_nr'])
+            except Submission.DoesNotExist:
+                context['submission'] = None
+
+        if not context.get('submission'):
             context['latest_events'] = SubmissionEvent.objects.for_eic().last_hours()
+
+        context['recommendations_undergoing_voting'] = (
+            EICRecommendation.objects.get_for_user_in_pool(self.request.user)
+            .filter(submission__status='put_to_EC_voting'))
+        context['recommendations_to_prepare_for_voting'] = (
+            EICRecommendation.objects.get_for_user_in_pool(self.request.user)
+            .filter(submission__status='voting_in_preparation'))
         return context
 
+    def get_template_names(self):
+        if self.request.GET.get('json'):
+            return ['partials/submissions/admin/submission_details.html']
+        else:
+            return ['submissions/admin/editorial_admin.html']
+
 
 class PlagiarismView(SubmissionAdminViewMixin, UpdateView):
     permission_required = 'scipost.can_do_plagiarism_checks'
@@ -1513,3 +1596,14 @@ class PlagiarismReportPDFView(SubmissionAdminViewMixin, SingleObjectMixin, Redir
         if not url:
             raise Http404
         return url
+
+
+class AdminRecommendationView(SubmissionAdminViewMixin, DetailView):
+    permission_required = 'scipost.can_fix_College_decision'
+    template_name = 'submissions/admin/recommendation.html'
+    editorial_page = True
+
+    def get_object(self):
+        """ Get the EICRecommendation as a submission-related instance. """
+        submission = super().get_object()
+        return submission.eicrecommendations.first()
diff --git a/theses/managers.py b/theses/managers.py
index 4d2b06986cce30276d4753244d0fb149061f08b6..532868fe98d8a5da4ae06189320b3da18db7736e 100644
--- a/theses/managers.py
+++ b/theses/managers.py
@@ -16,5 +16,8 @@ class ThesisLinkManager(models.Manager):
     def vetted(self):
         return self.filter(vetted=True)
 
+    def awaiting_vetting(self):
+        return self.filter(vetted=False)
+
     def open_for_commenting(self):
         return self.filter(open_for_commenting=True)
diff --git a/theses/migrations/0009_auto_20170925_2124.py b/theses/migrations/0009_auto_20170925_2124.py
new file mode 100644
index 0000000000000000000000000000000000000000..e921672ad57d7c04e01babef5401e0d8ed63f403
--- /dev/null
+++ b/theses/migrations/0009_auto_20170925_2124.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-09-25 19:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('theses', '0008_auto_20170909_1649'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='thesislink',
+            name='author_as_cont',
+            field=models.ManyToManyField(blank=True, related_name='theses', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='thesislink',
+            name='author_claims',
+            field=models.ManyToManyField(blank=True, related_name='claimed_theses', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='thesislink',
+            name='author_false_claims',
+            field=models.ManyToManyField(blank=True, related_name='false_claimed_theses', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='thesislink',
+            name='requested_by',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='requested_theses', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='thesislink',
+            name='supervisor_as_cont',
+            field=models.ManyToManyField(blank=True, related_name='supervised_theses', to='scipost.Contributor', verbose_name='supervisor(s)'),
+        ),
+    ]
diff --git a/theses/models.py b/theses/models.py
index ad143b5a72d9c5cfa1b4fff33fe4cdbfa0d0afca..a6c05936e7ac238d5cc3976e9aa2c3e10092ab69 100644
--- a/theses/models.py
+++ b/theses/models.py
@@ -14,7 +14,7 @@ class ThesisLink(models.Model):
     """ An URL pointing to a thesis """
     requested_by = models.ForeignKey(
         'scipost.Contributor', blank=True, null=True,
-        related_name='thesislink_requested_by',
+        related_name='requested_theses',
         on_delete=models.CASCADE)
     vetted = models.BooleanField(default=False)
     vetted_by = models.ForeignKey(
@@ -37,18 +37,18 @@ class ThesisLink(models.Model):
     author = models.CharField(max_length=1000)
     author_as_cont = models.ManyToManyField(
         'scipost.Contributor', blank=True,
-        related_name='author_cont')
+        related_name='theses')
     author_claims = models.ManyToManyField(
         'scipost.Contributor', blank=True,
-        related_name='authors_thesis_claims')
+        related_name='claimed_theses')
     author_false_claims = models.ManyToManyField(
         'scipost.Contributor', blank=True,
-        related_name='authors_thesis_false_claims')
+        related_name='false_claimed_theses')
     supervisor = models.CharField(max_length=1000)
     supervisor_as_cont = models.ManyToManyField(
         'scipost.Contributor', blank=True,
         verbose_name='supervisor(s)',
-        related_name='supervisor_cont')
+        related_name='supervised_theses')
     institution = models.CharField(
         max_length=300,
         verbose_name='degree granting institution')