From 28d88c9b5c6eef0859a3aff0f55d4cc7055544b1 Mon Sep 17 00:00:00 2001
From: Jorran de Wit <jorrandewit@outlook.com>
Date: Sun, 6 May 2018 00:31:40 +0200
Subject: [PATCH] XL Project, step 4.

---
 .../commands/add_groups_and_permissions.py    |   8 +-
 .../static/scipost/assets/css/_tables.scss    |   8 +-
 submissions/forms.py                          | 123 ++++++++++++------
 submissions/managers.py                       |  45 ++-----
 submissions/models.py                         |  11 +-
 .../submissions/pool/referee_invitations.html |   2 +-
 .../pool/referee_invitations_status.html      |  38 +++---
 .../admin/submission_prescreening.html        |  55 ++++++++
 .../submissions/pool/editorial_page.html      |  51 +++++++-
 .../templates/submissions/pool/pool.html      |  22 +++-
 submissions/urls.py                           |   5 +-
 submissions/views.py                          | 111 ++++------------
 12 files changed, 271 insertions(+), 208 deletions(-)
 create mode 100644 submissions/templates/submissions/admin/submission_prescreening.html

diff --git a/scipost/management/commands/add_groups_and_permissions.py b/scipost/management/commands/add_groups_and_permissions.py
index d8da56200..6e060bd60 100644
--- a/scipost/management/commands/add_groups_and_permissions.py
+++ b/scipost/management/commands/add_groups_and_permissions.py
@@ -17,7 +17,6 @@ class Command(BaseCommand):
 
     def handle(self, *args, verbose=True, **options):
         """Append all user Groups and setup a Contributor roles to user."""
-
         # Create Groups
         SciPostAdmin, created = Group.objects.get_or_create(name='SciPost Administrators')
         FinancialAdmin, created = Group.objects.get_or_create(name='Financial Administrators')
@@ -40,8 +39,6 @@ class Command(BaseCommand):
 
         # Create Permissions
         content_type = ContentType.objects.get_for_model(Contributor)
-        content_type_contact = ContentType.objects.get_for_model(Contact)
-        content_type_draft_invitation = ContentType.objects.get_for_model(DraftInvitation)
 
         # Supporting Partners
         can_manage_SPB, created = Permission.objects.get_or_create(
@@ -188,6 +185,10 @@ class Command(BaseCommand):
             codename='can_oversee_refereeing',
             name='Can oversee refereeing',
             content_type=content_type)
+        can_run_pre_screening, created = Permission.objects.get_or_create(
+            codename='can_run_pre_screening',
+            name='Can run pre-screening on Submissions',
+            content_type=content_type)
 
         # Reports
         can_manage_reports, created = Permission.objects.get_or_create(
@@ -331,6 +332,7 @@ class Command(BaseCommand):
             can_assign_submissions,
             can_do_plagiarism_checks,
             can_oversee_refereeing,
+            can_run_pre_screening,
             can_prepare_recommendations_for_voting,
             can_manage_college_composition,
             can_fix_College_decision,
diff --git a/scipost/static/scipost/assets/css/_tables.scss b/scipost/static/scipost/assets/css/_tables.scss
index 8e01f59c4..175b068a1 100644
--- a/scipost/static/scipost/assets/css/_tables.scss
+++ b/scipost/static/scipost/assets/css/_tables.scss
@@ -1,7 +1,9 @@
 .table {
-    th,
-    td {
-        vertical-align: middle;
+    &.v-center {
+        th,
+        td {
+            vertical-align: middle;
+        }
     }
 
     td {
diff --git a/submissions/forms.py b/submissions/forms.py
index 1037e388c..3032ccba3 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -13,10 +13,11 @@ from django.utils import timezone
 from .constants import (
     ASSIGNMENT_BOOL, ASSIGNMENT_REFUSAL_REASONS, STATUS_RESUBMITTED, REPORT_ACTION_CHOICES,
     REPORT_REFUSAL_CHOICES, STATUS_REJECTED, STATUS_INCOMING, REPORT_POST_EDREC, REPORT_NORMAL,
-    STATUS_DRAFT, STATUS_UNVETTED, REPORT_ACTION_ACCEPT, REPORT_ACTION_REFUSE, STATUS_VETTED,
+    STATUS_DRAFT, STATUS_UNVETTED, REPORT_ACTION_ACCEPT, REPORT_ACTION_REFUSE, STATUS_UNASSIGNED,
     EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS, SUBMISSION_STATUS, PUT_TO_VOTING, CYCLE_UNDETERMINED,
-    SUBMISSION_CYCLE_CHOICES, REPORT_PUBLISH_1, REPORT_PUBLISH_2, REPORT_PUBLISH_3,
-    REPORT_MINOR_REV, REPORT_MAJOR_REV, REPORT_REJECT, STATUS_ACCEPTED, DECISION_FIXED, DEPRECATED)
+    SUBMISSION_CYCLE_CHOICES, REPORT_PUBLISH_1, REPORT_PUBLISH_2, REPORT_PUBLISH_3, STATUS_VETTED,
+    REPORT_MINOR_REV, REPORT_MAJOR_REV, REPORT_REJECT, STATUS_ACCEPTED, DECISION_FIXED, DEPRECATED,
+    STATUS_EIC_ASSIGNED)
 from . import exceptions, helpers
 from .models import (
     Submission, RefereeInvitation, Report, EICRecommendation, EditorialAssignment,
@@ -65,7 +66,7 @@ class SubmissionPoolFilterForm(forms.Form):
     def search(self, queryset, current_user):
         if self.cleaned_data.get('status'):
             # Do extra check on non-required field to never show errors on template
-            queryset = queryset.pool_full(current_user).filter(status=self.cleaned_data['status'])
+            queryset = queryset.pool_editable(current_user).filter(status=self.cleaned_data['status'])
         else:
             # If no specific status if requested, just return the Pool by default
             queryset = queryset.pool(current_user)
@@ -374,8 +375,9 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
             open_for_reporting=True,
             open_for_commenting=True,
             is_resubmission=True,
+            visible_pool=True,
             editor_in_charge=self.last_submission.editor_in_charge,
-            status=STATUS_INCOMING)
+            status=STATUS_EIC_ASSIGNED)
 
         # Add author(s) (claim) fields
         submission.authors.add(*self.last_submission.authors.all())
@@ -445,6 +447,36 @@ class SubmissionReportsForm(forms.ModelForm):
         fields = ['pdf_refereeing_pack']
 
 
+class SubmissionPrescreeningForm(forms.ModelForm):
+    """Processing decision for pre-screening of Submission."""
+
+    PASS = 'pass'
+    CHOICES = ((PASS, 'Pass pre-screening. Proceed to the Pool.'),)
+    decision = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES, required=False)
+
+    class Meta:
+        model = Submission
+        fields = ()
+
+    def __init__(self, *args, **kwargs):
+        """Add related submission as argument."""
+        self.submission = kwargs.pop('submission')
+        super().__init__(*args, **kwargs)
+
+    def clean(self):
+        """Check if Submission has right status."""
+        data = super().clean()
+        if self.instance.status != STATUS_INCOMING:
+            self.add_error(None, 'This Submission is currently not in pre-screening.')
+        return data
+
+    @transaction.atomic
+    def save(self):
+        """Update Submission status."""
+        Submission.objects.filter(id=self.instance.id).update(
+            status=STATUS_UNASSIGNED, visible_pool=True)
+
+
 ######################
 # Editorial workflow #
 ######################
@@ -617,7 +649,7 @@ class ReportForm(forms.ModelForm):
 
         self.submission = kwargs.pop('submission')
 
-        super(ReportForm, self).__init__(*args, **kwargs)
+        super().__init__(*args, **kwargs)
         self.fields['strengths'].widget.attrs.update({
             'placeholder': ('Give a point-by-point '
                             '(numbered 1-, 2-, ...) list of the paper\'s strengths'),
@@ -758,6 +790,8 @@ class EditorialCommunicationForm(forms.ModelForm):
 ######################
 
 class EICRecommendationForm(forms.ModelForm):
+    """Formulate an EICRecommendation."""
+
     DAYS_TO_VOTE = 7
     assignment = None
     earlier_recommendations = None
@@ -786,7 +820,7 @@ class EICRecommendationForm(forms.ModelForm):
         }
 
     def __init__(self, *args, **kwargs):
-        """EICRecommendation accepts two additional kwargs.
+        """Accept two additional kwargs.
 
         -- submission: The Submission to formulate an EICRecommendation for.
         -- reformulate (bool): Reformulate the currently available EICRecommendations.
@@ -808,7 +842,7 @@ class EICRecommendationForm(forms.ModelForm):
         super().__init__(*args, **kwargs)
         self.load_assignment()
 
-    def save(self, commit=True):
+    def save(self):
         recommendation = super().save(commit=False)
         recommendation.submission = self.submission
         recommendation.voting_deadline += datetime.timedelta(days=self.DAYS_TO_VOTE)  # Test this
@@ -819,39 +853,37 @@ class EICRecommendationForm(forms.ModelForm):
         else:
             event_text = 'An Editorial Recommendation has been formulated: {}.'
 
-        if recommendation.recommendation in [1, 2, 3, -3] and commit:
+        if recommendation.recommendation in [REPORT_MINOR_REV, REPORT_MAJOR_REV]:
+            # Minor/Major revision: return to Author; ask to resubmit
+            recommendation.status = DECISION_FIXED
+            Submission.objects.filter(id=self.submission.id).update(open_for_reporting=False)
+
+            # Add SubmissionEvents for both Author and EIC
+            self.submission.add_general_event(event_text.format(
+                recommendation.get_recommendation_display()))
+        else:
             # Add SubmissionEvent for EIC only
             self.submission.add_event_for_eic(event_text.format(
                 recommendation.get_recommendation_display()))
-        elif recommendation.recommendation in [-1, -2]:
-            # Minor/Major revision: return to Author; ask to resubmit
-            self.submission.open_for_reporting = False
 
-            if commit:
-                # Add SubmissionEvents for both Author and EIC
-                self.submission.add_general_event(event_text.format(
-                    recommendation.get_recommendation_display()))
-
-        if commit:
-            if self.earlier_recommendations:
-                self.earlier_recommendations.update(active=False, status=DEPRECATED)
+        if self.earlier_recommendations:
+            self.earlier_recommendations.update(active=False, status=DEPRECATED)
 
-                # All reports already submitted are now formulated *after* eic rec formulation
-                Report.objects.filter(
-                    submission__eicrecommendations__in=self.earlier_recommendations).update(
-                        report_type=REPORT_NORMAL)
+            # All reports already submitted are now formulated *after* eic rec formulation
+            Report.objects.filter(
+                submission__eicrecommendations__in=self.earlier_recommendations).update(
+                    report_type=REPORT_NORMAL)
 
-            recommendation.save()
-            self.submission.save()
+        recommendation.save()
 
-            if self.assignment:
-                # The EIC has fulfilled this editorial assignment.
-                self.assignment.completed = True
-                self.assignment.save()
+        if self.assignment:
+            # The EIC has fulfilled this editorial assignment.
+            self.assignment.completed = True
+            self.assignment.save()
         return recommendation
 
     def revision_requested(self):
-        return self.instance.recommendation in [-1, -2]
+        return self.instance.recommendation in [REPORT_MINOR_REV, REPORT_MAJOR_REV]
 
     def has_assignment(self):
         return self.assignment is not None
@@ -866,6 +898,7 @@ class EICRecommendationForm(forms.ModelForm):
             return False
 
     def load_earlier_recommendations(self):
+        """Load and save EICRecommendations related to Submission of the instance."""
         self.earlier_recommendations = self.submission.eicrecommendations.all()
 
 
@@ -874,21 +907,21 @@ class EICRecommendationForm(forms.ModelForm):
 ###############
 
 class RecommendationVoteForm(forms.Form):
-    vote = forms.ChoiceField(widget=forms.RadioSelect,
-                             choices=[('agree', 'Agree'),
-                                      ('disagree', 'Disagree'),
-                                      ('abstain', 'Abstain')],
-                             label='',
-                             )
-    remark = forms.CharField(widget=forms.Textarea(), label='', required=False)
+    """Cast vote on EICRecommendation form."""
 
-    def __init__(self, *args, **kwargs):
-        super(RecommendationVoteForm, self).__init__(*args, **kwargs)
-        self.fields['remark'].widget.attrs.update(
-            {'rows': 3, 'cols': 30, 'placeholder': 'Your remarks (optional)'})
+    vote = forms.ChoiceField(
+        widget=forms.RadioSelect, choices=[
+            ('agree', 'Agree'), ('disagree', 'Disagree'), ('abstain', 'Abstain')], label='')
+    remark = forms.CharField(widget=forms.Textarea(attrs={
+        'rows': 3,
+        'cols': 30,
+        'placeholder': 'Your remarks (optional)'
+    }), label='', required=False)
 
 
 class SubmissionCycleChoiceForm(forms.ModelForm):
+    """Make a decision on the Submission's cycle and make publicly available."""
+
     referees_reinvite = forms.ModelMultipleChoiceField(
         queryset=RefereeInvitation.objects.none(),
         widget=forms.CheckboxSelectMultiple({'checked': 'checked'}),
@@ -900,6 +933,7 @@ class SubmissionCycleChoiceForm(forms.ModelForm):
         widgets = {'refereeing_cycle': forms.RadioSelect}
 
     def __init__(self, *args, **kwargs):
+        """Update choices and queryset."""
         super().__init__(*args, **kwargs)
         self.fields['refereeing_cycle'].choices = SUBMISSION_CYCLE_CHOICES
         other_submissions = self.instance.other_versions.all()
@@ -907,6 +941,11 @@ class SubmissionCycleChoiceForm(forms.ModelForm):
             self.fields['referees_reinvite'].queryset = RefereeInvitation.objects.filter(
                 submission__in=other_submissions).distinct()
 
+    def save(self):
+        """Make Submission publicly available after decision."""
+        self.instance.visible_public = True
+        return super().save()
+
 
 class iThenticateReportForm(forms.ModelForm):
     class Meta:
diff --git a/submissions/managers.py b/submissions/managers.py
index d244fc2b6..b652be402 100644
--- a/submissions/managers.py
+++ b/submissions/managers.py
@@ -68,13 +68,10 @@ class SubmissionQuerySet(models.QuerySet):
 
     def pool(self, user):
         """Return the user-dependent pool of Submissions in active referee phase."""
-        qs = self._pool(user)
-        qs = qs.filter(is_current=True, status__in=[
+        return self.pool_editable(user).filter(is_current=True, status__in=[
             constants.STATUS_UNASSIGNED,
             constants.STATUS_EIC_ASSIGNED,
-            constants.STATUS_ACCEPTED,
-        ])
-        return qs
+            constants.STATUS_ACCEPTED])
 
     def pool_editable(self, user):
         """Return the editable pool for a certain user.
@@ -84,31 +81,7 @@ class SubmissionQuerySet(models.QuerySet):
         the Editor-in-charge.
         """
         qs = self._pool(user)
-        qs = qs.filter(status__in=[
-            constants.STATUS_INCOMING,
-            constants.STATUS_UNASSIGNED,
-            constants.STATUS_EIC_ASSIGNED,
-            constants.STATUS_ACCEPTED,
-            constants.STATUS_PUBLISHED,
-            #
-            # constants.STATUS_INCOMING,
-            # constants.STATUS_ASSIGNMENT_FAILED,
-            # constants.STATUS_REJECTED,
-            # constants.STATUS_WITHDRAWN,
-            # constants.STATUS_PUBLISHED,
-        ])
-        return qs
-
-    def pool_full(self, user):
-        """Return the *FULL* user-dependent Submission pool.
-
-        This makes sure the user can see all history of Submissions related to its Fellowship(s).
-
-        Do not use this filter by default however, as this also contains Submissions
-        that are for example either rejected or accepted already and thus "inactive."
-        """
-        qs = self._pool(user)
-        return qs
+        return qs.filter(visible_pool=True)
 
     def filter_for_eic(self, user):
         """Return the set of Submissions the user is Editor-in-charge for.
@@ -117,8 +90,8 @@ class SubmissionQuerySet(models.QuerySet):
         """
         qs = self._pool(user)
 
-        if not user.has_perm('scipost.can_oversee_refereeing') and hasattr(user, 'contributor'):
-            qs = qs.filter(editor_in_charge=user.contributor)
+        if not user.has_perm('scipost.can_oversee_refereeing'):
+            qs = qs.filter(editor_in_charge__user=user)
         return qs
 
     def filter_for_author(self, user):
@@ -188,7 +161,8 @@ class SubmissionQuerySet(models.QuerySet):
         """Return Submissions with a fixed EICRecommendation: minor or major revision."""
         return self.filter(
             eicrecommendations__status=constants.DECISION_FIXED,
-            eicrecommendations__recommendation__in=[-1, -2])
+            eicrecommendations__recommendation__in=[
+                constants.REPORT_MINOR_REV, constants.REPORT_MAJOR_REV])
 
     def published(self):
         """Return published Submissions."""
@@ -361,10 +335,7 @@ class RefereeInvitationQuerySet(models.QuerySet):
         return qs
 
     def overdue(self):
-        qs = self.in_process()
-        deadline = now
-        qs = qs.filter(submission__reporting_deadline__lte=deadline)
-        return qs
+        return self.in_process().filter(submission__reporting_deadline__lte=now)
 
 
 class EditorialCommunicationQueryset(models.QuerySet):
diff --git a/submissions/models.py b/submissions/models.py
index c941daa11..955f62210 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -17,7 +17,7 @@ from .behaviors import SubmissionRelatedObjectMixin
 from .constants import (
     ASSIGNMENT_REFUSAL_REASONS, ASSIGNMENT_NULLBOOL, SUBMISSION_TYPE,
     ED_COMM_CHOICES, REFEREE_QUALIFICATION, QUALITY_SPEC, RANKING_CHOICES, REPORT_REC,
-    SUBMISSION_STATUS, STATUS_UNASSIGNED, REPORT_STATUSES, STATUS_UNVETTED,
+    SUBMISSION_STATUS, REPORT_STATUSES, STATUS_UNVETTED, STATUS_INCOMING,
     SUBMISSION_CYCLES, CYCLE_DEFAULT, CYCLE_SHORT, STATUS_RESUBMITTED, DECISION_FIXED,
     CYCLE_DIRECT_REC, EVENT_GENERAL, EVENT_TYPES, EVENT_FOR_AUTHOR, EVENT_FOR_EIC, REPORT_TYPES,
     REPORT_NORMAL, STATUS_DRAFT, STATUS_VETTED, EIC_REC_STATUSES, VOTING_IN_PREP)
@@ -64,10 +64,10 @@ class Submission(models.Model):
         blank=True, null=True)
 
     # Submission status fields
-    status = models.CharField(max_length=30, choices=SUBMISSION_STATUS, default=STATUS_UNASSIGNED)
+    status = models.CharField(max_length=30, choices=SUBMISSION_STATUS, default=STATUS_INCOMING)
     is_current = models.BooleanField(default=True)
     visible_public = models.BooleanField("Is publicly visible", default=False)
-    visible_pool = models.BooleanField("Is visible in the Pool", default=True)
+    visible_pool = models.BooleanField("Is visible in the Pool", default=False)
     is_resubmission = models.BooleanField(default=False)
     refereeing_cycle = models.CharField(
         max_length=30, choices=SUBMISSION_CYCLES, default=CYCLE_DEFAULT, blank=True)
@@ -208,6 +208,11 @@ class Submission(models.Model):
         """Check if Submission has passed it's reporting deadline."""
         return timezone.now() > self.reporting_deadline
 
+    @property
+    def is_open_for_reporting(self):
+        """Check if Submission is open for reporting and within deadlines."""
+        return self.open_for_reporting and not self.reporting_deadline_has_passed
+
     @property
     def original_submission_date(self):
         """Return the submission_date of the first Submission in the thread."""
diff --git a/submissions/templates/partials/submissions/pool/referee_invitations.html b/submissions/templates/partials/submissions/pool/referee_invitations.html
index 8367c939a..0c56191df 100644
--- a/submissions/templates/partials/submissions/pool/referee_invitations.html
+++ b/submissions/templates/partials/submissions/pool/referee_invitations.html
@@ -1,4 +1,4 @@
-<table class="table bg-light table-hover">
+<table class="table bg-light table-hover v-center">
     <thead>
         <tr>
             <th>Referee</th>
diff --git a/submissions/templates/partials/submissions/pool/referee_invitations_status.html b/submissions/templates/partials/submissions/pool/referee_invitations_status.html
index 6d1099c8c..c7b8d4d44 100644
--- a/submissions/templates/partials/submissions/pool/referee_invitations_status.html
+++ b/submissions/templates/partials/submissions/pool/referee_invitations_status.html
@@ -1,20 +1,18 @@
-{% if submission.refereeing_cycle != 'direct_rec' %}
-    <div class="table-responsive-md">
-        <table class="table table-borderless">
-            <tbody>
-                <tr>
-                    <td>Nr referees invited:</td>
-                    <td>
-                        {{submission.referee_invitations.count}} <span>[{{submission.count_accepted_invitations}} acccepted / {{submission.count_declined_invitations}} declined / {{submission.count_pending_invitations}} response pending]</span>
-                    </td>
-                </tr>
-                <tr>
-                    <td>Nr reports obtained:</td>
-                    <td>
-                        {{submission.count_obtained_reports}} [{{submission.count_invited_reports}} invited / {{submission.count_contrib_reports}} contributed], nr refused: {{submission.reports.rejected.count}}, nr awaiting vetting: {{submission.reports.awaiting_vetting.count}}
-                    </td>
-                </tr>
-            </tbody>
-        </table>
-    </div>
-{% endif %}
+<div class="table-responsive-md">
+    <table class="table table-borderless">
+        <tbody>
+            <tr>
+                <td>Nr referees invited:</td>
+                <td>
+                    {{submission.referee_invitations.count}} <span>[{{submission.count_accepted_invitations}} acccepted / {{submission.count_declined_invitations}} declined / {{submission.count_pending_invitations}} response pending]</span>
+                </td>
+            </tr>
+            <tr>
+                <td>Nr reports obtained:</td>
+                <td>
+                    {{submission.count_obtained_reports}} [{{submission.count_invited_reports}} invited / {{submission.count_contrib_reports}} contributed], nr refused: {{submission.reports.rejected.count}}, nr awaiting vetting: {{submission.reports.awaiting_vetting.count}}
+                </td>
+            </tr>
+        </tbody>
+    </table>
+</div>
diff --git a/submissions/templates/submissions/admin/submission_prescreening.html b/submissions/templates/submissions/admin/submission_prescreening.html
new file mode 100644
index 000000000..4804eb79b
--- /dev/null
+++ b/submissions/templates/submissions/admin/submission_prescreening.html
@@ -0,0 +1,55 @@
+{% extends 'submissions/admin/base.html' %}
+
+{% load bootstrap %}
+
+{% block pagetitle %}: pre-screening ({{ submission.arxiv_identifier_w_vn_nr }}){% endblock pagetitle %}
+
+{% block breadcrumb_items %}
+    {{block.super}}
+    <span class="breadcrumb-item">Pre-screening {{ submission.arxiv_identifier_w_vn_nr }}</span>
+{% endblock %}
+
+{% block content %}
+    <h1 class="highlight">Pre-screening of Submission</h1>
+    <h3>Submission summary</h3>
+    {% include 'partials/submissions/submission_summary.html' with submission=submission hide_title=1 show_abstract=1 %}
+
+    <h3>Plagiarism report</h3>
+    {% if submission.plagiarism_report %}
+        <a href="{% url 'submissions:plagiarism' submission.arxiv_identifier_w_vn_nr %}">Update plagiarism report</a>
+        <br>
+        <table>
+            <tr>
+                <td style="min-width: 150px;">iThenticate document</td>
+                <td>{{submission.plagiarism_report.doc_id}}</td>
+            </tr>
+            <tr>
+                <td>Percent match</td>
+                <td>{{ submission.plagiarism_report.percent_match|default:'?' }}%</td>
+            </tr>
+            <tr>
+                <td>Processed</td>
+                <td>{{submission.plagiarism_report.processed_time}}</td>
+            </tr>
+            <tr>
+                <td>Uploaded</td>
+                <td>{{submission.plagiarism_report.uploaded_time}}</td>
+            </tr>
+            <tr>
+                <td>Latest update</td>
+                <td>{{submission.plagiarism_report.latest_activity}}</td>
+            </tr>
+        </table>
+        <br>
+    {% else %}
+        <p>No Plagiarism Report found. <a href="{% url 'submissions:plagiarism' submission.arxiv_identifier_w_vn_nr %}">Run plagiarism check</a>.</p>
+    {% endif %}
+
+    <h3>Take decision of pre-screening</h3>
+    <form method="post">
+        {% csrf_token %}
+        {{ form|bootstrap }}
+        <input type="submit" class="btn btn-primary" value="Submit">
+    </form>
+
+{% endblock content %}
diff --git a/submissions/templates/submissions/pool/editorial_page.html b/submissions/templates/submissions/pool/editorial_page.html
index 1e0ddf49e..0bf346ced 100644
--- a/submissions/templates/submissions/pool/editorial_page.html
+++ b/submissions/templates/submissions/pool/editorial_page.html
@@ -77,9 +77,10 @@
 
 <div class="row"><!-- Status -->
     <div class="col">
+        <h3>Editorial status:</h3>
         <table class="table table-borderless">
             <tr>
-                <td>Current status:</td>
+                <td>Submission status:</td>
                 <td><span class="label label-secondary">{{ submission.get_status_display }}</span></td>
             </tr>
             {% if submission.eicrecommendations.active.first %}
@@ -89,15 +90,27 @@
                 </tr>
             {% endif %}
             <tr>
-                <td>Cycle:</td>
+                <td>Refereeing cycle:</td>
                 <td>{{ submission.get_refereeing_cycle_display }}</td>
             </tr>
+            <tr>
+                <td>Publicly available:</td>
+                <td>
+                    {% if submission.visible_public %}
+                        <i class="fa fa-check-circle text-success" aria-hidden="true"></i>
+                        <span class="text-muted">Available in public pages and search results.</span>
+                    {% else %}
+                        <i class="fa fa-times-circle text-danger" aria-hidden="true"></i>
+                        <span class="text-muted">Only available for editors and authors.</span>
+                    {% endif %}
+                </td>
+            </tr>
             <tr>
                 <td>Plagiarism report:</td>
                 <td>
                     {% if submission.plagiarism_report %}
                         {% if submission.plagiarism_report.percent_match %}
-                            <b>{{submission.plagiarism_report.percent_match}}%</b>
+                            <b>{{ submission.plagiarism_report.percent_match }}%</b>
                         {% else %}
                             <em>Scan in progress</em>
                             {% if perms.scipost.can_do_plagiarism_checks %}
@@ -114,10 +127,38 @@
                     {% endif %}
                 </td>
             </tr>
+            <tr>
+                <td>Open for commenting:</td>
+                <td>
+                    {% if submission.open_for_commenting %}
+                        <i class="fa fa-check-circle text-success" aria-hidden="true"></i>
+                        <span class="text-muted">Open for commenting.</span>
+                    {% else %}
+                        <i class="fa fa-times-circle text-danger" aria-hidden="true"></i>
+                        <span class="text-muted">Commenting closed.</span>
+                    {% endif %}
+                </td>
+            </tr>
+            <tr>
+                <td>Open for refereeing:</td>
+                <td>
+                    {% if submission.is_open_for_reporting %}
+                        <i class="fa fa-check-circle text-success" aria-hidden="true"></i>
+                        <span class="text-muted">Open for refereeing. Deadline: {{ submission.reporting_deadline|date:"SHORT_DATE_FORMAT" }}</span>
+                    {% else %}
+                        <i class="fa fa-times-circle text-danger" aria-hidden="true"></i>
+                        <span class="text-muted">
+                            Refereeing closed.
+                            <br>
+                            <em>Invitated referees may still submit a Report, as long as their invitation is not finished nor cancelled.</em>
+                        </span>
+                    {% endif %}
+                </td>
+            </tr>
         </table>
     </div>
     {% if full_access %}
-        <div class="col-12 col-lg-6">
+        <div class="col-12">
             {% include 'partials/submissions/pool/required_actions_block.html' with submission=submission %}
         </div>
     {% endif %}
@@ -234,7 +275,7 @@
                                 {% endif %}
                             {% endwith %}
 
-                            {% if not submission.reporting_deadline_has_passed %}
+                            {% if submission.is_open_for_reporting %}
                                 <li><a href="{% url 'submissions:close_refereeing_round' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Close the refereeing round</a> &nbsp;(deactivates submission of new Reports and Comments)</li>
                             {% endif %}
                         {% endif %}
diff --git a/submissions/templates/submissions/pool/pool.html b/submissions/templates/submissions/pool/pool.html
index 92ae237be..92af9fba5 100644
--- a/submissions/templates/submissions/pool/pool.html
+++ b/submissions/templates/submissions/pool/pool.html
@@ -30,11 +30,24 @@
                     <div class="quote-border">
                         <h2 class="text-primary">Administrative Tasks</h2>
 
+                        {% if pre_screening_subs %}
+                            <h3>Submissions in pre-screening phase <i class="fa fa-exclamation-circle text-warning"></i></h3>
+                            <ul>
+                                {% for submission in pre_screening_subs %}
+                                    <li>
+                                        {{ submission }}<br>
+                                        <a href="{% url 'submissions:do_prescreening' submission.arxiv_identifier_w_vn_nr %}">Do pre-screening</a>
+                                    </li>
+                                {% endfor %}
+                            </ul>
+                        {% endif %}
+
                         {% if recommendations.voting_in_preparation %}
                             <h3>Recommendations to prepare for voting <i class="fa fa-exclamation-circle text-warning"></i></h3>
                             <ul>
                                 {% for recommendation in recommendations.voting_in_preparation %}
-                                    <li>On Editorial Recommendation: {{ recommendation }}<br>
+                                    <li>
+                                        On Editorial Recommendation: {{ recommendation }}<br>
                                         <a href="{% url 'submissions:prepare_for_voting' rec_id=recommendation.id %}">Prepare for voting</a>
                                     </li>
                                 {% endfor %}
@@ -45,7 +58,8 @@
                             <h3>Recommendations undergoing voting <i class="fa fa-exclamation-circle text-warning"></i></h3>
                             <ul class="fa-ul">
                                 {% for recommendation in recommendations.put_to_voting %}
-                                    <li>{% include 'partials/submissions/admin/recommendation_tooltip.html' with classes='fa-li' recommendation=recommendation %}
+                                    <li>
+                                        {% include 'partials/submissions/admin/recommendation_tooltip.html' with classes='fa-li' recommendation=recommendation %}
                                         On Editorial Recommendation: {{ recommendation }}<br>
                                         <a href="{% url 'submissions:eic_recommendation_detail' recommendation.submission.arxiv_identifier_w_vn_nr recommendation.id %}">See Editorial Recommendation</a>
                                     </li>
@@ -99,8 +113,8 @@
                 <h3>All Submissions with status: <span class="text-primary">{{ search_form.status_verbose }}</span></h3>
                 {% include 'partials/submissions/pool/submissions_list.html' with submissions=submissions %}
             {% else %}
-                <h3>Submissions currently in pre-screening</h3>
-                {% include 'partials/submissions/pool/submissions_list.html' with submissions=submissions.prescreening %}
+                <h3>Submissions currently unassigned</h3>
+                {% include 'partials/submissions/pool/submissions_list.html' with submissions=submissions.unassigned %}
 
                 <h3>Submissions currently in active refereeing phase</h3>
                 {% include 'partials/submissions/pool/submissions_list.html' with submissions=submissions.actively_refereeing %}
diff --git a/submissions/urls.py b/submissions/urls.py
index 1bc133482..ace829f43 100644
--- a/submissions/urls.py
+++ b/submissions/urls.py
@@ -33,6 +33,8 @@ urlpatterns = [
 
     # Editorial Administration
     url(r'^admin/treated$', views.treated_submissions_list, name='treated_submissions_list'),
+    url(r'^admin/{regex}/prescreening$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
+        views.PreScreeningView.as_view(), name='do_prescreening'),
     url(r'^admin/{regex}/reports/compile$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
         views.treated_submission_pdf_compile, name='treated_submission_pdf_compile'),
     url(r'^admin/{regex}/plagiarism$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
@@ -122,7 +124,4 @@ urlpatterns = [
     url(r'^vote_on_rec/(?P<rec_id>[0-9]+)$', views.vote_on_rec, name='vote_on_rec'),
     url(r'^remind_Fellows_to_vote$', views.remind_Fellows_to_vote,
         name='remind_Fellows_to_vote'),
-    # Editorial Administration
-    url(r'fix_College_decision/(?P<rec_id>[0-9]+)$', views.fix_College_decision,
-        name='fix_College_decision'),
 ]
diff --git a/submissions/views.py b/submissions/views.py
index 6f789246c..a1c69ff7d 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -8,7 +8,6 @@ import strings
 
 from django.contrib import messages
 from django.contrib.auth.decorators import login_required, permission_required
-from django.contrib.auth.models import Group
 from django.core.exceptions import PermissionDenied
 from django.core.urlresolvers import reverse, reverse_lazy
 from django.db import transaction, IntegrityError
@@ -22,11 +21,9 @@ from django.views.generic.detail import SingleObjectMixin
 from django.views.generic.edit import CreateView, UpdateView
 from django.views.generic.list import ListView
 
-from guardian.shortcuts import assign_perm
-
 from .constants import (
     STATUS_VETTED, STATUS_EIC_ASSIGNED, SUBMISSION_STATUS, STATUS_ASSIGNMENT_FAILED,
-    STATUS_DRAFT, CYCLE_DIRECT_REC, STATUS_REJECTED, STATUS_ACCEPTED)
+    STATUS_DRAFT, CYCLE_DIRECT_REC)
 from .models import (
     Submission, EICRecommendation, EditorialAssignment, RefereeInvitation, Report, SubmissionEvent)
 from .mixins import SubmissionAdminViewMixin
@@ -36,8 +33,7 @@ from .forms import (
     RefereeRecruitmentForm, ConsiderRefereeInvitationForm, EditorialCommunicationForm,
     EICRecommendationForm, ReportForm, VetReportForm, VotingEligibilityForm,
     SubmissionCycleChoiceForm, ReportPDFForm, SubmissionReportsForm, iThenticateReportForm,
-    SubmissionPoolFilterForm, FixCollegeDecisionForm)
-from .signals import notify_manuscript_accepted
+    SubmissionPoolFilterForm, FixCollegeDecisionForm, SubmissionPrescreeningForm)
 from .utils import SubmissionUtils
 
 from colleges.permissions import fellowship_required, fellowship_or_admin_required
@@ -45,7 +41,6 @@ from comments.forms import CommentForm
 from journals.models import Journal
 from mails.views import MailEditingSubView
 from production.forms import ProofsDecisionForm
-from production.models import ProductionStream
 from scipost.forms import RemarkForm
 from scipost.mixins import PaginationMixin
 from scipost.models import Contributor, Remark
@@ -406,7 +401,7 @@ def pool(request, arxiv_identifier_w_vn_nr=None):
     context['submission'] = None
     if arxiv_identifier_w_vn_nr:
         try:
-            context['submission'] = Submission.objects.pool_full(request.user).get(
+            context['submission'] = Submission.objects.pool_editable(request.user).get(
                 arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
         except Submission.DoesNotExist:
             pass
@@ -416,6 +411,9 @@ def pool(request, arxiv_identifier_w_vn_nr=None):
         context['latest_submission_events'] = SubmissionEvent.objects.for_eic().last_hours()\
             .filter(submission__in=context['submissions'])
 
+    if request.user.has_perm('scipost.can_run_pre_screening'):
+        context['pre_screening_subs'] = Submission.objects.prescreening()
+
     # Pool gets Submission details via ajax request
     if context['submission'] and request.is_ajax():
         template = 'partials/submissions/pool/submission_details.html'
@@ -644,7 +642,8 @@ def assignment_failed(request, arxiv_identifier_w_vn_nr):
 
         # Update status of Submission
         submission.touch()
-        Submission.objects.filter(id=submission.id).update(status=STATUS_ASSIGNMENT_FAILED)
+        Submission.objects.filter(id=submission.id).update(
+            status=STATUS_ASSIGNMENT_FAILED, visible_pool=False, visible_public=False)
 
         messages.success(
             request, 'Submission {arxiv} has failed pre-screening and been rejected.'.format(
@@ -684,7 +683,7 @@ def editorial_page(request, arxiv_identifier_w_vn_nr):
     The central page for the Editor-in-charge to manage all its Editorial duties. It's accessible
     for both the Editor-in-charge of the Submission and the Editorial Administration.
     """
-    submission = get_object_or_404(Submission.objects.pool_full(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
 
     full_access = True
@@ -1043,9 +1042,7 @@ def extend_refereeing_deadline(request, arxiv_identifier_w_vn_nr, days):
 
 @login_required
 def set_refereeing_deadline(request, arxiv_identifier_w_vn_nr):
-    """
-    Set Refereeing deadline for Submission and open reporting and commenting if
-    the new date is in the future.
+    """Set Refereeing deadline for Submission and open reporting and commenting.
 
     Accessible for: Editor-in-charge and Editorial Administration
     """
@@ -1058,8 +1055,8 @@ def set_refereeing_deadline(request, arxiv_identifier_w_vn_nr):
         if form.cleaned_data['deadline'] > timezone.now().date():
             submission.open_for_reporting = True
             submission.open_for_commenting = True
-        submission.status = STATUS_EIC_ASSIGNED
-        submission.latest_activity = timezone.now()
+            submission.latest_activity = timezone.now()
+        # submission.status = STATUS_EIC_ASSIGNED  # This is dangerous as shit.
         submission.save()
         submission.add_general_event('A new refereeing deadline is set.')
         messages.success(request, 'New reporting deadline set.')
@@ -1090,6 +1087,7 @@ def close_refereeing_round(request, arxiv_identifier_w_vn_nr):
         reporting_deadline=timezone.now(),
         latest_activity=timezone.now())
     submission.add_general_event('Refereeing round has been closed.')
+    messages.success(request, 'Refereeing round closed.')
 
     return redirect(reverse('submissions:editorial_page',
                             kwargs={'arxiv_identifier_w_vn_nr': arxiv_identifier_w_vn_nr}))
@@ -1274,22 +1272,21 @@ def reformulate_eic_recommendation(request, arxiv_identifier_w_vn_nr):
 @permission_required('scipost.can_referee', raise_exception=True)
 @transaction.atomic
 def submit_report(request, arxiv_identifier_w_vn_nr):
-    """
-    A form to submit a report on a submission will be shown and processed here.
+    """Submit Report on a Submission.
 
     Important checks to be aware of include an author check for the submission,
     has the reporting deadline not been reached yet and does there exist any invitation
     for the current user on this submission.
     """
-    submission = get_object_or_404(Submission.objects.open_for_reporting(),
-                                   arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
+    submission = get_object_or_404(Submission, arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
     # Check whether the user can submit a report:
     current_contributor = request.user.contributor
     is_author = current_contributor in submission.authors.all()
     is_author_unchecked = (not is_author and not
                            (current_contributor in submission.authors_false_claims.all()) and
                            (request.user.last_name in submission.author_list))
-    invitation = submission.referee_invitations.filter(referee=current_contributor).first()
+    invitation = submission.referee_invitations.filter(
+        fulfilled=False, cancelled=False, referee=current_contributor).first()
 
     errormessage = None
     if not invitation:
@@ -1532,74 +1529,14 @@ def remind_Fellows_to_vote(request):
     return render(request, 'scipost/acknowledgement.html', context)
 
 
-@permission_required('scipost.can_fix_College_decision', raise_exception=True)
-@transaction.atomic
-def fix_College_decision(request, rec_id):
-    """Terminate the voting on a Recommendation.
+class PreScreeningView(SubmissionAdminViewMixin, UpdateView):
+    """Do pre-screening of new incoming Submissions."""
 
-    Called by an Editorial Administrator.
-    """
-    #
-    # submissions = Submission.objects.pool_full(request.user)
-    # recommendation = get_object_or_404(EICRecommendation.objects.filter(
-    #     submission__in=submissions).put_to_voting(), id=rec_id)
-    #
-    # form = FixCollegeDecisionForm(request.POST or None, instance=recommendation)
-    # if form.is_valid():
-    #     recommendation = form.save()
-    #     submission = recommendation.submission
-    #
-    #     # Temporary: Update submission instance for utils email func.
-    #     # Won't be needed in new mail construct.
-    #     submission = Submission.objects.get(id=recommendation.submission.id)
-    #     SubmissionUtils.load({'submission': submission, 'recommendation': recommendation})
-    #     SubmissionUtils.send_author_College_decision_email()
-    #
-    #     submission.add_event_for_eic(
-    #         'The Editorial College\'s decision has been fixed: {0}.'.format(
-    #             recommendation.get_recommendation_display()))
-    #     messages.success(request, 'The Editorial College\'s decision has been fixed.')
-    #     return redirect(reverse('submissions:pool'))
-    #
-    # submission = recommendation.submission
-    # if recommendation.recommendation in [1, 2, 3]:
-    #     # Publish as Tier I, II or III
-    #     Submission.objects.filter(id=submission.id).update(
-    #         visible_public=True, status=STATUS_ACCEPTED, acceptance_date=datetime.date.today(),
-    #         latest_activity=timezone.now())
-    #
-    #     # 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
-    #     notify_manuscript_accepted(request.user, submission, False)
-    #     submission.add_event_for_author('An Editorial Recommendation has been formulated: %s.'
-    #                                     % recommendation.get_recommendation_display())
-    # elif recommendation.recommendation == -3:
-    #     # Decision: Rejection
-    #     Submission.objects.filter(id=submission.id).update(
-    #         visible_public=False, status=STATUS_REJECTED, latest_activity=timezone.now())
-    #     submission.get_other_versions().update(visible_public=False)
-    #
-    #     # Add SubmissionEvent for authors
-    #     submission.add_event_for_author('An Editorial Recommendation has been formulated: %s.'
-    #                                     % recommendation.get_recommendation_display())
-    #
-    # # Add SubmissionEvent for EIC
-    # submission.add_event_for_eic('The Editorial College\'s decision has been fixed: %s.'
-    #                              % recommendation.get_recommendation_display())
-    # #
-    # # # Temporary: Update submission instance for utils email func.
-    # # # Won't be needed in new mail construct.
-    # # submission = Submission.objects.get(id=submission.id)
-    # # SubmissionUtils.load({'submission': submission, 'recommendation': recommendation})
-    # # SubmissionUtils.send_author_College_decision_email()
-    # # messages.success(request, 'The Editorial College\'s decision has been fixed.')
-    return redirect(reverse('submissions:pool'))
+    queryset = Submission.objects.prescreening()
+    template_name = 'submissions/admin/submission_prescreening.html'
+    form_class = SubmissionPrescreeningForm
+    editorial_page = True
+    success_url = reverse_lazy('submissions:pool')
 
 
 class EICRecommendationView(SubmissionAdminViewMixin, UpdateView):
-- 
GitLab