From 8da700705143e721c43675eb9e5782bacfdf09ab Mon Sep 17 00:00:00 2001 From: "J.-S. Caux" <J.S.Caux@uva.nl> Date: Sat, 26 Oct 2019 20:03:34 +0200 Subject: [PATCH] Improve Editorial Decision workflow and presentation --- submissions/admin.py | 2 +- submissions/constants.py | 3 + submissions/forms.py | 10 +- .../migrations/0079_auto_20191026_1603.py | 17 +++ .../migrations/0080_auto_20191026_1736.py | 26 ++++ .../migrations/0081_auto_20191026_1828.py | 18 +++ submissions/mixins.py | 20 +++ submissions/models.py | 10 +- .../submissions/pool/submission_details.html | 2 +- .../submission_author_information.html | 16 +- .../submission_editorial_information.html | 26 +++- .../submissions/submission_summary.html | 20 +-- .../admin/_editorial_decision_as_table.html | 3 + .../admin/editorial_decision_detail.html | 4 +- .../admin/editorial_decision_form.html | 2 +- .../templates/submissions/pool/pool.html | 2 +- .../submissions/submission_detail.html | 10 ++ submissions/urls.py | 11 +- submissions/views.py | 142 +++++++++++------- .../inform_authors_editorial_decision.html | 4 +- 20 files changed, 266 insertions(+), 82 deletions(-) create mode 100644 submissions/migrations/0079_auto_20191026_1603.py create mode 100644 submissions/migrations/0080_auto_20191026_1736.py create mode 100644 submissions/migrations/0081_auto_20191026_1828.py diff --git a/submissions/admin.py b/submissions/admin.py index a4161b29c..b7cbec330 100644 --- a/submissions/admin.py +++ b/submissions/admin.py @@ -277,7 +277,7 @@ class EditorialDecisionAdmin(admin.ModelAdmin): ] list_filter = ['for_journal', 'decision', 'status',] list_display = [submission_short_title, 'for_journal', 'decision', - 'taken_on', 'status'] + 'taken_on', 'status', 'version'] admin.site.register(EditorialDecision, EditorialDecisionAdmin) diff --git a/submissions/constants.py b/submissions/constants.py index 82ba22efd..a90989f50 100644 --- a/submissions/constants.py +++ b/submissions/constants.py @@ -9,6 +9,7 @@ STATUS_FAILED_PRESCREENING = 'failed_pre' STATUS_EIC_ASSIGNED = 'assigned' STATUS_ASSIGNMENT_FAILED = 'assignment_failed' STATUS_RESUBMITTED = 'resubmitted' +STATUS_ACCEPTED_AWAITING_PUBOFFER_ACCEPTANCE = 'puboffer_waiting' STATUS_ACCEPTED = 'accepted' STATUS_REJECTED = 'rejected' STATUS_WITHDRAWN = 'withdrawn' @@ -28,6 +29,8 @@ SUBMISSION_STATUS = ( (STATUS_ASSIGNMENT_FAILED, 'Failed to assign Editor-in-charge; manuscript rejected'), (STATUS_RESUBMITTED, 'Has been resubmitted'), (STATUS_ACCEPTED, 'Publication decision taken: accept'), + (STATUS_ACCEPTED_AWAITING_PUBOFFER_ACCEPTANCE, + 'Accepted in other journal; awaiting puboffer acceptance'), (STATUS_REJECTED, 'Publication decision taken: reject'), (STATUS_WITHDRAWN, 'Withdrawn by the Authors'), (STATUS_PUBLISHED, 'Published'), diff --git a/submissions/forms.py b/submissions/forms.py index 59db31826..206893493 100644 --- a/submissions/forms.py +++ b/submissions/forms.py @@ -1396,7 +1396,7 @@ class EditorialDecisionForm(forms.ModelForm): 'taken_on', 'remarks_for_authors', 'remarks_for_editorial_college', - 'status', + 'status' ] def __init__(self, *args, **kwargs): @@ -1411,6 +1411,14 @@ class EditorialDecisionForm(forms.ModelForm): self.fields['remarks_for_editorial_college'].widget.attrs.update({ 'placeholder': '[will only be seen by Fellows]'}) + def save(self): + decision = super().save(commit=False) + if not self.instance.id: # a new object is created + decision.version = self.cleaned_data['submission'].editorialdecision_set.all( + ).last().version + 1 + decision.save() + return decision + class SubmissionCycleChoiceForm(forms.ModelForm): """Make a decision on the Submission's cycle and make publicly available.""" diff --git a/submissions/migrations/0079_auto_20191026_1603.py b/submissions/migrations/0079_auto_20191026_1603.py new file mode 100644 index 000000000..adc610c93 --- /dev/null +++ b/submissions/migrations/0079_auto_20191026_1603.py @@ -0,0 +1,17 @@ +# Generated by Django 2.1.8 on 2019-10-26 14:03 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('submissions', '0078_auto_20191023_1508'), + ] + + operations = [ + migrations.AlterModelOptions( + name='editorialdecision', + options={'ordering': ['submission', 'taken_on'], 'verbose_name': 'Editorial Decision', 'verbose_name_plural': 'Editorial Decisions'}, + ), + ] diff --git a/submissions/migrations/0080_auto_20191026_1736.py b/submissions/migrations/0080_auto_20191026_1736.py new file mode 100644 index 000000000..c03b5aaff --- /dev/null +++ b/submissions/migrations/0080_auto_20191026_1736.py @@ -0,0 +1,26 @@ +# Generated by Django 2.1.8 on 2019-10-26 15:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('submissions', '0079_auto_20191026_1603'), + ] + + operations = [ + migrations.AlterModelOptions( + name='editorialdecision', + options={'ordering': ['version'], 'verbose_name': 'Editorial Decision', 'verbose_name_plural': 'Editorial Decisions'}, + ), + migrations.AddField( + model_name='editorialdecision', + name='version', + field=models.SmallIntegerField(default=1), + ), + migrations.AlterUniqueTogether( + name='editorialdecision', + unique_together={('submission', 'version')}, + ), + ] diff --git a/submissions/migrations/0081_auto_20191026_1828.py b/submissions/migrations/0081_auto_20191026_1828.py new file mode 100644 index 000000000..290c600f1 --- /dev/null +++ b/submissions/migrations/0081_auto_20191026_1828.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.8 on 2019-10-26 16:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('submissions', '0080_auto_20191026_1736'), + ] + + operations = [ + migrations.AlterField( + model_name='submission', + name='status', + field=models.CharField(choices=[('incoming', 'Submission incoming, undergoing pre-screening'), ('unassigned', 'Unassigned, awaiting editor assignment'), ('failed_pre', 'Failed pre-screening'), ('assigned', 'Editor-in-charge assigned'), ('assignment_failed', 'Failed to assign Editor-in-charge; manuscript rejected'), ('resubmitted', 'Has been resubmitted'), ('accepted', 'Publication decision taken: accept'), ('puboffer_waiting', 'Accepted in other journal; awaiting puboffer acceptance'), ('rejected', 'Publication decision taken: reject'), ('withdrawn', 'Withdrawn by the Authors'), ('published', 'Published')], default='incoming', max_length=30), + ), + ] diff --git a/submissions/mixins.py b/submissions/mixins.py index 1c6eb19d2..fe3b9e3c8 100644 --- a/submissions/mixins.py +++ b/submissions/mixins.py @@ -4,6 +4,7 @@ __license__ = "AGPL v3" from django.core.exceptions import ImproperlyConfigured from django.contrib.auth.mixins import PermissionRequiredMixin +from django.shortcuts import get_object_or_404 from django.views.generic.list import ListView from .models import Submission @@ -26,6 +27,25 @@ class FriendlyPermissionMixin(PermissionRequiredMixin): return super().dispatch(request, *args, **kwargs) +class SubmissionMixin: + """Provides submission as self.submission for get, post and in context.""" + + def get(self, request, *args, **kwargs): + self.submission = get_object_or_404( + Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) + return super().get(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + self.submission = get_object_or_404( + Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) + return super().post(request, *args, **kwargs) + + def get_context_data(self, *args, **kwargs): + context = super().get_context_data(*args, **kwargs) + context['submission'] = self.submission + return context + + class SubmissionFormViewMixin: def get_success_url(self): if not self.success_url: diff --git a/submissions/models.py b/submissions/models.py index 44fec59ae..cccf82350 100644 --- a/submissions/models.py +++ b/submissions/models.py @@ -410,6 +410,10 @@ class Submission(models.Model): fellowships__pool=self).values_list('id', flat=True) return self.editor_in_charge.id not in pool_contributors_ids + @property + def editorial_decision(self): + """Returns the EditorialDecision (if exists and not deprecated).""" + return self.editorialdecision_set.last() class SubmissionEvent(SubmissionRelatedObjectMixin, TimeStampedModel): @@ -1086,8 +1090,11 @@ class EditorialDecision(models.Model): remarks_for_editorial_college = models.TextField( blank=True, verbose_name='optional remarks for the Editorial College') status = models.SmallIntegerField(choices=EDITORIAL_DECISION_STATUSES) + version = models.SmallIntegerField(default=1) class Meta: + ordering = ['version'] + unique_together = ['submission', 'version'] verbose_name = 'Editorial Decision' verbose_name_plural = 'Editorial Decisions' @@ -1098,8 +1105,7 @@ class EditorialDecision(models.Model): def get_absolute_url(self): return reverse('submissions:editorial_decision_detail', - kwargs={'identifier_w_vn_nr': self.submission.preprint.identifier_w_vn_nr, - 'pk': self.id}) + kwargs={'identifier_w_vn_nr': self.submission.preprint.identifier_w_vn_nr}) @property def publish(self): diff --git a/submissions/templates/partials/submissions/pool/submission_details.html b/submissions/templates/partials/submissions/pool/submission_details.html index bf8f221e8..38f75ecb3 100644 --- a/submissions/templates/partials/submissions/pool/submission_details.html +++ b/submissions/templates/partials/submissions/pool/submission_details.html @@ -97,7 +97,7 @@ <li>See Editorial Recommendations:</li> <ul class="pl-3"> {% for rec in submission.eicrecommendations.all %} - <li><a href="{% url 'submissions:eic_recommendation_detail' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr rec_id=rec.id %}">{{rec.get_recommendation_display}}</a></li> + <li><a href="{% url 'submissions:eic_recommendation_detail' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}">{{ rec.get_recommendation_display }}</a></li> {% endfor %} </ul> {% endif %} diff --git a/submissions/templates/partials/submissions/submission_author_information.html b/submissions/templates/partials/submissions/submission_author_information.html index c4d8ab78b..cf010878f 100644 --- a/submissions/templates/partials/submissions/submission_author_information.html +++ b/submissions/templates/partials/submissions/submission_author_information.html @@ -46,6 +46,18 @@ {% endif %} </td> </tr> + <tr> + <td>Submission is current version:</td> + <td> + {% if submission.is_current %} + <i class="fa fa-check-circle text-success" aria-hidden="true"></i> + <span class="text-muted">This is the current version.</span> + {% else %} + <i class="fa fa-times-circle text-danger" aria-hidden="true"></i> + <span class="text-muted">This is not the current version.</span> + {% endif %} + </td> + </tr> {% if submission.publication and submission.publication.is_published %} <tr> <td>Submission is published as:</td> @@ -65,13 +77,13 @@ {% for recommendation in submission.eicrecommendations.active %} {% include 'partials/submissions/recommendation_author_content.html' with recommendation=recommendation %} {% empty %} - No Editorial Recommendation is formulated yet. The editor will formulate the Editorial Recommendation after all Reports have been received. + No Editorial Recommendation has yet been formulated. {% endfor %} </div> {% endif %} <div class="mb-4"> - <h4>Communication</h4> + <h4>Communications</h4> <div id="communications"> {% if submission.editor_in_charge %} <a href="{% url 'submissions:communication' submission.preprint.identifier_w_vn_nr 'AtoE' %}">Write to the Editor-in-charge</a> diff --git a/submissions/templates/partials/submissions/submission_editorial_information.html b/submissions/templates/partials/submissions/submission_editorial_information.html index b19b77035..8dc92fb19 100644 --- a/submissions/templates/partials/submissions/submission_editorial_information.html +++ b/submissions/templates/partials/submissions/submission_editorial_information.html @@ -1,7 +1,8 @@ {% load bootstrap %} -<h3>Editorial information</h3> -<button type="button" class="btn btn-link d-block mb-2" data-toggle="toggle" data-target="#editorialinformation"><small>Show/hide editorial information</small></button> +<h3 class="highlight"> + Editorial information  <button type="button" class="btn btn-primary px-1 py-0" data-toggle="toggle" data-target="#editorialinformation"><small>Show/hide</small></button> +</h3> <div id="editorialinformation" class="mt-2" style="display:none;"> <div class="mb-4"> @@ -27,6 +28,18 @@ {% endif %} </td> </tr> + <tr> + <td>Editorial decision:</td> + <td> + {% if submission.editorial_decision %} + For Journal {{ submission.editorial_decision.for_journal }}: {{ submission.editorial_decision.get_decision_display }} + <br> + (status: {{ submission.editorial_decision.get_status_display }}) + {% else %} + <span class="label label-secondary">No Editorial Decision has been taken yet.</span> + {% endif %} + </td> + </tr> <tr> <td>Submission is publicly available:</td> <td> @@ -69,10 +82,17 @@ {% for recommendation in submission.eicrecommendations.active %} {% include 'partials/submissions/recommendation_author_content.html' with recommendation=recommendation %} {% empty %} - No Editorial Recommendation is formulated yet. + No Editorial Recommendation has yet been formulated. {% endfor %} </div> + <div class="mb-4"> + <h4>Communications</h4> + <div id="communications"> + {% include 'partials/submissions/communication_thread.html' with communication=submission.editorial_communications.for_authors css_class='wide' %} + </div> + </div> + <div class="mb-4"> <h3>Events:</h3> <div id="eventslist"> diff --git a/submissions/templates/partials/submissions/submission_summary.html b/submissions/templates/partials/submissions/submission_summary.html index 3375f44ad..ddd5c3272 100644 --- a/submissions/templates/partials/submissions/submission_summary.html +++ b/submissions/templates/partials/submissions/submission_summary.html @@ -2,18 +2,18 @@ {% if not hide_title %} <tr> <td>Title:</td> - <td>{{submission.title}}</td> + <td>{{ submission.title }}</td> </tr> <tr> <td>Author(s):</td> - <td>{{submission.author_list}}</td> + <td>{{ submission.author_list }}</td> </tr> {% endif %} <tr> <td>As Contributors:</td> <td> {% for author in submission.authors.all %} - {% if not forloop.first %}<span class="text-blue">·</span> {% endif %}<a href="{% url 'scipost:contributor_info' author.id %}">{{author.user.first_name}} {{author.user.last_name}}</a> + {% if not forloop.first %}<span class="text-blue">·</span> {% endif %}<a href="{% url 'scipost:contributor_info' author.id %}">{{ author.user.first_name }} {{ author.user.last_name }}</a> {% empty %} (none claimed) {% endfor %} @@ -23,7 +23,7 @@ <tr> <td>Arxiv Link:</td> <td> - <a href="{{submission.preprint.url}}" target="_blank">{{submission.preprint.url}}</a> + <a href="{{ submission.preprint.url }}" target="_blank">{{ submission.preprint.url }}</a> </td> </tr> {% elif submission.preprint.get_absolute_url %} @@ -37,20 +37,20 @@ {% if submission.acceptance_date %} <tr> <td>Date accepted:</td> - <td>{{submission.acceptance_date}}</td> + <td>{{ submission.acceptance_date }}</td> </tr> {% endif %} <tr> <td>Date submitted:</td> - <td>{{submission.submission_date}}</td> + <td>{{ submission.submission_date }}</td> </tr> <tr> <td>Submitted by:</td> - <td>{{submission.submitted_by}}</td> + <td>{{ submission.submitted_by }}</td> </tr> <tr> <td>Submitted to:</td> - <td>{{submission.submitted_to}}</td> + <td>{{ submission.submitted_to }}</td> </tr> {% if submission.proceedings %} <tr> @@ -64,7 +64,7 @@ </tr> <tr> <td>Subject area:</td> - <td>{{submission.get_subject_area_display}}</td> + <td>{{ submission.get_subject_area_display }}</td> </tr> {% if submission.approaches %} <tr> @@ -81,5 +81,5 @@ </p> {% endif %} <h3 class="mt-4">Abstract</h3> - <p>{{submission.abstract}}</p> + <p>{{ submission.abstract }}</p> {% endif %} diff --git a/submissions/templates/submissions/admin/_editorial_decision_as_table.html b/submissions/templates/submissions/admin/_editorial_decision_as_table.html index 9a0cd39a4..697dccd50 100644 --- a/submissions/templates/submissions/admin/_editorial_decision_as_table.html +++ b/submissions/templates/submissions/admin/_editorial_decision_as_table.html @@ -18,6 +18,9 @@ <tr> <td>Status</td><td>{{ decision.get_status_display }}</td> </tr> + <tr> + <td>Version</td><td>{{ decision.version }}</td> + </tr> <tr> <td>Remarks for authors</td><td>{{ decision.remarks_for_authors|automarkup }}</td> </tr> diff --git a/submissions/templates/submissions/admin/editorial_decision_detail.html b/submissions/templates/submissions/admin/editorial_decision_detail.html index 599e27a1f..869c95dc3 100644 --- a/submissions/templates/submissions/admin/editorial_decision_detail.html +++ b/submissions/templates/submissions/admin/editorial_decision_detail.html @@ -21,10 +21,10 @@ <ul class="list-unstyled"> <li class="list-item my-2"> - <a class="btn btn-warning" href="{% url 'submissions:editorial_decision_update' identifier_w_vn_nr=decision.submission.preprint.identifier_w_vn_nr pk=decision.id %}">Update this decision</a> + <a class="btn btn-warning" href="{% url 'submissions:editorial_decision_update' identifier_w_vn_nr=decision.submission.preprint.identifier_w_vn_nr %}">Update this decision</a> </li> <li class="list-item my-2"> - <a class="btn btn-danger" href="{% url 'submissions:fix_editorial_decision' identifier_w_vn_nr=decision.submission.preprint.identifier_w_vn_nr pk=decision.id %}">Fix this decision</a> + <a class="btn btn-danger" href="{% url 'submissions:fix_editorial_decision' identifier_w_vn_nr=decision.submission.preprint.identifier_w_vn_nr %}">Fix this decision</a> <span class="text-danger"> <strong>CAREFUL: MAKE SURE YOU KNOW EXACTLY WHAT YOU ARE DOING.</strong> <br> diff --git a/submissions/templates/submissions/admin/editorial_decision_form.html b/submissions/templates/submissions/admin/editorial_decision_form.html index 3e887bf0b..268369da7 100644 --- a/submissions/templates/submissions/admin/editorial_decision_form.html +++ b/submissions/templates/submissions/admin/editorial_decision_form.html @@ -26,7 +26,7 @@ <a class="d-inline-block mb-3" href="{{ submission.get_absolute_url }}" target="_blank">View Reports and Submission details</a> </li> <li> - <a href="{% url 'submissions:eic_recommendation_detail' submission.preprint.identifier_w_vn_nr submission.eicrecommendations.last.id %}" target="_blank">View the Recommendations and Voting results</a> + <a href="{% url 'submissions:eic_recommendation_detail' submission.preprint.identifier_w_vn_nr %}" target="_blank">View the Recommendations and Voting results</a> </li> </ul> diff --git a/submissions/templates/submissions/pool/pool.html b/submissions/templates/submissions/pool/pool.html index c2d313c83..31d8eaee4 100644 --- a/submissions/templates/submissions/pool/pool.html +++ b/submissions/templates/submissions/pool/pool.html @@ -77,7 +77,7 @@ <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.preprint.identifier_w_vn_nr recommendation.id %}">See Editorial Recommendation</a> + <a href="{% url 'submissions:eic_recommendation_detail' recommendation.submission.preprint.identifier_w_vn_nr %}">See Editorial Recommendation</a> </li> {% endfor %} </ul> diff --git a/submissions/templates/submissions/submission_detail.html b/submissions/templates/submissions/submission_detail.html index 6450bd778..df8dbcee2 100644 --- a/submissions/templates/submissions/submission_detail.html +++ b/submissions/templates/submissions/submission_detail.html @@ -94,6 +94,16 @@ {% include 'partials/submissions/submission_topics.html' with submission=submission %} <br/> + {% if submission.editorial_decision %} + <h3 class="highlight">Editorial decision</h3> + <p>For Journal {{ submission.editorial_decision.for_journal }}: {{ submission.editorial_decision.get_decision_display }}<br>(status: {{ submission.editorial_decision.get_status_display }})</p> + {% if is_author and submission.editorial_decision.status == submission.editorial_decision.AWAITING_PUBOFFER_ACCEPTANCE %} + <p>Message from Editorial Administration: we are awaiting your response to the publication offer.</p> + {% endif %} + {% endif %} + + <br> + <hr> {% if submission.author_comments %} <h3>Author comments upon resubmission</h3> <div class="blockquote"> diff --git a/submissions/urls.py b/submissions/urls.py index ca1198395..91d138031 100644 --- a/submissions/urls.py +++ b/submissions/urls.py @@ -66,29 +66,30 @@ urlpatterns = [ # url(r'^admin/{regex}/recommendations/(?P<rec_id>[0-9]+)$'.format( # regex=SUBMISSIONS_COMPLETE_REGEX), views.EICRecommendationView.as_view(), # name='eic_recommendation_detail'), - url(r'^admin/{regex}/recommendations/(?P<rec_id>[0-9]+)$'.format( + # url(r'^admin/{regex}/recommendations/(?P<rec_id>[0-9]+)$'.format( + url(r'^admin/{regex}/recommendation$'.format( regex=SUBMISSIONS_COMPLETE_REGEX), views.EICRecommendationDetailView.as_view(), name='eic_recommendation_detail'), url( - r'^admin/{regex}/editorial_decision/create/$'.format( + r'^admin/{regex}/editorial_decision/create$'.format( regex=SUBMISSIONS_COMPLETE_REGEX), views.EditorialDecisionCreateView.as_view(), name='editorial_decision_create' ), url( - r'^admin/{regex}/editorial_decision/(?P<pk>[0-9]+)/$'.format( + r'^admin/{regex}/editorial_decision$'.format( regex=SUBMISSIONS_COMPLETE_REGEX), views.EditorialDecisionDetailView.as_view(), name='editorial_decision_detail' ), url( - r'^admin/{regex}/editorial_decision/(?P<pk>[0-9]+)/update/$'.format( + r'^admin/{regex}/editorial_decision/update$'.format( regex=SUBMISSIONS_COMPLETE_REGEX), views.EditorialDecisionUpdateView.as_view(), name='editorial_decision_update' ), url( - r'^admin/{regex}/editorial_decision/(?P<pk>[0-9]+)/fix/$'.format( + r'^admin/{regex}/editorial_decision/fix$'.format( regex=SUBMISSIONS_COMPLETE_REGEX), views.fix_editorial_decision, name='fix_editorial_decision' diff --git a/submissions/views.py b/submissions/views.py index 3000311de..0017d4cf3 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -25,7 +25,8 @@ from django.views.generic.edit import CreateView, UpdateView from django.views.generic.list import ListView from .constants import ( - STATUS_ACCEPTED, STATUS_REJECTED, STATUS_VETTED, SUBMISSION_STATUS, STATUS_ASSIGNMENT_FAILED, + STATUS_ACCEPTED_AWAITING_PUBOFFER_ACCEPTANCE, STATUS_ACCEPTED, STATUS_REJECTED, + STATUS_VETTED, SUBMISSION_STATUS, STATUS_ASSIGNMENT_FAILED, STATUS_DRAFT, CYCLE_DIRECT_REC, STATUS_COMPLETED, STATUS_DEPRECATED, EIC_REC_PUBLISH, EIC_REC_REJECT, DECISION_FIXED) from .helpers import check_verified_author, check_unverified_author @@ -33,7 +34,7 @@ from .models import ( Submission, EICRecommendation, SubmissionTiering, AlternativeRecommendation, EditorialDecision, EditorialAssignment, RefereeInvitation, Report, SubmissionEvent) -from .mixins import SubmissionAdminViewMixin +from .mixins import SubmissionMixin, SubmissionAdminViewMixin from .forms import ( SubmissionIdentifierForm, SubmissionForm, SubmissionSearchForm, RecommendationVoteForm, ConsiderAssignmentForm, InviteEditorialAssignmentForm, EditorialAssignmentForm, VetReportForm, @@ -1956,11 +1957,12 @@ class SubmissionConflictsView(SubmissionAdminViewMixin, DetailView): # return HttpResponseRedirect(self.success_url) -class EICRecommendationDetailView(UserPassesTestMixin, DetailView): - """EICRecommendation detail page, visible to EdAdmin, voting Fellows (NOT authors).""" +class EICRecommendationDetailView(SubmissionMixin, LoginRequiredMixin, + UserPassesTestMixin, DetailView): + """EICRecommendation detail page, visible to EdAdmin, voting Fellows (but NOT authors).""" model = EICRecommendation - pk_url_kwarg = 'rec_id' + # pk_url_kwarg = 'rec_id' template_name = 'submissions/pool/recommendation.html' context_object_name = 'recommendation' @@ -1968,15 +1970,35 @@ class EICRecommendationDetailView(UserPassesTestMixin, DetailView): """Grants access to EdAdmin, voting Fellows and authors.""" if self.request.user.has_perm('scipost.can_fix_College_decision'): return True - eicrec = get_object_or_404(EICRecommendation, pk=self.kwargs.get('rec_id')) + # eicrec = get_object_or_404(EICRecommendation, pk=self.kwargs.get('rec_id')) + submission = get_object_or_404( + Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) + eicrec = submission.eicrecommendations.last() if eicrec.eligible_to_vote.filter(user=self.request.user).exists(): return True - # if eicrec.submission.authors.filter(user=self.request.user).exists(): - # return True return False + # def get(self, request, *args, **kwargs): + # self.submission = get_object_or_404( + # Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) + # return super().get(request, *args, **kwargs) + + # def post(self, request, *args, **kwargs): + # self.submission = get_object_or_404( + # Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) + # return super().post(request, *args, **kwargs) -class EditorialDecisionCreateView(PermissionsMixin, CreateView): + # def get_context_data(self, *args, **kwargs): + # context = super().get_context_data(*args, **kwargs) + # context['submission'] = self.submission + # return context + + def get_object(self): + """Return the latest version of the EICRecommendation associated to this Submission.""" + return self.submission.eicrecommendations.last() + + +class EditorialDecisionCreateView(SubmissionMixin, PermissionsMixin, CreateView): """For EdAdmin to create the editorial decision on a Submission, after voting is completed. The complete workflow involves drafting the decision with this view, @@ -1989,20 +2011,20 @@ class EditorialDecisionCreateView(PermissionsMixin, CreateView): form_class = EditorialDecisionForm template_name = 'submissions/admin/editorial_decision_form.html' - def get(self, request, *args, **kwargs): - self.submission = get_object_or_404( - Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) - return super().get(request, *args, **kwargs) + # def get(self, request, *args, **kwargs): + # self.submission = get_object_or_404( + # Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) + # return super().get(request, *args, **kwargs) - def post(self, request, *args, **kwargs): - self.submission = get_object_or_404( - Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) - return super().post(request, *args, **kwargs) + # def post(self, request, *args, **kwargs): + # self.submission = get_object_or_404( + # Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) + # return super().post(request, *args, **kwargs) - def get_context_data(self, *args, **kwargs): - context = super().get_context_data(*args, **kwargs) - context['submission'] = self.submission - return context + # def get_context_data(self, *args, **kwargs): + # context = super().get_context_data(*args, **kwargs) + # context['submission'] = self.submission + # return context def get_initial(self, *args, **kwargs): initial = super().get_initial(*args, **kwargs) @@ -2020,15 +2042,23 @@ class EditorialDecisionCreateView(PermissionsMixin, CreateView): return initial -class EditorialDecisionDetailView(PermissionsMixin, DetailView): +class EditorialDecisionDetailView(SubmissionMixin, PermissionsMixin, DetailView): permission_required = 'scipost.can_fix_College_decision' model = EditorialDecision context_object_name = 'decision' template_name = 'submissions/admin/editorial_decision_detail.html' + def get_object(self): + try: + return self.submission.editorial_decision + except EditorialDecision.DoesNotExist: + return render(self.request, 'scipost/error.html', + {'errormessage', + 'No editorial decision has yet been taken on this Submission.'}) -class EditorialDecisionUpdateView(PermissionsMixin, UpdateView): + +class EditorialDecisionUpdateView(SubmissionMixin, PermissionsMixin, UpdateView): permission_required = 'scipost.can_fix_College_decision' model = EditorialDecision @@ -2036,25 +2066,33 @@ class EditorialDecisionUpdateView(PermissionsMixin, UpdateView): form_class = EditorialDecisionForm template_name = 'submissions/admin/editorial_decision_form.html' - def get(self, request, *args, **kwargs): - self.submission = get_object_or_404( - Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) - return super().get(request, *args, **kwargs) + # def get(self, request, *args, **kwargs): + # self.submission = get_object_or_404( + # Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) + # return super().get(request, *args, **kwargs) - def post(self, request, *args, **kwargs): - self.submission = get_object_or_404( - Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) - return super().post(request, *args, **kwargs) + # def post(self, request, *args, **kwargs): + # self.submission = get_object_or_404( + # Submission, preprint__identifier_w_vn_nr=kwargs.get('identifier_w_vn_nr')) + # return super().post(request, *args, **kwargs) - def get_context_data(self, *args, **kwargs): - context = super().get_context_data(*args, **kwargs) - context['submission'] = self.submission - return context + # def get_context_data(self, *args, **kwargs): + # context = super().get_context_data(*args, **kwargs) + # context['submission'] = self.submission + # return context + + def get_object(self): + try: + return self.submission.editorial_decision + except EditorialDecision.DoesNotExist: + return render(self.request, 'scipost/error.html', + {'errormessage', + 'No editorial decision has yet been taken on this Submission.'}) @login_required @permission_required('scipost.can_fix_College_decision') -def fix_editorial_decision(request, identifier_w_vn_nr, pk): +def fix_editorial_decision(request, identifier_w_vn_nr): """Fix the editorial decision, which is then final. Email authors. This is the method completing the editorial decision process. @@ -2063,20 +2101,18 @@ def fix_editorial_decision(request, identifier_w_vn_nr, pk): """ submission = get_object_or_404(Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr) - decision = get_object_or_404(EditorialDecision, pk=pk) - if submission != decision.submission: - errormessage = ('The Submission from the url and that of the Editorial Decision' - ' do not correspond to each other. Please update the Decision or' - ' contect techsupport.') - return render(request, 'scipost/error.html', {'errormessage', errormessage}) + decision = submission.editorial_decision # Set latest EICRecommedation to DECISION_FIXED eicrec = submission.eicrecommendations.last() eicrec.status = DECISION_FIXED eicrec.save() if decision.decision == EIC_REC_PUBLISH: + new_sub_status = STATUS_ACCEPTED + if decision.for_journal != submission.submitted_to: + new_sub_status = STATUS_ACCEPTED_AWAITING_PUBOFFER_ACCEPTANCE Submission.objects.filter(id=submission.id).update( - visible_public=True, status=STATUS_ACCEPTED, acceptance_date=datetime.date.today(), + visible_public=True, status=new_sub_status, acceptance_date=datetime.date.today(), latest_activity=timezone.now()) # Start a new ProductionStream @@ -2098,20 +2134,24 @@ def fix_editorial_decision(request, identifier_w_vn_nr, pk): EditorialAssignment.objects.filter( submission=submission, to=submission.editor_in_charge).update(status=STATUS_COMPLETED) - # Add SubmissionEvent for authors - submission.add_event_for_author( - 'The Editorial Decision has been fixed: {0}.'.format( - decision.get_decision_display())) - submission.add_event_for_eic( - 'The Editorial Decision has been fixed: {0}.'.format( - decision.get_decision_display())) - mail_request = MailEditorSubview( request, mail_code='authors/inform_authors_editorial_decision', decision=decision) if mail_request.is_valid(): messages.success(request, 'Authors have been emailed about the decision') mail_request.send_mail() + if decision.for_journal == submission.submitted_to: + decision.status = EditorialDecision.FIXED_AND_ACCEPTED + else: + decision.status = EditorialDecision.AWAITING_PUBOFFER_ACCEPTANCE + decision.save() + submission.add_event_for_author( + 'The Editorial Decision has been fixed: %s (with status: %s).' % ( + decision.get_decision_display(), decision.get_status_display())) + submission.add_event_for_eic( + 'The Editorial Decision has been fixed: %s (with status: %s).' % ( + decision.get_decision_display(), decision.get_status_display())) + return redirect('submissions:pool') else: return mail_request.interrupt() diff --git a/templates/email/authors/inform_authors_editorial_decision.html b/templates/email/authors/inform_authors_editorial_decision.html index ea9d7fe31..e473fd8fc 100644 --- a/templates/email/authors/inform_authors_editorial_decision.html +++ b/templates/email/authors/inform_authors_editorial_decision.html @@ -23,7 +23,7 @@ </p> {% else %} {% if decision.publish %} - {% if decision.status == decision.FIXED_AND_ACCEPTED %} + {% if decision.for_journal == decision.submission.submitted_to %} <p> We are pleased to let you know that your manuscript has been accepted for publication in {{ decision.submission.submitted_to }}. @@ -32,7 +32,7 @@ Your manuscript will now be taken charge of by our production team, which will soon send you proofs to check before final publication. </p> - {% elif decision.status == decision.AWAITING_PUBOFFER_ACCEPTANCE %} + {% else %} <p> We would like to offer you publication of your manuscript in {{ decision.for_journal }} (you had originally submitted -- GitLab