diff --git a/scipost/templates/scipost/personal_page.html b/scipost/templates/scipost/personal_page.html index dcbfd1a99dabff106a3e63dde117c1b8678de710..11b784cc34743d3c20fff6077f08533fad812da4 100644 --- a/scipost/templates/scipost/personal_page.html +++ b/scipost/templates/scipost/personal_page.html @@ -158,10 +158,13 @@ </ul> </div> {% if pending_ref_tasks %} - <h3>Refereeing tasks to fulfill: please provide a Report on the following Submissions</h3> + <h3>Pending Refereeing Tasks:</h3> <ul> {% for task in pending_ref_tasks %} - {{ task.submission.header_as_li|safe }} + <li>{{ task.submission }}, due {{ task.submission.reporting_deadline }}. + <a href="{% url 'submissions:submit_report' submission_id=task.submission.id %}">Submit your Report</a>. + <a href="{% url 'submissions:communication' submission_id=task.submission.id type='RtoE' %}">Write to the Editor-in-charge</a>. + </li> {% endfor %} </ul> {% endif %} diff --git a/submissions/forms.py b/submissions/forms.py index ff2c0238402f7c05172379c7d9d4702460fd066a..925de1bce0be8e86572cc251dcc9854644d8c849 100644 --- a/submissions/forms.py +++ b/submissions/forms.py @@ -129,3 +129,19 @@ class EditorialCommunicationForm(forms.Form): def __init__(self, *args, **kwargs): super(EditorialCommunicationForm, self).__init__(*args, **kwargs) self.fields['text'].widget.attrs.update({'rows': 5, 'cols': 50, 'placeholder': 'Write your message in this box.'}) + + + +###################### +# EIC Recommendation # +###################### + +class EICRecommendationForm(forms.ModelForm): + class Meta: + model = EICRecommendation + fields = ['remarks_for_authors', 'requested_changes', 'recommendation', 'remarks_for_editorial_college'] + def __init__(self, *args, **kwargs): + super(EICRecommendationForm, self).__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.'}) diff --git a/submissions/models.py b/submissions/models.py index 414d7d1f482fc259ded75f942df9eb8dd9162dd4..46c7bd075c3b2ac8fbc4618d826ccaf8b8093001 100644 --- a/submissions/models.py +++ b/submissions/models.py @@ -63,7 +63,7 @@ class Submission(models.Model): latest_activity = models.DateTimeField(default=timezone.now) def __str__ (self): - return self.title[:30] + return self.title[:30] + ' by ' + self.author_list[:30] @property def reporting_deadline_has_passed(self): @@ -320,9 +320,9 @@ class Report(models.Model): return mark_safe(output) -########################### -# EditorialCorrespondence # -########################### +########################## +# EditorialCommunication # +########################## ED_CORR_CHOICES = ( ('EtoA', 'Editor-in-charge to Author'), @@ -346,4 +346,61 @@ class EditorialCommunication(models.Model): text = models.TextField() def __str__ (self): - return self.type + ' for submission ' + self.submission.title[:30] + ' by ' + self.submission.author_list[:30] + output = self.type + if self.referee is not None: + output += ' ' + self.referee.user.first_name + ' ' + self.referee.user.last_name + output += ' for submission ' + self.submission.title[:30] + ' by ' + self.submission.author_list[:30] + return output + + def print_contents_as_li(self): + output = '<li><p>' + if self.type == 'EtoA': + output += 'From you to Authors' + elif self.type == 'EtoR': + output += 'From you to Referee ' + try: + output += self.referee.user.first_name + ' ' + self.referee.user.last_name + except AttributeError: + pass + elif self.type == 'EtoS': + output += 'From you to SciPost Ed Admin' + elif self.type == 'AtoE': + output += 'From Authors to you' + elif self.type == 'RtoE': + output += 'From Referee ' + try: + output += self.referee.user.first_name + ' ' + self.referee.user.last_name + ' to you' + except AttributeError: + pass + elif self.type == 'StoE': + output += 'From SciPost Ed Admin to you' + output += ' on ' + self.timestamp.strftime("%Y-%m-%d %H:%M") + '</p>' + output += '<p>' + self.text + '</p>' + return mark_safe(output) + + + +############################ +# Editorial Recommendation # +############################ + +# From the Editor-in-charge of a Submission +class EICRecommendation(models.Model): + submission = models.ForeignKey(Submission) + date_submitted = models.DateTimeField('date submitted') + remarks_for_authors = models.TextField(blank=True, null=True) + requested_changes = models.TextField(verbose_name="requested changes", blank=True, null=True) + remarks_for_editorial_college = models.TextField(default='', blank=True, null=True, verbose_name='optional remarks for the Editorial College') + recommendation = models.SmallIntegerField(choices=REPORT_REC) + # Editorial Fellows who have assessed this recommendation: + voted_for = models.ManyToManyField (Contributor, blank=True, related_name='voted_for') + voted_against = models.ManyToManyField (Contributor, blank=True, related_name='voted_against') + voting_deadline = models.DateTimeField('date submitted', default=timezone.now) + + @property + def nr_for(self): + return self.voted_for.count() + + @property + def nr_against(self): + return self.voted_against.count() diff --git a/submissions/templates/submissions/editorial_page.html b/submissions/templates/submissions/editorial_page.html index 90e9afca8244ae19b5152da72ee87eb1c9cbfb5a..6c187817a23789fcac1a92ca9a5fa3e0c84d0a6d 100644 --- a/submissions/templates/submissions/editorial_page.html +++ b/submissions/templates/submissions/editorial_page.html @@ -66,12 +66,19 @@ </ul> </li> <li><a href="{% url 'submissions:communication' submission_id=submission.id type='EtoS' %}">Communicate with SciPost Editorial Administration</a></li> - <li>Formulate an Editorial Recommendation and send it to Editorial College for ratification</li> - <li>Inform authors of Editorial Decisions</li> + <li><a href="{% url 'submissions:eic_recommendation' submission_id=submission.id %}">Formulate an Editorial Recommendation</a> + <p>If you recommend revisions, this will be communicated directly to the Authors, who will be asked to resubmit. + <br/>If you recommend acceptance or rejection, this will be put to the Editorial College for ratification.</p> + </li> + <li>Inform authors of Editorial Decision</li> </ul> - <hr class="hr6"/> - <h3>Refereeing invitations</h3> +</section> + +<section> + <div class="flex-greybox"> + <h1>Refereeing invitations</h1> + </div> {% if ref_invitations %} <ul> {% for invitation in ref_invitations %} @@ -81,6 +88,22 @@ {% else %} <p>You have not invited any referees yet.</p> {% endif %} + +</section> + +<section> + <div class="flex-greybox"> + <h1>Communications</h1> + </div> + {% if communications %} + <ul> + {% for comm in communications %} + {{ comm.print_contents_as_li }} + {% endfor %} + </ul> + {% else %} + <p>There have been no communications for this Submission.</p> + {% endif %} </section> {% endif %} <!-- Temporary strip --> diff --git a/submissions/templates/submissions/eic_recommendation.html b/submissions/templates/submissions/eic_recommendation.html new file mode 100644 index 0000000000000000000000000000000000000000..0882b36a484d8106322f57c53e77fcefec98cdd5 --- /dev/null +++ b/submissions/templates/submissions/eic_recommendation.html @@ -0,0 +1,54 @@ +{% extends 'scipost/base.html' %} + +{% block pagetitle %}: editorial recommendation for submission{% endblock pagetitle %} + +{% block headsup %} + +{% load scipost_extras %} + +{% endblock headsup %} + +{% block bodysup %} + +<!-- Temporary strip --> +{% if user.is_authenticated %} + +<section> + <div class="flex-greybox"> + <h1>Formulate Editorial Recommendation for Submission</h1> + <h3>(go to the <a href="{% url 'submissions:submission' submission_id=submission.id %}">Submissions Page</a> to view Reports and Comments)</h3> + <h3>(go back to the <a href="{% url 'submissions:editorial_page' submission_id=submission.id %}">Editorial Page</a> to take editorial actions)</h3> + </div> + + <hr class="hr12"> + <div class="row"> + <div class="col-4"> + <h2>Submission:</h2> + </div> + </div> + {{ submission.header_as_table|safe }} + <h3>Abstract:</h3> + <p>{{ submission.abstract }}</p> + +</section> + + +<section> + <div class="flex-greybox"> + <h1>Your Editorial Recommendation (to be forwarded to the Editorial College for ratification)</h1> + </div> + + <form action="{% url 'submissions:eic_recommendation' submission_id=submission.id %}" method="post"> + {% csrf_token %} + <table> + <ul> + {{ form.as_table }} + </ul> + </table> + <input type="submit" value="Submit"/> + </form> +</section> + +{% endif %} <!-- Temporary strip --> + +{% endblock bodysup %} diff --git a/submissions/urls.py b/submissions/urls.py index e2e14c362d379ec6b1602af2808e4a31af0dc298..9b5ccfffdea2167a3fbc2d78e47f989f231897c5 100644 --- a/submissions/urls.py +++ b/submissions/urls.py @@ -26,6 +26,7 @@ urlpatterns = [ url(r'^close_refereeing_round/(?P<submission_id>[0-9]+)$', views.close_refereeing_round, name='close_refereeing_round'), url(r'^communication/(?P<submission_id>[0-9]+)/(?P<type>[a-zA-Z]{4,})$', views.communication, name='communication'), url(r'^communication/(?P<submission_id>[0-9]+)/(?P<type>[a-zA-Z]{4,})/(?P<referee_id>[0-9]+)$', views.communication, name='communication'), + url(r'^eic_recommendation/(?P<submission_id>[0-9]+)$', views.eic_recommendation, name='eic_recommendation'), # Reports url(r'^submit_report/(?P<submission_id>[0-9]+)$', views.submit_report, name='submit_report'), url(r'^submit_report_ack$', TemplateView.as_view(template_name='submissions/submit_report_ack.html'), name='submit_report_ack'), diff --git a/submissions/views.py b/submissions/views.py index 8160a1b78eb83a9b7426cff72e592703294ad91e..a2defe199b0dc7018b0b876d31efce362015d133 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -222,8 +222,9 @@ def accept_or_decline_assignment_ack(request, assignment_id): def editorial_page(request, submission_id): submission = get_object_or_404(Submission, pk=submission_id) ref_invitations = RefereeInvitation.objects.filter(submission=submission) - - context = {'submission': submission, 'ref_invitations': ref_invitations} + + communications = EditorialCommunication.objects.filter(submission=submission).order_by('timestamp') + context = {'submission': submission, 'ref_invitations': ref_invitations, 'communications': communications} return render(request, 'submissions/editorial_page.html', context) @@ -358,6 +359,9 @@ def communication(request, submission_id, type, referee_id=None): type=type, timestamp=timezone.now(), text=form.cleaned_data['text']) + if referee_id is not None: + referee = get_object_or_404(Contributor, pk=referee_id) + communication.referee = referee communication.save() if type == 'EtoA' or type == 'EtoR' or type == 'EtoS': return redirect(reverse('submissions:editorial_page', kwargs={'submission_id': submission_id})) @@ -368,6 +372,26 @@ def communication(request, submission_id, type, referee_id=None): context = {'submission': submission, 'type': type, 'form': form} return render(request, 'submissions/communication.html', context) + +@permission_required('scipost.can_take_charge_of_submissions', raise_exception=True) +def eic_recommendation(request, submission_id): + submission = get_object_or_404 (Submission, pk=submission_id) + if request.method == 'POST': + form = EICRecommendationForm(request.POST) + if form.is_valid(): + recommendation = form.save() + recommendation.submission = submission + recommendation.date_submitted = timezone.now() + 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 + return redirect(reverse('submissions:editorial_page', kwargs={'submission_id': submission_id})) + else: + form = EICRecommendationForm() + context = {'submission': submission, 'form': form} + return render(request, 'submissions/eic_recommendation.html', context) + ########### # Reports