From 046b5fd89ea6e5fc266c054ff93190e6ad08ebab Mon Sep 17 00:00:00 2001
From: Jorran de Wit <jorrandewit@outlook.com>
Date: Fri, 20 Oct 2017 11:57:29 +0200
Subject: [PATCH] Auto fill old Pools-script to the migrations

---
 .../migrations/0002_auto_20171020_0931.py     | 27 ++++++++++
 submissions/admin.py                          |  4 +-
 submissions/forms.py                          | 20 +++++---
 submissions/managers.py                       | 30 ++++++++---
 .../migrations/0078_auto_20171020_1054.py     | 34 +++++++++++++
 submissions/views.py                          | 51 ++++++++++---------
 6 files changed, 126 insertions(+), 40 deletions(-)
 create mode 100644 colleges/migrations/0002_auto_20171020_0931.py
 create mode 100644 submissions/migrations/0078_auto_20171020_1054.py

diff --git a/colleges/migrations/0002_auto_20171020_0931.py b/colleges/migrations/0002_auto_20171020_0931.py
new file mode 100644
index 000000000..c5ba871e0
--- /dev/null
+++ b/colleges/migrations/0002_auto_20171020_0931.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-10-20 07:31
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def fill_editorial_college(apps, schema_editor):
+    Fellowship = apps.get_model('colleges', 'Fellowship')
+    Contributor = apps.get_model('scipost', 'Contributor')
+    for contributor in Contributor.objects.filter(user__groups__name='Editorial College'):
+        Fellowship.objects.get_or_create(contributor=contributor)
+
+
+def return_empty(*args, **kwargs):
+    return
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('colleges', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.RunPython(fill_editorial_college, return_empty),
+    ]
diff --git a/submissions/admin.py b/submissions/admin.py
index 63559e3ed..8a2f0f0e8 100644
--- a/submissions/admin.py
+++ b/submissions/admin.py
@@ -87,7 +87,7 @@ class SubmissionAdmin(GuardedModelAdmin):
                 'domain',
                 'subject_area',
                 'secondary_areas',
-                'proceeding'),
+                'proceedings'),
         }),
         ('Authors', {
             'classes': ('collapse',),
@@ -111,7 +111,7 @@ class SubmissionAdmin(GuardedModelAdmin):
                 'referees_suggested',
                 'remarks_for_editors',
                 'submitted_to_journal',
-                'proceeding',
+                'proceedings',
                 'pdf_refereeing_pack',
                 'plagiarism_report',
                 'fellows'),
diff --git a/submissions/forms.py b/submissions/forms.py
index 23656883f..0b68bba37 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -45,19 +45,23 @@ 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)
+    status = forms.ChoiceField(
+        choices=((None, 'All in refereeing phase'),) + 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):
+    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.filter(status=self.cleaned_data['status'])
+            queryset = queryset.pool_full(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)
 
-        if self.cleaned_data.get('editor_in_charge') and current_contributor:
-            queryset = queryset.filter(editor_in_charge=current_contributor)
+        if self.cleaned_data.get('editor_in_charge') and hasattr(current_user, 'contributor'):
+            queryset = queryset.filter(editor_in_charge=current_user.contributor)
 
-        return queryset
+        return queryset.order_by('-submission_date')
 
 
 ###############################
diff --git a/submissions/managers.py b/submissions/managers.py
index 683eaf0b6..a8aa583f2 100644
--- a/submissions/managers.py
+++ b/submissions/managers.py
@@ -48,9 +48,13 @@ class SubmissionQuerySet(models.QuerySet):
 
     def _pool(self, user):
         """
-        This filter creates 'the complete pool' for an user.
+        This filter creates 'the complete pool' for an user. This new-style pool does
+        explicitly not have the author filter anymore, but registered pools for every Submission.
 
-        This new-style pool does explicitly not have the author filter.
+        !!!  IMPORTANT SECURITY NOTICE  !!!
+        All permissions regarding Editorial College actions are implicitly taken care
+        of in this filter method! ALWAYS use this filter method in your Editorial College
+        related view/action.
         """
         if not hasattr(user, 'contributor'):
             return self.none()
@@ -66,22 +70,34 @@ class SubmissionQuerySet(models.QuerySet):
 
     def pool(self, user):
         """
-        Return the pool for a certain user.
+        Return the pool for a certain user: filtered to "in active referee phase".
         """
         qs = self._pool(user)
         qs = qs.exclude(is_current=False).exclude(status__in=SUBMISSION_STATUS_OUT_OF_POOL)
-        return qs.order_by('-submission_date')
+        return qs
 
-    def overcomplete_pool(self, user):
+    def pool_editable(self, user):
         """
-        Return the overcomplete pool for a certain user.
+        Return the editable pool for a certain user.
+
         This is similar to the regular pool, however it also contains submissions that are
         hidden in the regular pool, but should still be able to be opened by for example
         the Editor-in-charge.
         """
         qs = self._pool(user)
         qs = qs.exclude(status__in=SUBMISSION_HTTP404_ON_EDITORIAL_PAGE)
-        return qs.order_by('-submission_date')
+        return qs
+
+    def pool_full(self, user):
+        """
+        Return the *FULL* pool for a certain user.
+        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
 
     def get_pool(self, user):
         """
diff --git a/submissions/migrations/0078_auto_20171020_1054.py b/submissions/migrations/0078_auto_20171020_1054.py
new file mode 100644
index 000000000..703f77966
--- /dev/null
+++ b/submissions/migrations/0078_auto_20171020_1054.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2017-10-20 08:54
+from __future__ import unicode_literals
+
+from django.db import migrations
+from django.db.models import Q
+
+
+def fill_pools(apps, schema_editor):
+    Fellowship = apps.get_model('colleges', 'Fellowship')
+    Submission = apps.get_model('submissions', 'Submission')
+    for fellowship in Fellowship.objects.all():
+        # Fellowship.objects.get_or_create(contributor=contributor)
+        contributor = fellowship.contributor
+        submissions = Submission.objects.exclude(authors=contributor).exclude(
+            Q(author_list__icontains=contributor.user.last_name),
+            ~Q(authors_false_claims=contributor))
+        fellowship.pool.add(*submissions)
+
+
+def return_empty(*args, **kwargs):
+    return
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('colleges', '0002_auto_20171020_0931'),
+        ('submissions', '0077_auto_20171020_0900'),
+    ]
+
+    operations = [
+        migrations.RunPython(fill_pools, return_empty),
+    ]
diff --git a/submissions/views.py b/submissions/views.py
index ebc088136..6bd6fa2f0 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -340,7 +340,18 @@ def pool(request, arxiv_identifier_w_vn_nr=None):
     All members of the Editorial College have access.
     """
     # Objects
-    submissions = Submission.objects.pool(request.user)
+
+    # The following is in test phase. Update if test is done
+    # --
+    # Search
+    search_form = SubmissionPoolFilterForm(request.GET or None)
+    if search_form.is_valid():
+        submissions = search_form.search(Submission.objects.all(), request.user)
+    else:
+        # Mainly as fallback for the old-pool while in test phase.
+        submissions = Submission.objects.pool(request.user)
+
+    # submissions = Submission.objects.pool(request.user)
     recommendations = EICRecommendation.objects.filter(submission__in=submissions)
     recs_to_vote_on = recommendations.user_may_vote_on(request.user)
     assignments_to_consider = EditorialAssignment.objects.open().filter(to=request.user.contributor)
@@ -363,12 +374,6 @@ def pool(request, arxiv_identifier_w_vn_nr=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'] = search_form.search(context['submissions'],
-                                                    request.user.contributor)
     context['search_form'] = search_form
 
     # Show specific submission in the pool
@@ -671,7 +676,7 @@ def assignments(request):
 @permission_required_or_403('can_take_editorial_actions',
                             (Submission, 'arxiv_identifier_w_vn_nr', 'arxiv_identifier_w_vn_nr'))
 def editorial_page(request, arxiv_identifier_w_vn_nr):
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
 
     context = {
@@ -686,7 +691,7 @@ def editorial_page(request, arxiv_identifier_w_vn_nr):
 @permission_required_or_403('can_take_editorial_actions',
                             (Submission, 'arxiv_identifier_w_vn_nr', 'arxiv_identifier_w_vn_nr'))
 def cycle_form_submit(request, arxiv_identifier_w_vn_nr):
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
 
     form = SubmissionCycleChoiceForm(request.POST or None, instance=submission)
@@ -709,7 +714,7 @@ def cycle_form_submit(request, arxiv_identifier_w_vn_nr):
 @permission_required_or_403('can_take_editorial_actions',
                             (Submission, 'arxiv_identifier_w_vn_nr', 'arxiv_identifier_w_vn_nr'))
 def select_referee(request, arxiv_identifier_w_vn_nr):
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
 
     context = {}
@@ -760,7 +765,7 @@ def recruit_referee(request, arxiv_identifier_w_vn_nr):
     The pending refereeing invitation is then recognized upon registration,
     using the invitation token.
     """
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
     if request.method == 'POST':
         ref_recruit_form = RefereeRecruitmentForm(request.POST)
@@ -820,7 +825,7 @@ def send_refereeing_invitation(request, arxiv_identifier_w_vn_nr, contributor_id
     For a referee who isn't a Contributor yet, the method recruit_referee above
     is called instead.
     """
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
     contributor = get_object_or_404(Contributor, pk=contributor_id)
     if not contributor.is_currently_available:
@@ -863,7 +868,7 @@ def ref_invitation_reminder(request, arxiv_identifier_w_vn_nr, invitation_id):
     when a referee has been invited but hasn't answered yet.
     It can be used for registered as well as unregistered referees.
     """
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
     invitation = get_object_or_404(submission.referee_invitations.all(), pk=invitation_id)
     invitation.nr_reminders += 1
@@ -985,7 +990,7 @@ def cancel_ref_invitation(request, arxiv_identifier_w_vn_nr, invitation_id):
 @permission_required_or_403('can_take_editorial_actions',
                             (Submission, 'arxiv_identifier_w_vn_nr', 'arxiv_identifier_w_vn_nr'))
 def extend_refereeing_deadline(request, arxiv_identifier_w_vn_nr, days):
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
     submission.reporting_deadline += datetime.timedelta(days=int(days))
     submission.open_for_reporting = True
@@ -1003,7 +1008,7 @@ def extend_refereeing_deadline(request, arxiv_identifier_w_vn_nr, days):
 @permission_required_or_403('can_take_editorial_actions',
                             (Submission, 'arxiv_identifier_w_vn_nr', 'arxiv_identifier_w_vn_nr'))
 def set_refereeing_deadline(request, arxiv_identifier_w_vn_nr):
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
 
     form = SetRefereeingDeadlineForm(request.POST or None)
@@ -1040,7 +1045,7 @@ def close_refereeing_round(request, arxiv_identifier_w_vn_nr):
     round off any replies to reports or comments before the
     editorial recommendation is formulated.
     """
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
     submission.open_for_reporting = False
     submission.open_for_commenting = False
@@ -1058,7 +1063,7 @@ def close_refereeing_round(request, arxiv_identifier_w_vn_nr):
 @permission_required('scipost.can_oversee_refereeing', raise_exception=True)
 def refereeing_overview(request):
     submissions_under_refereeing = (Submission.objects
-                                    .overcomplete_pool(request.user)
+                                    .pool_editable(request.user)
                                     .filter(status=STATUS_EIC_ASSIGNED)
                                     .order_by('submission_date'))
     context = {'submissions_under_refereeing': submissions_under_refereeing}
@@ -1071,7 +1076,7 @@ def communication(request, arxiv_identifier_w_vn_nr, comtype, referee_id=None):
     Communication between editor-in-charge, author or referee
     occurring during the submission refereeing.
     """
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
     errormessage = None
     if comtype not in dict(ED_COMM_CHOICES).keys():
@@ -1122,7 +1127,7 @@ def communication(request, arxiv_identifier_w_vn_nr, comtype, referee_id=None):
                             (Submission, 'arxiv_identifier_w_vn_nr', 'arxiv_identifier_w_vn_nr'))
 @transaction.atomic
 def eic_recommendation(request, arxiv_identifier_w_vn_nr):
-    submission = get_object_or_404(Submission.objects.overcomplete_pool(request.user),
+    submission = get_object_or_404(Submission.objects.pool_editable(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
     if submission.eic_recommendation_required():
         messages.warning(request, ('<h3>An Editorial Recommendation is not required</h3>'
@@ -1338,7 +1343,7 @@ def vet_submitted_report(request, report_id):
 @permission_required('scipost.can_prepare_recommendations_for_voting', raise_exception=True)
 @transaction.atomic
 def prepare_for_voting(request, rec_id):
-    submissions = Submission.objects.overcomplete_pool(request.user)
+    submissions = Submission.objects.pool_editable(request.user)
     recommendation = get_object_or_404(EICRecommendation.objects.filter(submission__in=submissions),
                                        id=rec_id)
 
@@ -1403,7 +1408,7 @@ def prepare_for_voting(request, rec_id):
 @permission_required('scipost.can_take_charge_of_submissions', raise_exception=True)
 @transaction.atomic
 def vote_on_rec(request, rec_id):
-    submissions = Submission.objects.overcomplete_pool(request.user)
+    submissions = Submission.objects.pool_editable(request.user)
     recommendation = get_object_or_404(EICRecommendation.objects.filter(submission__in=submissions),
                                        id=rec_id)
 
@@ -1458,7 +1463,7 @@ def remind_Fellows_to_vote(request):
 
     TODO: This reminder function doesn't filter per submission?!
     """
-    submissions = Submission.objects.overcomplete_pool(request.user)
+    submissions = Submission.objects.pool_editable(request.user)
     recommendations = EICRecommendation.objects.filter(submission__in=submissions).put_to_voting()
 
     Fellow_emails = []
@@ -1496,7 +1501,7 @@ def fix_College_decision(request, rec_id):
     TO FIX: If multiple recommendations are submitted; decisions may be overruled unexpectedly.
     TO FIX: A college decision can be fixed multiple times, there is no already-fixed mechanism!!!
     """
-    submissions = Submission.objects.overcomplete_pool(request.user)
+    submissions = Submission.objects.pool_editable(request.user)
     recommendation = get_object_or_404(EICRecommendation.objects.filter(submission__in=submissions),
                                        id=rec_id)
 
-- 
GitLab