diff --git a/scipost/utils.py b/scipost/utils.py index 07da56a2a7a0f5c5eb0f312a2a4156112bade871..4e8236490f9f1dad43085a23b5d069b389b000f6 100644 --- a/scipost/utils.py +++ b/scipost/utils.py @@ -217,7 +217,7 @@ class Utils(BaseMailUtil): email_text_html += ',<br/>' if len(cls.invitation.personal_message) > 3: email_text += cls.invitation.personal_message + '\n\n' - email_text_html += '\n<i>{{ personal_message|linebreaks }}</i><br/>\n' + email_text_html += '\n{{ personal_message|linebreaks }}<br/>\n' email_context['personal_message'] = cls.invitation.personal_message # This text to be put in C, ci invitations @@ -304,6 +304,14 @@ class Utils(BaseMailUtil): 'https://scipost.org/invitation/' + cls.invitation.invitation_key + '\n\n' 'after which your registration will be activated, allowing you to contribute, ' 'in particular by providing referee reports.\n\n' + 'To ensure timely processing of the submission (out of respect for the authors), ' + 'we would appreciate a quick accept/decline ' + 'response from you, ideally within the next 2 days.\n\n' + 'If you are not able to provide a Report, you can let us know by simply ' + 'navigating to \n\nhttps://scipost.org/submissions/decline_ref_invitation/' + + cls.invitation.invitation_key + '\n\n' + 'If you are able to provide a Report, you can confirm this after registering ' + 'and logging in (you will automatically be prompted for a confirmation).\n\n' 'We very much hope that we can count on your expertise,\n\n' 'Many thanks in advance,\n\nThe SciPost Team') email_text_html += ( @@ -315,6 +323,15 @@ class Utils(BaseMailUtil): '<a href="https://scipost.org/invitation/{{ invitation_key }}">registration form</a> ' 'for you. After activation of your registration, you will be allowed to contribute, ' 'in particular by providing referee reports.</p>' + '<p>To ensure timely processing of the submission (out of respect for the authors), ' + 'we would appreciate a quick accept/decline ' + 'response from you, ideally within the next 2 days.</p>' + '<p>If you are <strong>not</strong> able to provide a Report, ' + 'you can let us know by simply ' + '<a href="https://scipost.org/submissions/decline_ref_invitation/{{ invitation_key }}>' + 'clicking here</a>.</p>' + '<p>If you are able to provide a Report, you can confirm this after registering ' + 'and logging in (you will automatically be prompted for a confirmation).</p>' '<p>We very much hope that we can count on your expertise,</p>' '<p>Many thanks in advance,</p>' '<p>The SciPost Team</p>') diff --git a/submissions/templates/submissions/decline_ref_invitation.html b/submissions/templates/submissions/decline_ref_invitation.html new file mode 100644 index 0000000000000000000000000000000000000000..9efedb177f5058eb3fbe73a51397de573d09391d --- /dev/null +++ b/submissions/templates/submissions/decline_ref_invitation.html @@ -0,0 +1,41 @@ +{% extends 'scipost/base.html' %} + +{% block pagetitle %}: decline refereeing invitation{% endblock pagetitle %} + +{% load bootstrap %} + +{% block content %} + +<script> +$(document).ready(function(){ + + $('[name="accept"]').on('change', function() { + if($('[name="accept"]:checked').val() == 'False') { + $('#id_refusal_reason').parents('.form-group').show(); + } + else { + $('#id_refusal_reason').parents('.form-group').hide(); + } + }).trigger('change'); + }); +</script> + + +<div class="row"> + <div class="col-12"> + <h1 class="highlight">SciPost Submission which you have been asked to Referee:</h1> + {% include 'submissions/_submission_summary.html' with submission=invitation.submission %} + </div> +</div> +<div class="row"> + <div class="col-12"> + <h3 class="highlight">You are choosing to decline this Refereeing Invitation</h3> + <form action="{% url 'submissions:decline_ref_invitation' invitation_key=invitation.invitation_key %}" method="post"> + {% csrf_token %} + {{ form|bootstrap }} + <input type="submit" class="btn btn-secondary" value="Submit" /> + </form> + </div> +</div> + +{% endblock content %} diff --git a/submissions/templates/submissions/refereeing_overview.html b/submissions/templates/submissions/refereeing_overview.html index bda7f5c3502d94e203179d0e8399c05cc5e93019..a7e09c540820a90a020a229f3f8bad204736186a 100644 --- a/submissions/templates/submissions/refereeing_overview.html +++ b/submissions/templates/submissions/refereeing_overview.html @@ -35,7 +35,7 @@ <h4>Refereeing status summary:</h4> {% include 'submissions/_submission_refereeing_status.html' with submission=submission %} <h3 class="mb-2">Detail of refereeing invitations:</h3> - {% include 'submissions/_submission_refereeing_invitations.html' with submission=submission invitations=ref_invitations %} + {% include 'submissions/_submission_refereeing_invitations.html' with submission=submission invitations=submission.referee_invitations.all %} <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='StoE' %}">Send a communication to the Editor-in-charge</a> </div> </div> diff --git a/submissions/urls.py b/submissions/urls.py index 48e208052b98fc264fd01f9c991d80325bd5a886..8465d4f9c7b572bed6e6e1437a7f904c1d377132 100644 --- a/submissions/urls.py +++ b/submissions/urls.py @@ -54,6 +54,8 @@ urlpatterns = [ views.accept_or_decline_ref_invitations, name='accept_or_decline_ref_invitations'), url(r'^accept_or_decline_ref_invitation/(?P<invitation_id>[0-9]+)$', views.accept_or_decline_ref_invitation_ack, name='accept_or_decline_ref_invitation_ack'), + url(r'^decline_ref_invitation/(?P<invitation_key>.+)$', + views.decline_ref_invitation, name='decline_ref_invitation'), url(r'^ref_invitation_reminder/(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/(?P<invitation_id>[0-9]+)$', views.ref_invitation_reminder, name='ref_invitation_reminder'), url(r'^cancel_ref_invitation/(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/(?P<invitation_id>[0-9]+)$', views.cancel_ref_invitation, name='cancel_ref_invitation'), diff --git a/submissions/utils.py b/submissions/utils.py index fb2039cc6df596f19c5dbce7b37985c794f9ee11..df19145f93f6a1e2db97d190fdb2e5a59d658fd0 100644 --- a/submissions/utils.py +++ b/submissions/utils.py @@ -616,6 +616,7 @@ class SubmissionUtils(BaseMailUtil): emailmessage.attach_alternative(html_version, 'text/html') emailmessage.send(fail_silently=False) + @classmethod def send_refereeing_invitation_email(cls): """ @@ -701,66 +702,162 @@ class SubmissionUtils(BaseMailUtil): emailmessage.attach_alternative(html_version, 'text/html') emailmessage.send(fail_silently=False) + @classmethod + def send_unreg_ref_reminder_email(cls): + """ + This method is used to remind a referee who has not yet responded. + It is used for unregistered referees only. + It is called from the ref_invitation_reminder method in submissions/views.py. + """ + email_text = ( + 'Dear ' + cls.invitation.title + ' ' + + cls.invitation.last_name + ',\n\n' + 'On behalf of the Editor-in-charge ' + + cls.invitation.submission.editor_in_charge.get_title_display() + ' ' + + cls.invitation.submission.editor_in_charge.user.last_name + + ', we would like to cordially remind you of our recent request to referee\n\n' + + cls.invitation.submission.title + ' by ' + + cls.invitation.submission.author_list + '.') + email_text_html = ( + '<p>Dear {{ title }} {{ last_name }},</p>' + '<p>On behalf of the Editor-in-charge {{ EIC_title }} {{ EIC_last_name }}, ' + 'we would like to cordially remind you of our recent request to referee</p>' + '<p>{{ sub_title }}</p>' + '\n<p>by {{ author_list }}.</p>') + email_text += ( + '\n\nWe would also like to renew ' + 'our invitation to become a Contributor on SciPost ' + '(our records show that you are not yet registered); ' + 'your partially pre-filled registration form is still available at\n\n' + 'https://scipost.org/invitation/' + cls.invitation.invitation_key + '\n\n' + 'after which your registration will be activated, giving you full access to ' + 'the portal\'s facilities (in particular allowing you to ' + 'provide referee reports).\n\n' + 'To ensure timely processing of the submission (out of respect for the authors), ' + 'we would appreciate a quick accept/decline response from you, ' + 'ideally within the next 2 days.\n\n' + 'If you are not able to provide a Report, you can quickly let us know by simply ' + 'navigating to \n\nhttps://scipost.org/decline_ref_invitation/' + + cls.invitation.invitation_key + '\n\n' + 'If you are able to provide a Report, you can confirm this after registering ' + 'and logging in (you will automatically be prompted for a confirmation). ' + 'Your report can thereafter be submitted by simply clicking on ' + 'the "Contribute a Report" link at ' + 'https://scipost.org/submission/' + + cls.invitation.submission.arxiv_identifier_w_vn_nr + + ' before the reporting deadline (currently set at ' + + datetime.datetime.strftime(cls.invitation.submission.reporting_deadline, "%Y-%m-%d") + + '; your report will be automatically recognized as an invited report). ' + 'You might want to make sure you are familiar with our refereeing code of conduct ' + 'https://scipost.org/journals/journals_terms_and_conditions and with the ' + 'refereeing procedure https://scipost.org/submissions/sub_and_ref_procedure.' + '\n\nWe very much hope we can count on your expertise,' + '\n\nMany thanks in advance,\n\nThe SciPost Team' + ) + email_text_html += ( + '\n<p>We would also like to renew ' + 'our invitation to become a Contributor on SciPost ' + '(our records show that you are not yet registered); ' + 'your partially pre-filled ' + '<a href="https://scipost.org/invitation/{{ invitation_key }}">' + 'registration form</a> is still available, ' + 'after which your registration will be activated, giving you full access to ' + 'the portal\'s facilities (in particular allowing you to provide referee reports).</p>' + '<p>To ensure timely processing of the submission (out of respect for the authors), ' + 'we would appreciate a quick accept/decline response from you, ' + 'ideally within the next 2 days.</p>' + '<p>If you are <strong>not</strong> able to provide a Report, ' + 'you can quickly let us know by simply ' + '<a href="https://scipost.org/decline_ref_invitation/{{ invitation_key }}>' + 'clicking here</a>.</p>' + '<p>If you are able to provide a Report, you can confirm this after registering ' + 'and logging in (you will automatically be prompted for a confirmation). ' + 'Your report can thereafter be submitted by simply clicking on ' + 'the "Contribute a Report" link at ' + 'the <a href="https://scipost.org/submission/{{ arxiv_identifier_w_vn_nr }}">' + 'Submission\'s page</a> before the reporting deadline (currently set at ' + '{{ deadline }}; your report will be automatically recognized as an invited report).</p>' + '\n<p>You might want to make sure you are familiar with our ' + '<a href="https://scipost.org/journals/journals_terms_and_conditions">' + 'refereeing code of conduct</a> and with the ' + '<a href="https://scipost.org/submissions/sub_and_ref_procedure">' + 'refereeing procedure</a>.</p>' + '<p>We very much hope we can count on your expertise,</p>' + '<p>Many thanks in advance,</p>' + '<p>The SciPost Team</p>') + email_context = Context({ + 'title': cls.invitation.title, + 'last_name': cls.invitation.last_name, + 'EIC_title': cls.invitation.submission.editor_in_charge.get_title_display(), + 'EIC_last_name': cls.invitation.submission.editor_in_charge.user.last_name, + 'sub_title': cls.invitation.submission.title, + 'author_list': cls.invitation.submission.author_list, + 'arxiv_identifier_w_vn_nr': cls.invitation.submission.arxiv_identifier_w_vn_nr, + 'deadline': datetime.datetime.strftime(cls.invitation.submission.reporting_deadline, + "%Y-%m-%d"), + 'invitation_key': cls.invitation.invitation_key, + }) + email_text_html += '<br/>' + EMAIL_FOOTER + html_template = Template(email_text_html) + html_version = html_template.render(email_context) + emailmessage = EmailMultiAlternatives( + 'SciPost: reminder (refereeing request and registration invitation)', email_text, + 'SciPost Submissions <submissions@scipost.org>', + [cls.invitation.email_address], + bcc=[cls.invitation.submission.editor_in_charge.user.email, + 'submissions@scipost.org'], + reply_to=['submissions@scipost.org']) + emailmessage.attach_alternative(html_version, 'text/html') + emailmessage.send(fail_silently=False) + + @classmethod def send_ref_reminder_email(cls): """ - This method is used to remind a referee who is not registered as a Contributor. + This method is used to remind a referee who has not yet responded. + It is used for registered Contributors only. It is called from the ref_invitation_reminder method in submissions/views.py. """ - email_text = ('Dear ' + cls.invitation.get_title_display() + ' ' - + cls.invitation.last_name + ',\n\n' - 'On behalf of the Editor-in-charge ' - + cls.invitation.submission.editor_in_charge.get_title_display() + ' ' - + cls.invitation.submission.editor_in_charge.user.last_name - + ', we would like to cordially remind you of our recent request to referee\n\n' - + cls.invitation.submission.title + ' by ' - + cls.invitation.submission.author_list + '.') + email_text = ( + 'Dear ' + cls.invitation.get_title_display() + ' ' + + cls.invitation.last_name + ',\n\n' + 'On behalf of the Editor-in-charge ' + + cls.invitation.submission.editor_in_charge.get_title_display() + ' ' + + cls.invitation.submission.editor_in_charge.user.last_name + + ', we would like to cordially remind you of our recent request to referee\n\n' + + cls.invitation.submission.title + ' by ' + + cls.invitation.submission.author_list + '.') email_text_html = ( '<p>Dear {{ title }} {{ last_name }},</p>' '<p>On behalf of the Editor-in-charge {{ EIC_title }} {{ EIC_last_name }}, ' 'we would like to cordially remind you of our recent request to referee</p>' '<p>{{ sub_title }}</p>' '\n<p>by {{ author_list }}.</p>') - if cls.invitation.referee is None: - email_text += ('\n\nWe would also like to renew ' - 'our invitation to become a Contributor on SciPost ' - '(our records show that you are not yet registered); ' - 'your partially pre-filled registration form is still available at\n\n' - 'https://scipost.org/invitation/' + cls.invitation.invitation_key + '\n\n' - 'after which your registration will be activated, giving you full access to ' - 'the portal\'s facilities (in particular allowing you to provide referee reports).') - email_text_html += ( - '\n<p>We would also like to renew ' - 'our invitation to become a Contributor on SciPost ' - '(our records show that you are not yet registered); ' - 'your partially pre-filled ' - '<a href="https://scipost.org/invitation/{{ invitation_key }}">' - 'registration form</a> is still available, ' - 'after which your registration will be activated, giving you full access to ' - 'the portal\'s facilities (in particular allowing you to provide referee reports).</p>') if cls.invitation.accepted is None: - email_text += ('\n\nPlease visit ' - 'https://scipost.org/submissions/accept_or_decline_ref_invitations ' - '(login required) as soon as possible (ideally within the next 2 days) ' - 'in order to accept or decline this invitation.') + email_text += ( + '\n\nPlease visit ' + 'https://scipost.org/submissions/accept_or_decline_ref_invitations ' + '(login required) as soon as possible (ideally within the next 2 days) ' + 'in order to accept or decline this invitation.') email_text_html += ( '\n<p>Please ' '<a href="https://scipost.org/submissions/accept_or_decline_ref_invitations">' 'accept or decline the invitation</a> ' '(login required) as soon as possible (ideally within the next 2 days) ' 'in order to ensure rapid processing of the submission.') - email_text += ('\n\nYour report can be submitted by simply clicking on ' - 'the "Contribute a Report" link at ' - 'https://scipost.org/submission/' - + cls.invitation.submission.arxiv_identifier_w_vn_nr - + ' before the reporting deadline (currently set at ' - + datetime.datetime.strftime(cls.invitation.submission.reporting_deadline, "%Y-%m-%d") - + '; your report will be automatically recognized as an invited report). ' - 'You might want to make sure you are familiar with our refereeing code of conduct ' - 'https://scipost.org/journals/journals_terms_and_conditions and with the ' - 'refereeing procedure https://scipost.org/submissions/sub_and_ref_procedure.' - '\n\nWe very much hope we can count on your expertise,' - '\n\nMany thanks in advance,\n\nThe SciPost Team') + email_text += ( + '\n\nYour report can be submitted by simply clicking on ' + 'the "Contribute a Report" link at ' + 'https://scipost.org/submission/' + + cls.invitation.submission.arxiv_identifier_w_vn_nr + + ' before the reporting deadline (currently set at ' + + datetime.datetime.strftime(cls.invitation.submission.reporting_deadline, "%Y-%m-%d") + + '; your report will be automatically recognized as an invited report). ' + 'You might want to make sure you are familiar with our refereeing code of conduct ' + 'https://scipost.org/journals/journals_terms_and_conditions and with the ' + 'refereeing procedure https://scipost.org/submissions/sub_and_ref_procedure.' + '\n\nWe very much hope we can count on your expertise,' + '\n\nMany thanks in advance,\n\nThe SciPost Team') email_text_html += ( '\n<p>Your report can be submitted by simply clicking on ' 'the "Contribute a Report" link at ' @@ -800,6 +897,7 @@ class SubmissionUtils(BaseMailUtil): emailmessage.attach_alternative(html_version, 'text/html') emailmessage.send(fail_silently=False) + @classmethod def send_ref_cancellation_email(cls): """ diff --git a/submissions/views.py b/submissions/views.py index 81375ff8b1198c191c9a0000b1e3d64687bcdc62..387ac0debb92a8bfbbf80734ef0d87d1e22dd4e3 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -800,7 +800,10 @@ def ref_invitation_reminder(request, arxiv_identifier_w_vn_nr, invitation_id): invitation.date_last_reminded = timezone.now() invitation.save() SubmissionUtils.load({'invitation': invitation}) - SubmissionUtils.send_ref_reminder_email() + if invitation.referee is not None: + SubmissionUtils.send_ref_reminder_email() + else: + SubmissionUtils.send_unreg_ref_reminder_email() return redirect(reverse('submissions:editorial_page', kwargs={'arxiv_identifier_w_vn_nr': arxiv_identifier_w_vn_nr})) @@ -842,6 +845,24 @@ def accept_or_decline_ref_invitation_ack(request, invitation_id): return render(request, 'submissions/accept_or_decline_ref_invitation_ack.html', context) +def decline_ref_invitation(request, invitation_key): + invitation = get_object_or_404(RefereeInvitation, invitation_key=invitation_key) + if request.method == 'POST': + form = ConsiderRefereeInvitationForm(request.POST) + if form.is_valid(): + invitation.accepted = False + invitation.refusal_reason = form.cleaned_data['refusal_reason'] + invitation.save() + SubmissionUtils.load({'invitation': invitation}, request) + SubmissionUtils.email_referee_response_to_EIC() + messages.success(request, 'Thank you for informing us that you will not provide a Report.') + return redirect(reverse('scipost:index')) + else: + form = ConsiderRefereeInvitationForm(initial={'accept': False}) + context = {'invitation': invitation, 'form': form} + return render(request, 'submissions/decline_ref_invitation.html', context) + + @login_required @permission_required_or_403('can_take_editorial_actions', (Submission, 'arxiv_identifier_w_vn_nr', 'arxiv_identifier_w_vn_nr')) diff --git a/templates/email/referee_in_response_to_decision.html b/templates/email/referee_in_response_to_decision.html index 563f0956c294831980e22356293ffa4d6432d5f2..4e3b8502223fa7402894ea9aa1f935c1923eeae8 100644 --- a/templates/email/referee_in_response_to_decision.html +++ b/templates/email/referee_in_response_to_decision.html @@ -5,6 +5,7 @@ We hereby confirm your choice to {% if invitation.accepted %}accept{% else %}dec {{invitation.submission.title}} by {{invitation.submission.author_list}}\n\n {% if invitation.accepted %} +We will look forward to receiving your Report by the reporting deadline {{ invitation.submission.reporting_deadline|date:'Y-m-d' }}.\n\n Many thanks for your collaboration,\n {% else %} Nonetheless, we thank you very much for considering this refereeing invitation,\n diff --git a/templates/email/referee_in_response_to_decision_html.html b/templates/email/referee_in_response_to_decision_html.html index c62074285a39e77a183e5909a0defe6affdade7d..d9a46fe44544f8ea7b72de0da038852df7d505fc 100644 --- a/templates/email/referee_in_response_to_decision_html.html +++ b/templates/email/referee_in_response_to_decision_html.html @@ -9,6 +9,7 @@ <p> {% if invitation.accepted %} + We will look forward to receiving your Report by the reporting deadline {{ invitation.submission.reporting_deadline|date:'Y-m-d' }}. Many thanks for your collaboration, {% else %} Nonetheless, we thank you very much for considering this refereeing invitation, diff --git a/templates/email/referee_response_to_EIC.html b/templates/email/referee_response_to_EIC.html index c3e7b18856e90284714941a74d3a529b134c5c5b..e73f226ccf6c68346f1d879ba008e59d5d828fcf 100644 --- a/templates/email/referee_response_to_EIC.html +++ b/templates/email/referee_response_to_EIC.html @@ -1,6 +1,6 @@ Dear {{invitation.submission.editor_in_charge.get_title_display}} {{invitation.submission.editor_in_charge.user.last_name}},\n\n -Referee {{invitation.referee.get_title_display}} {{invitation.referee.user.last_name}} has {% if invitation.accepted %}accepted{% else %}declined (due to reason: {{invitation.get_refusal_reason_display}}){% endif %} to referee Submission\n\n +Referee {% if invitation.referee %}{{invitation.referee.get_title_display}} {{invitation.referee.user.last_name}}{% else %}{{ invitation.title }} {{ invitation.first_name }} {{ invitation.last_name }}{% endif %} has {% if invitation.accepted %}accepted{% else %}declined (due to reason: {{invitation.get_refusal_reason_display}}){% endif %} to referee Submission\n\n {{invitation.submission.title}} by {{invitation.submission.author_list}}\n\n diff --git a/templates/email/referee_response_to_EIC_html.html b/templates/email/referee_response_to_EIC_html.html index 8a8ea2958a74a03a1419863f1d3c56733c7a6a8b..e7bf2687d608b4f65977260e012dbcaa7a61d30b 100644 --- a/templates/email/referee_response_to_EIC_html.html +++ b/templates/email/referee_response_to_EIC_html.html @@ -1,7 +1,7 @@ <h3>Dear {{invitation.submission.editor_in_charge.get_title_display}} {{invitation.submission.editor_in_charge.user.last_name}},</h3> <p> - Referee {{invitation.referee.get_title_display}} {{invitation.referee.user.last_name}} has {% if invitation.accepted %}accepted{% else %}declined (due to reason: {{invitation.get_refusal_reason_display}}){% endif %} to referee Submission + Referee {% if invitation.referee %}{{invitation.referee.get_title_display}} {{invitation.referee.user.last_name}}{% else %}{{ invitation.title }} {{ invitation.first_name }} {{ invitation.last_name }}{% endif %} has {% if invitation.accepted %}accepted{% else %}declined (due to reason: {{invitation.get_refusal_reason_display}}){% endif %} to referee Submission </p> <p> "<span style="color: grey;">{{invitation.submission.title}} by {{invitation.submission.author_list}}</span>".