From 3debb84b1e70f63b9af295c48775712a29586125 Mon Sep 17 00:00:00 2001
From: Jorran de Wit <jorrandewit@outlook.com>
Date: Tue, 23 Jan 2018 23:57:37 +0100
Subject: [PATCH] Reformulate EICRecommendation v1

---
 submissions/admin.py                          |   1 +
 submissions/forms.py                          | 101 +++++++++++++--
 submissions/managers.py                       |   3 +
 .../migrations/0005_auto_20180123_2312.py     |  28 +++++
 .../0006_eicrecommendation_active.py          |  20 +++
 submissions/models.py                         |  34 ++---
 .../_recommendation_author_content.html       |   2 +-
 .../templates/submissions/editorial_page.html |  26 ++--
 .../recommendation_formulate_rewrite.html     |  68 ++++++++++
 submissions/urls.py                           |  23 ++--
 submissions/views.py                          | 116 ++++++++++--------
 11 files changed, 330 insertions(+), 92 deletions(-)
 create mode 100644 submissions/migrations/0005_auto_20180123_2312.py
 create mode 100644 submissions/migrations/0006_eicrecommendation_active.py
 create mode 100644 submissions/templates/submissions/pool/recommendation_formulate_rewrite.html

diff --git a/submissions/admin.py b/submissions/admin.py
index 0466fba0c..c052e6718 100644
--- a/submissions/admin.py
+++ b/submissions/admin.py
@@ -233,6 +233,7 @@ class EICRecommendationAdminForm(forms.ModelForm):
 
 class EICRecommendationAdmin(admin.ModelAdmin):
     search_fields = ['submission__title']
+    list_display = (submission_short_title, 'recommendation', 'active', 'version')
     form = EICRecommendationAdminForm
 
 
diff --git a/submissions/forms.py b/submissions/forms.py
index 4e3ce90c7..64da2d530 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -1,3 +1,4 @@
+import datetime
 import re
 
 from django import forms
@@ -681,6 +682,10 @@ class EditorialCommunicationForm(forms.ModelForm):
 ######################
 
 class EICRecommendationForm(forms.ModelForm):
+    DAYS_TO_VOTE = 7
+    assignment = None
+    earlier_recommendations = None
+
     class Meta:
         model = EICRecommendation
         fields = [
@@ -689,17 +694,97 @@ class EICRecommendationForm(forms.ModelForm):
             'requested_changes',
             'remarks_for_editorial_college'
         ]
+        widgets = {
+            'remarks_for_authors': forms.Textarea({
+                'placeholder': 'Your general remarks for the authors',
+                'rows': 10,
+            }),
+            'requested_changes': forms.Textarea({
+                'placeholder': ('If you request revisions, give a numbered (1-, 2-, ...)'
+                                ' list of specifically requested changes'),
+            }),
+            'remarks_for_editorial_college': forms.Textarea({
+                'placeholder': ('If you recommend to accept or refuse, the Editorial College '
+                                'will vote; write any relevant remarks for the EC here.'),
+            }),
+        }
 
     def __init__(self, *args, **kwargs):
+        self.submission = kwargs.pop('submission')
+        self.reformulate = kwargs.pop('reformulate', False)
+        if self.reformulate:
+            self.load_earlier_recommendations()
+            latest_recommendation = self.earlier_recommendations.first()
+            if latest_recommendation:
+                kwargs['initial'] = {
+                    'recommendation': latest_recommendation.recommendation,
+                    'remarks_for_authors': latest_recommendation.remarks_for_authors,
+                    'requested_changes': latest_recommendation.requested_changes,
+                    'remarks_for_editorial_college':
+                        latest_recommendation.remarks_for_editorial_college,
+                }
+
         super().__init__(*args, **kwargs)
-        self.fields['remarks_for_authors'].widget.attrs.update(
-            {'placeholder': 'Your general remarks for the authors',
-             'rows': 10, 'cols': 100})
-        self.fields['requested_changes'].widget.attrs.update(
-            {'placeholder': 'If you request revisions, give a numbered (1-, 2-, ...) list of specifically requested changes',
-             'cols': 100})
-        self.fields['remarks_for_editorial_college'].widget.attrs.update(
-            {'placeholder': 'If you recommend to accept or refuse, the Editorial College will vote; write any relevant remarks for the EC here.'})
+        self.load_assignment()
+
+    def save(self, commit=True):
+        recommendation = super().save(commit=False)
+        recommendation.submission = self.submission
+        recommendation.voting_deadline += datetime.timedelta(days=self.DAYS_TO_VOTE)  # Test this
+        if self.reformulate:
+            # Increment version number
+            recommendation.version = len(self.earlier_recommendations) + 1
+            event_text = 'The Editorial Recommendation has been reformulated: {}.'
+        else:
+            event_text = 'An Editorial Recommendation has been formulated: {}.'
+
+        if recommendation.recommendation in [1, 2, 3, -3]:
+            # Accept/Reject: Forward to the Editorial College for voting
+            self.submission.status = 'voting_in_preparation'
+
+            if commit:
+                # 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.status = 'revision_requested'
+            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)
+
+            recommendation.save()
+            self.submission.save()
+
+            if self.assignment:
+                # The EIC has fulfilled this editorial assignment.
+                self.assignment.completed = True
+                self.assignment.save()
+
+    def revision_requested(self):
+        return self.instance.recommendation in [-1, -2]
+
+    def has_assignment(self):
+        return self.assignment is not None
+
+    def load_assignment(self):
+        # Find EditorialAssignment for Submission
+        try:
+            self.assignment = self.submission.editorial_assignments.accepted().get(
+                to=self.submission.editor_in_charge)
+            return True
+        except EditorialAssignment.DoesNotExist:
+            return False
+
+    def load_earlier_recommendations(self):
+        self.earlier_recommendations = self.submission.eicrecommendations.all()
 
 
 ###############
diff --git a/submissions/managers.py b/submissions/managers.py
index d74e9cc56..e85f7218c 100644
--- a/submissions/managers.py
+++ b/submissions/managers.py
@@ -302,6 +302,9 @@ class EICRecommendationQuerySet(models.QuerySet):
     def voting_in_preparation(self):
         return self.filter(submission__status=STATUS_VOTING_IN_PREPARATION)
 
+    def active(self):
+        return self.filter(active=True)
+
 
 class ReportQuerySet(models.QuerySet):
     def accepted(self):
diff --git a/submissions/migrations/0005_auto_20180123_2312.py b/submissions/migrations/0005_auto_20180123_2312.py
new file mode 100644
index 000000000..35d948ca9
--- /dev/null
+++ b/submissions/migrations/0005_auto_20180123_2312.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-01-23 22:12
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0004_merge_20180123_2041'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='eicrecommendation',
+            options={'ordering': ['version']},
+        ),
+        migrations.AddField(
+            model_name='eicrecommendation',
+            name='version',
+            field=models.SmallIntegerField(default=1),
+        ),
+        migrations.AlterUniqueTogether(
+            name='eicrecommendation',
+            unique_together=set([('submission', 'version')]),
+        ),
+    ]
diff --git a/submissions/migrations/0006_eicrecommendation_active.py b/submissions/migrations/0006_eicrecommendation_active.py
new file mode 100644
index 000000000..94d1c1555
--- /dev/null
+++ b/submissions/migrations/0006_eicrecommendation_active.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-01-23 22:42
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0005_auto_20180123_2312'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='eicrecommendation',
+            name='active',
+            field=models.BooleanField(default=True),
+        ),
+    ]
diff --git a/submissions/models.py b/submissions/models.py
index 00a262f1e..804a1a32d 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -15,7 +15,8 @@ from .constants import ASSIGNMENT_REFUSAL_REASONS, ASSIGNMENT_NULLBOOL,\
                        REPORT_STATUSES, STATUS_UNVETTED, SUBMISSION_EIC_RECOMMENDATION_REQUIRED,\
                        SUBMISSION_CYCLES, CYCLE_DEFAULT, CYCLE_SHORT, CYCLE_DIRECT_REC,\
                        EVENT_GENERAL, EVENT_TYPES, EVENT_FOR_AUTHOR, EVENT_FOR_EIC,\
-                       REPORT_TYPES, REPORT_NORMAL, STATUS_DRAFT, STATUS_VETTED
+                       REPORT_TYPES, REPORT_NORMAL, STATUS_DRAFT, STATUS_VETTED,\
+                       STATUS_VOTING_IN_PREPARATION, STATUS_PUT_TO_EC_VOTING
 from .managers import SubmissionQuerySet, EditorialAssignmentQuerySet, EICRecommendationQuerySet,\
                       ReportQuerySet, SubmissionEventQuerySet, RefereeInvitationQuerySet,\
                       EditorialCommunicationQueryset
@@ -508,16 +509,6 @@ class Report(SubmissionRelatedObjectMixin, models.Model):
             submission__arxiv_identifier_wo_vn_nr=self.submission.arxiv_identifier_wo_vn_nr,
             submission__arxiv_vn_nr__lt=self.submission.arxiv_vn_nr).exists())
 
-    def save(self, *args, **kwargs):
-        # Control Report count per Submission.
-        if not self.report_nr:
-            self.report_nr = self.submission.reports.count() + 1
-        return super().save(*args, **kwargs)
-
-    def create_doi_label(self):
-        self.doi_label = 'SciPost.Report.' + str(self.id)
-        self.save()
-
     def latest_report_from_series(self):
         """
         Get latest Report from the same author for the Submission series.
@@ -526,7 +517,6 @@ class Report(SubmissionRelatedObjectMixin, models.Model):
             submission__arxiv_identifier_wo_vn_nr=self.submission.arxiv_identifier_wo_vn_nr)
                 .order_by('submission__arxiv_identifier_wo_vn_nr').last())
 
-
     @property
     def associated_published_doi(self):
         """
@@ -622,6 +612,8 @@ class EICRecommendation(SubmissionRelatedObjectMixin, models.Model):
                                                      verbose_name='optional remarks for the'
                                                                   ' Editorial College')
     recommendation = models.SmallIntegerField(choices=REPORT_REC)
+    version = models.SmallIntegerField(default=1)
+    active = models.BooleanField(default=True)
 
     # Editorial Fellows who have assessed this recommendation:
     eligible_to_vote = models.ManyToManyField('scipost.Contributor', blank=True,
@@ -635,9 +627,17 @@ class EICRecommendation(SubmissionRelatedObjectMixin, models.Model):
 
     objects = EICRecommendationQuerySet.as_manager()
 
+    class Meta:
+        unique_together = ('submission', 'version')
+        ordering = ['version']
+
     def __str__(self):
-        return (self.submission.title[:20] + ' by ' + self.submission.author_list[:30] +
-                ', ' + self.get_recommendation_display())
+        return '{title} by {author}, {recommendation} version {version}'.format(
+            title=self.submission.title[:20],
+            author=self.submission.author_list[:30],
+            recommendation=self.get_recommendation_display(),
+            version=self.version,
+        )
 
     def get_absolute_url(self):
         # TODO: Fix this weird redirect, but it's neccesary for the notifications to have one.
@@ -659,6 +659,12 @@ class EICRecommendation(SubmissionRelatedObjectMixin, models.Model):
     def nr_abstained(self):
         return self.voted_abstain.count()
 
+    def may_be_reformulated(self):
+        if not self.active:
+            # Already reformulated before; please use the latest version
+            return False
+        return self.submission.status in [STATUS_VOTING_IN_PREPARATION, STATUS_PUT_TO_EC_VOTING]
+
 
 class iThenticateReport(TimeStampedModel):
     """
diff --git a/submissions/templates/submissions/_recommendation_author_content.html b/submissions/templates/submissions/_recommendation_author_content.html
index d646512ba..39743bb93 100644
--- a/submissions/templates/submissions/_recommendation_author_content.html
+++ b/submissions/templates/submissions/_recommendation_author_content.html
@@ -1,6 +1,6 @@
 <div class="card bg-white">
     <div class="card-body">
-        <h2 class="pb-0 mb-0">Editorial Recommendation</h2>
+        <h2 class="card-title mb-0">Editorial Recommendation <small>(version {{ recommendation.version }}){% if not recommendation.active %} (Deprecated: This Editorial Recommendation has been reformulated){% endif %}</small></h2>
 
         {% block recommendation_header %}
             <h3 class="card-title text-muted">Date {{recommendation.date_submitted}}</h3>
diff --git a/submissions/templates/submissions/editorial_page.html b/submissions/templates/submissions/editorial_page.html
index 66b4ad1c6..bb0048c3e 100644
--- a/submissions/templates/submissions/editorial_page.html
+++ b/submissions/templates/submissions/editorial_page.html
@@ -76,17 +76,16 @@
     </div>
 </div>
 
-{% with recommendation as submission.eicrecommendations.first %}
-    {% if recommendation %}
-        <div class="row">
-            <div class="col-12">
-                <div class="card card-outline-secondary">
-                    {% include 'submissions/_recommendation_author_content.html' with recommendation=recommendation %}
-                </div>
-            </div>
-        </div>
-    {% endif %}
-{% endwith %}
+<div class="row">
+    <div class="col-12">
+        {% for recommendation in submission.eicrecommendations.all %}
+            {% include 'submissions/_recommendation_author_content.html' with recommendation=recommendation %}
+            {% if recommendation.may_be_reformulated %}
+                <a href="{% url 'submissions:reformulate_eic_recommendation' submission.arxiv_identifier_w_vn_nr %}">Reformulate this Editorial Recommendation</a>
+            {% endif %}
+        {% endfor %}
+    </div>
+</div>
 
 <div class="card card-grey my-4">
     <div class="card-body">
@@ -237,6 +236,11 @@
                                 </p>
                             </li>
                         {% endif %}
+                        {% if submission.eicrecommendations.active.first %}
+                            {% if submission.eicrecommendations.active.first.may_be_reformulated %}
+                                <li><a href="{% url 'submissions:reformulate_eic_recommendation' submission.arxiv_identifier_w_vn_nr %}">Reformulate Editorial Recommendation</a></li>
+                            {% endif %}
+                        {% endif %}
                   </ul>
             </div>
         </div>
diff --git a/submissions/templates/submissions/pool/recommendation_formulate_rewrite.html b/submissions/templates/submissions/pool/recommendation_formulate_rewrite.html
new file mode 100644
index 000000000..58b73d22d
--- /dev/null
+++ b/submissions/templates/submissions/pool/recommendation_formulate_rewrite.html
@@ -0,0 +1,68 @@
+{% extends 'submissions/pool/base.html' %}
+
+{% block pagetitle %}: Editorial Recommendation for Submission{% endblock pagetitle %}
+
+{% load scipost_extras %}
+{% load bootstrap %}
+
+{% block breadcrumb_items %}
+    {{block.super}}
+    <a href="{% url 'submissions:editorial_page' submission.arxiv_identifier_w_vn_nr %}" class="breadcrumb-item">Editorial Page ({{submission.arxiv_identifier_w_vn_nr}})</a>
+    <span class="breadcrumb-item">Reformulate Editorial Recommendation</span>
+{% endblock %}
+
+{% block content %}
+
+<h1 class="highlight">Reformulate Editorial Recommendation for Submission</h1>
+
+<br>
+{% include 'submissions/_submission_summary.html' with submission=submission %}
+
+<br>
+<div class="card card-grey">
+    <div class="card-body">
+        <h2 class="card-title">Reformulate Editorial Recommendation</h2>
+        <p class="card-text">You recommendation will be processed by the Editorial Administration.</p>
+        <ul>
+            <li>acceptance or rejection: forwarded to the Editorial College for ratification</li>
+            <li>request for revision: sent directly to the authors</li>
+        </ul>
+
+        <p class="card-text">
+            This recommendation will be saved with a new version number and any other Editorial Recommendation will be deactived. <b>All obtained votes will be lost.</b>
+        </p>
+    </div>
+</div>
+
+{% if submission.editor_in_charge != request.user.contributor %}
+    <div class="row">
+        <div class="col-12">
+            <div class="card border-danger">
+                <div class="card-body d-flex flex-row">
+                    <div class="p-2">
+                        <i class="fa fa-2x fa-exclamation-triangle text-warning" aria-hidden="true"></i>
+                    </div>
+                    <div class="px-2">
+                        You are not assigned as Editor in charge. However, you can formulate an Editorial Recommendation because you are Editorial Administrator. <strong>This Editorial Recommendation will still be signed by the Editor-in-charge.</strong>
+                    </div>
+
+                </div>
+            </div>
+        </div>
+    </div>
+{% endif %}
+
+<br>
+
+<div class="row">
+    <div class="col-12">
+        <form method="post">
+            {% csrf_token %}
+            {{ form|bootstrap }}
+            <input class="btn btn-primary" type="submit" value="Submit Recommendation"/>
+        </form>
+    </div>
+</div>
+
+
+{% endblock content %}
diff --git a/submissions/urls.py b/submissions/urls.py
index 3981f846e..139dc2528 100644
--- a/submissions/urls.py
+++ b/submissions/urls.py
@@ -68,7 +68,8 @@ urlpatterns = [
         views.select_referee, name='select_referee'),
     url(r'^recruit_referee/{regex}$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
         views.recruit_referee, name='recruit_referee'),
-    url(r'^send_refereeing_invitation/{regex}/(?P<contributor_id>[0-9]+)$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
+    url(r'^send_refereeing_invitation/{regex}/(?P<contributor_id>[0-9]+)$'.format(
+        regex=SUBMISSIONS_COMPLETE_REGEX),
         views.send_refereeing_invitation, name='send_refereeing_invitation'),
     url(r'^accept_or_decline_ref_invitations/$',
         views.accept_or_decline_ref_invitations, name='accept_or_decline_ref_invitations'),
@@ -76,23 +77,30 @@ urlpatterns = [
         views.accept_or_decline_ref_invitations, name='accept_or_decline_ref_invitations'),
     url(r'^decline_ref_invitation/(?P<invitation_key>.+)$',
         views.decline_ref_invitation, name='decline_ref_invitation'),
-    url(r'^ref_invitation_reminder/{regex}/(?P<invitation_id>[0-9]+)$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
+    url(r'^ref_invitation_reminder/{regex}/(?P<invitation_id>[0-9]+)$'.format(
+        regex=SUBMISSIONS_COMPLETE_REGEX),
         views.ref_invitation_reminder, name='ref_invitation_reminder'),
-    url(r'^cancel_ref_invitation/{regex}/(?P<invitation_id>[0-9]+)$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
+    url(r'^cancel_ref_invitation/{regex}/(?P<invitation_id>[0-9]+)$'.format(
+        regex=SUBMISSIONS_COMPLETE_REGEX),
         views.cancel_ref_invitation, name='cancel_ref_invitation'),
-    url(r'^extend_refereeing_deadline/{regex}/(?P<days>[0-9]+)$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
+    url(r'^extend_refereeing_deadline/{regex}/(?P<days>[0-9]+)$'.format(
+        regex=SUBMISSIONS_COMPLETE_REGEX),
         views.extend_refereeing_deadline, name='extend_refereeing_deadline'),
     url(r'^set_refereeing_deadline/{regex}$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
         views.set_refereeing_deadline, name='set_refereeing_deadline'),
     url(r'^close_refereeing_round/{regex}$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
         views.close_refereeing_round, name='close_refereeing_round'),
     url(r'^refereeing_overview$', views.refereeing_overview, name='refereeing_overview'),
-    url(r'^communication/{regex}/(?P<comtype>[a-zA-Z]{{4,}})$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
+    url(r'^communication/{regex}/(?P<comtype>[a-zA-Z]{{4,}})$'.format(
+        regex=SUBMISSIONS_COMPLETE_REGEX),
         views.communication, name='communication'),
-    url(r'^communication/{regex}/(?P<comtype>[a-zA-Z]{{4,}})/(?P<referee_id>[0-9]+)$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
+    url(r'^communication/{regex}/(?P<comtype>[a-zA-Z]{{4,}})/(?P<referee_id>[0-9]+)$'.format(
+        regex=SUBMISSIONS_COMPLETE_REGEX),
         views.communication, name='communication'),
     url(r'^eic_recommendation/{regex}$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
         views.eic_recommendation, name='eic_recommendation'),
+    url(r'^eic_recommendation/{regex}/reformulate$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
+        views.reformulate_eic_recommendation, name='reformulate_eic_recommendation'),
     url(r'^cycle/{regex}/submit$'.format(regex=SUBMISSIONS_COMPLETE_REGEX),
         views.cycle_form_submit, name='cycle_confirmation'),
 
@@ -104,7 +112,8 @@ urlpatterns = [
         name='vet_submitted_report'),
 
     # Voting
-    url(r'^prepare_for_voting/(?P<rec_id>[0-9]+)$', views.prepare_for_voting, name='prepare_for_voting'),
+    url(r'^prepare_for_voting/(?P<rec_id>[0-9]+)$', views.prepare_for_voting,
+        name='prepare_for_voting'),
     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'),
diff --git a/submissions/views.py b/submissions/views.py
index 5e9c27c23..5ab6f37ae 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -20,10 +20,11 @@ from django.views.generic.list import ListView
 from guardian.shortcuts import assign_perm
 
 from .constants import STATUS_VETTED, STATUS_EIC_ASSIGNED,\
-                       SUBMISSION_STATUS_PUBLICLY_INVISIBLE, SUBMISSION_STATUS, ED_COMM_CHOICES,\
-                       STATUS_DRAFT, CYCLE_DIRECT_REC
+                       SUBMISSION_STATUS_PUBLICLY_INVISIBLE, SUBMISSION_STATUS,\
+                       STATUS_DRAFT, CYCLE_DIRECT_REC, STATUS_VOTING_IN_PREPARATION,\
+                       STATUS_PUT_TO_EC_VOTING
 from .models import Submission, EICRecommendation, EditorialAssignment,\
-                    RefereeInvitation, Report, EditorialCommunication, SubmissionEvent
+                    RefereeInvitation, Report, SubmissionEvent
 from .mixins import SubmissionAdminViewMixin
 from .forms import SubmissionIdentifierForm, RequestSubmissionForm, SubmissionSearchForm,\
                    RecommendationVoteForm, ConsiderAssignmentForm, AssignSubmissionForm,\
@@ -221,7 +222,7 @@ def submission_detail(request, arxiv_identifier_w_vn_nr):
         context['communication'] = submission.editorial_communications.for_referees().filter(
             referee__user=request.user)
 
-    recommendations = submission.eicrecommendations.all()
+    recommendations = submission.eicrecommendations.active()
 
     context.update({
         'submission': submission,
@@ -358,8 +359,7 @@ def pool(request, arxiv_identifier_w_vn_nr=None):
         # 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)
+    recommendations = EICRecommendation.objects.active().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)
@@ -1192,11 +1192,9 @@ def eic_recommendation(request, arxiv_identifier_w_vn_nr):
         return redirect(reverse('submissions:editorial_page',
                                 args=[submission.arxiv_identifier_w_vn_nr]))
 
+    form = EICRecommendationForm(request.POST or None, submission=submission)
     # Find EditorialAssignment for user
-    try:
-        assignment = submission.editorial_assignments.accepted().get(
-            to=submission.editor_in_charge)
-    except EditorialAssignment.DoesNotExist:
+    if not form.has_assignment():
         messages.warning(request, ('You cannot formulate an Editorial Recommendation,'
                                    ' because the Editorial Assignment has not been set properly.'
                                    ' Please '
@@ -1204,53 +1202,68 @@ def eic_recommendation(request, arxiv_identifier_w_vn_nr):
         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
-        recommendation = form.save(commit=False)
-        recommendation.submission = submission
-        recommendation.voting_deadline = timezone.now() + datetime.timedelta(days=7)
-        recommendation.save()
-
-        # If recommendation is to accept or reject,
-        # it is forwarded to the Editorial College for voting
-        # If it is to carry out minor or major revisions,
-        # it is returned to the Author who is asked to resubmit
-        if (recommendation.recommendation == 1 or
-                recommendation.recommendation == 2 or
-                recommendation.recommendation == 3 or
-                recommendation.recommendation == -3):
-            submission.status = 'voting_in_preparation'
-
-            # Add SubmissionEvent for EIC
-            submission.add_event_for_eic('An Editorial Recommendation has been formulated: %s.'
-                                         % recommendation.get_recommendation_display())
-
-        elif (recommendation.recommendation == -1 or
-              recommendation.recommendation == -2):
-            submission.status = 'revision_requested'
-            SubmissionUtils.load({'submission': submission,
-                                  'recommendation': recommendation})
+        recommendation = form.save()
+        if form.revision_requested():
+            # Send mail to authors to notify about the request for revision.
+            SubmissionUtils.load({
+                'submission': form.submission,
+                'recommendation': recommendation,
+            })
             SubmissionUtils.send_author_revision_requested_email()
 
-            # Add SubmissionEvents
-            submission.add_general_event('An Editorial Recommendation has been formulated: %s.'
-                                         % recommendation.get_recommendation_display())
-        submission.open_for_reporting = False
-        submission.save()
-
-        # The EIC has fulfilled this editorial assignment.
-        assignment.completed = True
-        assignment.save()
-        messages.success(request, 'Your Editorial Recommendation has been succesfully submitted')
+        messages.success(request, 'Editorial Recommendation succesfully submitted')
         return redirect(reverse('submissions:editorial_page',
                                 kwargs={'arxiv_identifier_w_vn_nr': arxiv_identifier_w_vn_nr}))
 
-    context = {'submission': submission,
-               'form': form}
+    context = {
+        'submission': submission,
+        'form': form
+    }
     return render(request, 'submissions/pool/recommendation_formulate.html', context)
 
 
+@login_required
+@fellowship_or_admin_required()
+@transaction.atomic
+def reformulate_eic_recommendation(request, arxiv_identifier_w_vn_nr):
+    """
+    Reformulate EIC Recommendation.
+
+    Accessible for: Editor-in-charge and Editorial Administration
+    """
+    submission = get_object_or_404(Submission.objects.filter_for_eic(request.user),
+                                   arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
+
+    if submission.status not in [STATUS_VOTING_IN_PREPARATION, STATUS_PUT_TO_EC_VOTING]:
+        messages.warning(request, ('With the current status of the Submission you are not '
+                                   'allowed to reformulate the Editorial Recommendation'))
+        return redirect(reverse('submissions:editorial_page',
+                                args=[submission.arxiv_identifier_w_vn_nr]))
+
+    form = EICRecommendationForm(request.POST or None, submission=submission, reformulate=True)
+
+    if form.is_valid():
+        recommendation = form.save()
+        if form.revision_requested():
+            # Send mail to authors to notify about the request for revision.
+            SubmissionUtils.load({
+                'submission': form.submission,
+                'recommendation': recommendation,
+            })
+            SubmissionUtils.send_author_revision_requested_email()
+
+        messages.success(request, 'Editorial Recommendation succesfully reformulated')
+        return redirect(reverse('submissions:editorial_page',
+                                kwargs={'arxiv_identifier_w_vn_nr': arxiv_identifier_w_vn_nr}))
+
+    context = {
+        'submission': submission,
+        'form': form
+    }
+    return render(request, 'submissions/pool/recommendation_formulate_rewrite.html', context)
+
+
 ###########
 # Reports
 ###########
@@ -1401,7 +1414,7 @@ def vet_submitted_report(request, report_id):
 def prepare_for_voting(request, rec_id):
     submissions = Submission.objects.pool_editable(request.user)
     recommendation = get_object_or_404(
-        EICRecommendation.objects.filter(submission__in=submissions), id=rec_id)
+        EICRecommendation.objects.active().filter(submission__in=submissions), id=rec_id)
 
     fellows_with_expertise = recommendation.submission.fellows.filter(
         contributor__expertises__contains=[recommendation.submission.subject_area])
@@ -1453,7 +1466,7 @@ def prepare_for_voting(request, rec_id):
 def vote_on_rec(request, rec_id):
     submissions = Submission.objects.pool_editable(request.user)
     recommendation = get_object_or_404(
-        EICRecommendation.objects.filter(submission__in=submissions), id=rec_id)
+        EICRecommendation.objects.active().filter(submission__in=submissions), id=rec_id)
 
     form = RecommendationVoteForm(request.POST or None)
     if form.is_valid():
@@ -1507,7 +1520,8 @@ def remind_Fellows_to_vote(request):
     TODO: This reminder function doesn't filter per submission?!
     """
     submissions = Submission.objects.pool_editable(request.user)
-    recommendations = EICRecommendation.objects.filter(submission__in=submissions).put_to_voting()
+    recommendations = EICRecommendation.objects.active().filter(
+        submission__in=submissions).put_to_voting()
 
     Fellow_emails = []
     Fellow_names = []
-- 
GitLab