From ab5a3e5591b0a950c7d6f9e03bcdadeb72df3014 Mon Sep 17 00:00:00 2001 From: "J.-S. Caux" <J.S.Caux@uva.nl> Date: Sun, 10 Apr 2016 17:57:47 +0200 Subject: [PATCH] Building up editorial workflow: EIC and referee selection done --- .../commands/add_groups_and_permissions.py | 30 +++++++++++++++---- scipost/templates/scipost/personal_page.html | 5 ++-- scipost/views.py | 4 +-- submissions/models.py | 7 +++++ .../templates/submissions/editorial_page.html | 24 +++++++++++---- .../templates/submissions/select_referee.html | 2 ++ .../submissions/submission_detail.html | 3 ++ submissions/views.py | 23 ++++++++++++-- 8 files changed, 81 insertions(+), 17 deletions(-) diff --git a/scipost/management/commands/add_groups_and_permissions.py b/scipost/management/commands/add_groups_and_permissions.py index d59952054..656f94769 100644 --- a/scipost/management/commands/add_groups_and_permissions.py +++ b/scipost/management/commands/add_groups_and_permissions.py @@ -29,6 +29,20 @@ class Command(BaseCommand): name= 'Can manage registration invitations', content_type=content_type) + # Contributions (not related to submissions) + can_submit_comments, created = Permission.objects.get_or_create( + codename='can_submit_comments', + name= 'Can submit Comments', + content_type=content_type) + can_request_commentary_pages, created = Permission.objects.get_or_create( + codename='can_request_commentary_pages', + name= 'Can request opening of Commentara Pages', + content_type=content_type) + can_request_thesislinks, created = Permission.objects.get_or_create( + codename='can_request_thesislinks', + name= 'Can request Thesis Links', + content_type=content_type) + # Vetting of simple objects can_vet_commentary_requests, created = Permission.objects.get_or_create( codename='can_vet_commentary_requests', @@ -54,19 +68,25 @@ class Command(BaseCommand): content_type=content_type) # Submission handling - can_process_incoming_submissions, created = Permission.objects.get_or_create( - codename='can_process_incoming_submissions', - name= 'Can process incoming Submissions', + can_assign_submissions, created = Permission.objects.get_or_create( + codename='can_assign_submissions', + name= 'Can assign incoming Submissions to potential Editor-in-charge', content_type=content_type) can_take_charge_of_submissions, created = Permission.objects.get_or_create( codename='can_take_charge_of_submissions', - name= 'Can take charge of submissions', + name= 'Can take charge (become Editor-in-charge) of submissions', content_type=content_type) can_vet_submitted_reports, created = Permission.objects.get_or_create( codename='can_vet_submitted_reports', name='Can vet submitted Reports', content_type=content_type) + # Refereeing + can_referee, created = Permission.objects.get_or_create( + codename='can_referee', + name= 'Can act as a referee and submit reports on Submissions', + content_type=content_type) + # Assign permissions to groups SciPostAdmin.permissions.add(can_manage_registration_invitations, can_vet_registration_requests, @@ -74,7 +94,7 @@ class Command(BaseCommand): can_vet_thesislink_requests, can_vet_authorship_claims, can_vet_comments, - can_process_incoming_submissions, + can_assign_submissions, ) EditorialCollege.permissions.add(can_take_charge_of_submissions, can_vet_submitted_reports, diff --git a/scipost/templates/scipost/personal_page.html b/scipost/templates/scipost/personal_page.html index af7fbde9a..dcbfd1a99 100644 --- a/scipost/templates/scipost/personal_page.html +++ b/scipost/templates/scipost/personal_page.html @@ -127,7 +127,7 @@ <div class="col-4"> <h3>Submissions assignments</h3> <ul> - {% if perms.scipost.can_process_incoming_submissions %} + {% if perms.scipost.can_assign_submissions %} <li><a href="{% url 'submissions:assign_submissions' %}">Assign SciPost Submissions</a> ({{ nr_submissions_to_assign }})</li> {% endif %} {% if perms.scipost.can_take_charge_of_submissions %} @@ -148,6 +148,7 @@ </section> {% endif %} +{% if perms.scipost.can_referee %} <section> <hr class="hr12"> <div class="flex-greybox"> @@ -164,8 +165,8 @@ {% endfor %} </ul> {% endif %} - </section> +{% endif %} <section> <hr class="hr12"> diff --git a/scipost/views.py b/scipost/views.py index 4579f0ed7..3c95c514e 100644 --- a/scipost/views.py +++ b/scipost/views.py @@ -200,7 +200,7 @@ def request_new_activation_link(request, oldkey): return render (request, 'scipost/request_new_activation_link_ack.html') -@permission_required('scipost.can_vet_registration_requests') +@permission_required('scipost.can_vet_registration_requests', raise_exception=True) def vet_registration_requests(request): contributor = Contributor.objects.get(user=request.user) contributors_to_vet = Contributor.objects.filter(user__is_active=True, status=0).order_by('key_expires') @@ -209,7 +209,7 @@ def vet_registration_requests(request): context = {'contributors_to_vet': contributors_to_vet, 'form': form } return render(request, 'scipost/vet_registration_requests.html', context) -@permission_required('scipost.can_vet_registration_requests') +@permission_required('scipost.can_vet_registration_requests', raise_exception=True) def vet_registration_request_ack(request, contributor_id): # process the form if request.method == 'POST': diff --git a/submissions/models.py b/submissions/models.py index f00e94e89..1c1bb9171 100644 --- a/submissions/models.py +++ b/submissions/models.py @@ -42,6 +42,7 @@ SUBMISSION_ACTION_REQUIRED = ( class Submission(models.Model): submitted_by = models.ForeignKey(Contributor) assigned = models.BooleanField(default=False) + editor_in_charge = models.ForeignKey(Contributor, related_name='EIC', blank=True, null=True) submitted_to_journal = models.CharField(max_length=30, choices=SCIPOST_JOURNALS_SUBMIT, verbose_name="Journal to be submitted to") discipline = models.CharField(max_length=20, choices=SCIPOST_DISCIPLINES, default='physics') domain = models.CharField(max_length=3, choices=SCIPOST_JOURNALS_DOMAINS) @@ -64,6 +65,12 @@ class Submission(models.Model): def __str__ (self): return self.title + @property + def reporting_deadline_has_passed(self): + if timezone.now() > self.reporting_deadline: + return True + return False + def header_as_table (self): # for Submission page header = '<table>' diff --git a/submissions/templates/submissions/editorial_page.html b/submissions/templates/submissions/editorial_page.html index bae5c49c7..d39d82d72 100644 --- a/submissions/templates/submissions/editorial_page.html +++ b/submissions/templates/submissions/editorial_page.html @@ -16,6 +16,7 @@ <section> <div class="flex-greybox"> <h1>Editorial Page 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> </div> <hr class="hr12"> @@ -38,22 +39,35 @@ <h3>Status:</h3> {{ submission.status_info_as_table }} + <hr class="hr6"/> <h3>Actions:</h3> <ul> <li><a href="{% url 'submissions:select_referee' submission_id=submission.id %}">Select an additional referee</a></li> + <li>Extend the reporting deadline + (currently {{ submission.reporting_deadline }}) + {% if submission.reporting_deadline_has_passed %} + <b style="color: red">THE REPORTING DEADLINE HAS PASSED</b> + {% endif %} + </li> + {% if not submission.reporting_deadline_has_passed %} <li><a href="{% url 'submissions:close_refereeing_round' submission_id=submission.id %}">Close the refereeing round</a></li> + {% endif %} + <li>Request author response to Reports and Comments</li> + <li>Formulate an Editorial Recommendation and send it to Editorial College for ratification</li> + <li>Inform authors of Editorial Decisions</li> </ul> -</section> -<section> - <div class="flex-greybox"> - <h1>Refereeing invitations</h1> - </div> + <hr class="hr6"/> + <h3>Refereeing invitations</h3> + {% if ref_invitations %} <ul> {% for invitation in ref_invitations %} {{ invitation.summary_as_li }} {% endfor %} </ul> + {% else %} + <p>You have not invited any referees yet.</p> + {% endif %} </section> {% endif %} <!-- Temporary strip --> diff --git a/submissions/templates/submissions/select_referee.html b/submissions/templates/submissions/select_referee.html index f25bfd342..2344cd950 100644 --- a/submissions/templates/submissions/select_referee.html +++ b/submissions/templates/submissions/select_referee.html @@ -16,6 +16,8 @@ <section> <div class="flex-greybox"> <h1>Referee Selection Page 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"> diff --git a/submissions/templates/submissions/submission_detail.html b/submissions/templates/submissions/submission_detail.html index 267adef6c..bc26873ce 100644 --- a/submissions/templates/submissions/submission_detail.html +++ b/submissions/templates/submissions/submission_detail.html @@ -30,6 +30,9 @@ <section> <div class="flex-greybox"> <h1>SciPost Submission Page (for papers submitted to SciPost)</h1> + {% if user.contributor == submission.editor_in_charge %} + <h3>(You are the Editor-in-charge, go to the <a href="{% url 'submissions:editorial_page' submission_id=submission.id %}">Editorial Page</a> to take editorial actions)</h3> + {% endif %} </div> <hr class="hr12"> diff --git a/submissions/views.py b/submissions/views.py index 9378dbe78..44f22698b 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -26,7 +26,6 @@ from comments.forms import CommentForm # SUBMISSIONS: ############### -#@permission_required('scipost.can_submit_manuscript', raise_exception=True) def submit_manuscript(request): if request.method == 'POST': form = SubmissionForm(request.POST) @@ -152,7 +151,7 @@ def submission_detail(request, submission_id): # Editorial workflow # ###################### - +@permission_required('scipost.can_assign_submissions', raise_exception=True) def assign_submissions(request): submission_to_assign = Submission.objects.filter(status='unassigned').first() # only handle one at at time if submission_to_assign is not None: @@ -164,6 +163,7 @@ def assign_submissions(request): return render(request, 'submissions/assign_submissions.html', context) +@permission_required('scipost.can_assign_submissions', raise_exception=True) def assign_submission_ack(request, submission_id): submission = Submission.objects.get(pk=submission_id) if request.method == 'POST': @@ -175,7 +175,6 @@ def assign_submission_ack(request, submission_id): date_created=timezone.now()) ed_assignment.save() submission.assigned = True - submission.assignment = ed_assignment submission.status = 'assigned' submission.latest_activity = timezone.now() submission.save() @@ -183,6 +182,7 @@ def assign_submission_ack(request, submission_id): return render(request, 'submissions/assign_submission_ack.html', context) +@permission_required('scipost.can_take_charge_of_submissions', raise_exception=True) def accept_or_decline_assignments(request): contributor = Contributor.objects.get(user=request.user) assignment = EditorialAssignment.objects.filter(to=contributor, accepted=None).first() @@ -191,6 +191,7 @@ def accept_or_decline_assignments(request): return render(request, 'submissions/accept_or_decline_assignments.html', context) +@permission_required('scipost.can_take_charge_of_submissions', raise_exception=True) def accept_or_decline_assignment_ack(request, assignment_id): contributor = Contributor.objects.get(user=request.user) assignment = get_object_or_404 (EditorialAssignment, pk=assignment_id) @@ -198,10 +199,15 @@ def accept_or_decline_assignment_ack(request, assignment_id): form = ConsiderAssignmentForm(request.POST) if form.is_valid(): assignment.date_answered = timezone.now() + deadline = timezone.now() + datetime.timedelta(days=28) # for papers + if assignment.submission.submitted_to_journal == 'SciPost Physics Lecture Notes': + deadline += datetime.timedelta(days=28) if form.cleaned_data['accept'] == 'True': assignment.accepted = True assignment.to = contributor assignment.submission.status = 'EICassigned' + assignment.submission.editor_in_charge = contributor + assignment.submission.reporting_deadline = deadline assignment.submission.save() else: assignment.accepted = False @@ -212,13 +218,16 @@ def accept_or_decline_assignment_ack(request, assignment_id): return render(request, 'submissions/accept_or_decline_assignment_ack.html', context) +@permission_required('scipost.can_take_charge_of_submissions', raise_exception=True) 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} return render(request, 'submissions/editorial_page.html', context) +@permission_required('scipost.can_take_charge_of_submissions', raise_exception=True) def select_referee(request, submission_id): submission = get_object_or_404(Submission, pk=submission_id) if request.method == 'POST': @@ -234,6 +243,7 @@ def select_referee(request, submission_id): return render(request, 'submissions/select_referee.html', context) +@permission_required('scipost.can_take_charge_of_submissions', raise_exception=True) def recruit_referee(request, submission_id): """ If the Editor-in-charge does not find the desired referee among Contributors, @@ -279,6 +289,7 @@ def recruit_referee(request, submission_id): return redirect(reverse('submissions:editorial_page', kwargs={'submission_id': submission_id})) +@permission_required('scipost.can_take_charge_of_submissions', raise_exception=True) def send_refereeing_invitation(request, submission_id, contributor_id): submission = get_object_or_404(Submission, pk=submission_id) contributor = get_object_or_404(Contributor, pk=contributor_id) @@ -292,6 +303,7 @@ def send_refereeing_invitation(request, submission_id, contributor_id): return redirect(reverse('submissions:editorial_page', kwargs={'submission_id': submission_id})) +@permission_required('scipost.can_referee', raise_exception=True) def accept_or_decline_ref_invitations(request): contributor = Contributor.objects.get(user=request.user) invitation = RefereeInvitation.objects.filter(referee=contributor, accepted=None).first() @@ -300,6 +312,7 @@ def accept_or_decline_ref_invitations(request): return render(request, 'submissions/accept_or_decline_ref_invitations.html', context) +@permission_required('scipost.can_referee', raise_exception=True) def accept_or_decline_ref_invitation_ack(request, invitation_id): contributor = Contributor.objects.get(user=request.user) invitation = get_object_or_404 (RefereeInvitation, pk=invitation_id) @@ -318,6 +331,7 @@ def accept_or_decline_ref_invitation_ack(request, invitation_id): return render(request, 'submissions/accept_or_decline_ref_invitation_ack.html', context) +@permission_required('scipost.can_take_charge_of_submissions', raise_exception=True) def close_refereeing_round(request, submission_id): submission = get_object_or_404 (Submission, pk=submission_id) submission.open_for_reporting = False @@ -331,6 +345,7 @@ def close_refereeing_round(request, submission_id): # Reports ########### +@permission_required('scipost.can_referee', raise_exception=True) def submit_report(request, submission_id): submission = get_object_or_404 (Submission, pk=submission_id) if request.method == 'POST': @@ -374,6 +389,7 @@ def submit_report(request, submission_id): return render(request, 'submissions/submit_report.html', context) +@permission_required('scipost.can_take_charge_of_submissions', raise_exception=True) def vet_submitted_reports(request): contributor = Contributor.objects.get(user=request.user) report_to_vet = Report.objects.filter(status=0).first() # only handle one at a time @@ -382,6 +398,7 @@ def vet_submitted_reports(request): return(render(request, 'submissions/vet_submitted_reports.html', context)) +@permission_required('scipost.can_take_charge_of_submissions', raise_exception=True) def vet_submitted_report_ack(request, report_id): if request.method == 'POST': form = VetReportForm(request.POST) -- GitLab