diff --git a/colleges/forms.py b/colleges/forms.py index 7a4653094ec3d1083d635eecb8d42dc120aa94a7..4968ae748ce693b1b9be65a9508c49474cac2b15 100644 --- a/colleges/forms.py +++ b/colleges/forms.py @@ -167,6 +167,7 @@ class SubmissionAddVotingFellowForm(forms.ModelForm): def save(self): fellowship = self.cleaned_data['fellowship'] submission = self.instance + submission.fellows.add(fellowship) submission.voting_fellows.add(fellowship) return submission diff --git a/colleges/permissions.py b/colleges/permissions.py new file mode 100644 index 0000000000000000000000000000000000000000..cd67ccbd87274b017b8f19380120c66f07b75ca6 --- /dev/null +++ b/colleges/permissions.py @@ -0,0 +1,11 @@ +from django.contrib.auth.decorators import user_passes_test + + +def fellowship_required(): + """Require user to have any Fellowship.""" + def test(u): + if u.is_authenticated(): + if hasattr(u, 'contributor') and u.contributor.fellowships.exists(): + return True + return False + return user_passes_test(test) diff --git a/submissions/templates/partials/submissions/pool/submission_details.html b/submissions/templates/partials/submissions/pool/submission_details.html index 36614f27fff8e056f01a8991e35a7d091518b7a0..7673c8703ef52d88590e9465e2278d26221de999 100644 --- a/submissions/templates/partials/submissions/pool/submission_details.html +++ b/submissions/templates/partials/submissions/pool/submission_details.html @@ -30,7 +30,7 @@ {% endfor %} </ul> - {% if is_editor_in_charge or is_editorial_admin %} + {% if is_editor_in_charge or is_editorial_admin or submission|is_voting_fellow:request.user %} <br> {% include 'submissions/_required_actions_block.html' with submission=submission %} <h4> diff --git a/submissions/templates/submissions/editorial_page.html b/submissions/templates/submissions/editorial_page.html index 2d00f95cf92b39b07187ae85627be9a9046c7b2f..66b4ad1c6369970cd97ad11a33af114e55fb43e3 100644 --- a/submissions/templates/submissions/editorial_page.html +++ b/submissions/templates/submissions/editorial_page.html @@ -104,18 +104,28 @@ </div> </div><!-- End status --> -<div class="row"> - <div class="col-md-10 col-lg-8"> - {% include 'submissions/_required_actions_block.html' with submission=submission %} +{% if full_access %} + <div class="row"> + <div class="col-md-10 col-lg-8"> + {% include 'submissions/_required_actions_block.html' with submission=submission %} + </div> </div> -</div> +{% endif %} {% if submission.status == 'resubmitted_incoming' %} - <div class="row"> - <div class="col-12"> - {% include 'submissions/_form_submission_cycle_choice.html' with form=cycle_choice_form submission=submission %} + {% if full_access %} + <div class="row"> + <div class="col-12"> + {% include 'submissions/_form_submission_cycle_choice.html' with form=cycle_choice_form submission=submission %} + </div> </div> - </div> + {% else %} + <div class="row"> + <div class="col-12"> + <h3 class="text-center">The Editor-in-charge first has to decide which refereeing cycle to use. Please check this page again at a later moment.</h3> + </div> + </div> + {% endif %} {% else %} {% if submission.refereeing_cycle != 'direct_rec' %} <div class="row"> @@ -125,137 +135,144 @@ </div> </div> - <div class="row"> - <div class="col-12"> - <h3 class="mb-2">Detail of refereeing invitations:</h3> - {% include 'submissions/_submission_refereeing_invitations.html' with submission=submission invitations=submission.referee_invitations.all %} + {% if full_access %} + <div class="row"> + <div class="col-12"> + <h3 class="mb-2">Detail of refereeing invitations:</h3> + {% include 'submissions/_submission_refereeing_invitations.html' with submission=submission invitations=submission.referee_invitations.all %} + </div> </div> - </div> + {% endif %} {% endif %} - <hr> - {% if not submission.is_current %} - <div class="row"> - <div class="col-12"> - <div class="card mt-3 border-warning bg-light"> - <div class="card-body"> - <h3 class="mb-3"><strong>BEWARE: This is not the editorial page for the current version!</strong></h3> - <p class="mb-0"> - The tools here are thus available only for exceptional circumstances (e.g. vetting a late report on a deprecated version). - <br>Please go to the current version's page using the link at the top. - </p> + {% if full_access %} + <hr> + + {% if not submission.is_current %} + <div class="row"> + <div class="col-12"> + <div class="card mt-3 border-warning bg-light"> + <div class="card-body"> + <h3 class="mb-3"><strong>BEWARE: This is not the editorial page for the current version!</strong></h3> + <p class="mb-0"> + The tools here are thus available only for exceptional circumstances (e.g. vetting a late report on a deprecated version). + <br>Please go to the current version's page using the link at the top. + </p> + </div> + </div> </div> </div> - </div> - </div> - {% endif %} + {% endif %} - <div class="row"> - <div class="col-12"> - <h2 class="mt-3">Actions</h2> - <ul> - {% if submission.refereeing_cycle != 'direct_rec' %} - <li> - <a href="{% url 'submissions:select_referee' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Select an additional referee</a> (bear in mind flagged referees if any) - </li> - <li>Extend the refereeing deadline (currently {{ submission.reporting_deadline|date:'Y-m-d' }}) by - <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=2 %}">2 days</a>, - <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=7 %}">1 week</a> or - <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=14 %}">2 weeks</a> - {% if submission.reporting_deadline_has_passed %} - <span class="ml-1 label label-sm label-outline-danger">THE REPORTING DEADLINE HAS PASSED</span> - {% endif %} - </li> - <li> - Set refereeing deadline: - <form class="form-inline" action="{% url 'submissions:set_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}" method="post"> - {% csrf_token %} - {{ set_deadline_form|bootstrap_inline:'0,12' }} - <div class="ml-2 form-group row"> - <div class="col-12"> - <input class="btn btn-secondary" type="submit" value="Set deadline"/> + <div class="row"> + <div class="col-12"> + <h2 class="mt-3">Actions</h2> + <ul> + {% if submission.refereeing_cycle != 'direct_rec' %} + <li> + <a href="{% url 'submissions:select_referee' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Select an additional referee</a> (bear in mind flagged referees if any) + </li> + <li>Extend the refereeing deadline (currently {{ submission.reporting_deadline|date:'Y-m-d' }}) by + <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=2 %}">2 days</a>, + <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=7 %}">1 week</a> or + <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=14 %}">2 weeks</a> + {% if submission.reporting_deadline_has_passed %} + <span class="ml-1 label label-sm label-outline-danger">THE REPORTING DEADLINE HAS PASSED</span> + {% endif %} + </li> + <li> + Set refereeing deadline: + <form class="form-inline" action="{% url 'submissions:set_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}" method="post"> + {% csrf_token %} + {{ set_deadline_form|bootstrap_inline:'0,12' }} + <div class="ml-2 form-group row"> + <div class="col-12"> + <input class="btn btn-secondary" type="submit" value="Set deadline"/> + </div> </div> - </div> - </form> - </li> - {% with submission.reports.awaiting_vetting as reports %} - {% if reports %} - <li> - Vet submitted Report{{reports|pluralize}}: - <ul class="mb-1"> - {% for report in reports %} - <li><a href="{% url 'submissions:vet_submitted_report' report.id %}">{{report}}</a></li> - {% endfor %} - </ul> - </li> - {% else %} - <li>All Reports have been vetted.</li> - {% endif %} - {% endwith %} - - {% with submission.comments_set_complete.awaiting_vetting as comments %} - {% if comments %} - <li> - Vet submitted Comment{{comments|pluralize}}: - <ul class="mb-1"> - {% for comment in comments %} - <li><a href="{% url 'comments:vet_submitted_comment' comment.id %}">{{comment}}</a></li> - {% endfor %} - </ul> - </li> - {% else %} - <li>All Comments have been vetted.</li> + </form> + </li> + {% with submission.reports.awaiting_vetting as reports %} + {% if reports %} + <li> + Vet submitted Report{{reports|pluralize}}: + <ul class="mb-1"> + {% for report in reports %} + <li><a href="{% url 'submissions:vet_submitted_report' report.id %}">{{report}}</a></li> + {% endfor %} + </ul> + </li> + {% else %} + <li>All Reports have been vetted.</li> + {% endif %} + {% endwith %} + + {% with submission.comments_set_complete.awaiting_vetting as comments %} + {% if comments %} + <li> + Vet submitted Comment{{comments|pluralize}}: + <ul class="mb-1"> + {% for comment in comments %} + <li><a href="{% url 'comments:vet_submitted_comment' comment.id %}">{{comment}}</a></li> + {% endfor %} + </ul> + </li> + {% else %} + <li>All Comments have been vetted.</li> + {% endif %} + {% endwith %} + + {% if not submission.reporting_deadline_has_passed %} + <li><a href="{% url 'submissions:close_refereeing_round' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Close the refereeing round</a> (deactivates submission of new Reports and Comments)</li> {% endif %} - {% endwith %} - - {% if not submission.reporting_deadline_has_passed %} - <li><a href="{% url 'submissions:close_refereeing_round' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Close the refereeing round</a> (deactivates submission of new Reports and Comments)</li> {% endif %} - {% endif %} - {% if submission.eic_recommendation_required %} - <li> - <a href="{% url 'submissions:eic_recommendation' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">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> - {% endif %} - </ul> + {% if submission.eic_recommendation_required %} + <li> + <a href="{% url 'submissions:eic_recommendation' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">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> + {% endif %} + </ul> + </div> </div> - </div> + {% endif %} {% endif %} -<h2 class="mt-3">Communications</h2> -<ul> - {% if submission.editor_in_charge == request.user.contributor %} - <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoA' %}">Draft and send a communication with the submitting Author</a></li> - <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoS' %}">Draft and send a communication with SciPost Editorial Administration</a></li> - {% endif %} - {% if is_editorial_admin %} - <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='StoE' %}">Draft and send a communication as Editorial Administrator to the Editor-in-charge</a></li> - {% endif %} -</ul> +{% if full_access %} + <h2 class="mt-3">Communications</h2> + <ul> + {% if submission.editor_in_charge == request.user.contributor %} + <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoA' %}">Draft and send a communication with the submitting Author</a></li> + <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoS' %}">Draft and send a communication with SciPost Editorial Administration</a></li> + {% endif %} + {% if is_editorial_admin %} + <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='StoE' %}">Draft and send a communication as Editorial Administrator to the Editor-in-charge</a></li> + {% endif %} + </ul> -<div class="row"> - <div class="col-12"> - <ul class="list-group list-group-flush"> - {% for comm in submission.editorial_communications.all %} - <li class="list-group-item"> - {% include 'submissions/_editorial_communication_content.html' with communication=comm %} - </li> - {% empty %} - <li class="list-group-item">There have been no communications for this Submission.</li> - {% endfor %} - </ul> + <div class="row"> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for comm in submission.editorial_communications.all %} + <li class="list-group-item"> + {% include 'submissions/_editorial_communication_content.html' with communication=comm %} + </li> + {% empty %} + <li class="list-group-item">There have been no communications for this Submission.</li> + {% endfor %} + </ul> + </div> </div> -</div> -<h2 class="mt-3">Events</h2> -{% include 'submissions/submission_event_list.html' with events=submission.events.for_eic %} + <h2 class="mt-3">Events</h2> + {% include 'submissions/submission_event_list.html' with events=submission.events.for_eic %} +{% endif %} <div class="mb-5"></div> {% endblock content %} diff --git a/submissions/templatetags/submissions_extras.py b/submissions/templatetags/submissions_extras.py index d98be57a13f124f628b54f7e016404de300fd475..97943119c4c443baf69fdaf9b1a477d53a550475 100644 --- a/submissions/templatetags/submissions_extras.py +++ b/submissions/templatetags/submissions_extras.py @@ -25,3 +25,8 @@ def is_viewable_by_authors(recommendation): @register.filter def user_is_referee(submission, user): return submission.referee_invitations.filter(referee__user=user).exists() + + +@register.filter +def is_voting_fellow(submission, user): + return submission.voting_fellows.filter(contributor__user=user).exists() diff --git a/submissions/views.py b/submissions/views.py index 24564a1a2ace125c92c93abc6596a82ddb05e2e0..071c5d599592b03cdbb8915b403b27bfc014dfd0 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -33,6 +33,7 @@ from .forms import SubmissionIdentifierForm, RequestSubmissionForm, SubmissionSe iThenticateReportForm, SubmissionPoolFilterForm from .utils import SubmissionUtils +from colleges.permissions import fellowship_required from mails.views import MailEditingSubView from scipost.forms import ModifyPersonalMessageForm, RemarkForm from scipost.mixins import PaginationMixin @@ -331,7 +332,7 @@ def editorial_workflow(request): @login_required -@permission_required('scipost.can_view_pool', raise_exception=True) +@fellowship_required() def pool(request, arxiv_identifier_w_vn_nr=None): """ The Submissions pool contains all submissions which are undergoing @@ -392,7 +393,7 @@ def pool(request, arxiv_identifier_w_vn_nr=None): # Temporary test logic: only testers see the new Pool if context['submission'] and request.is_ajax(): template = 'partials/submissions/pool/submission_details.html' - elif is_tester(request.user) and not request.GET.get('test'): + elif is_tester(request.user) and not request.GET.get('test') or True: template = 'submissions/pool/pool.html' else: template = 'submissions/pool.html' @@ -679,13 +680,23 @@ def editorial_page(request, arxiv_identifier_w_vn_nr): Accessible for: Editor-in-charge and Editorial Administration """ - submission = get_object_or_404(Submission.objects.filter_for_eic(request.user), + submission = get_object_or_404(Submission.objects.pool_full(request.user), arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr) + full_access = True + if not request.user.has_perm('scipost.can_oversee_refereeing'): + # Administrators will be able to see all Submissions + if submission.editor_in_charge != request.user.contributor: + # The current user is not EIC of the Submission! + full_access = False + if not submission.voting_fellows.filter(contributor__user=request.user).exists(): + raise Http404 + context = { 'submission': submission, 'set_deadline_form': SetRefereeingDeadlineForm(), 'cycle_choice_form': SubmissionCycleChoiceForm(instance=submission), + 'full_access': full_access, } return render(request, 'submissions/editorial_page.html', context) @@ -714,7 +725,8 @@ def cycle_form_submit(request, arxiv_identifier_w_vn_nr): # Redirect to EIC Recommendation page immediately return redirect(reverse('submissions:eic_recommendation', args=[submission.arxiv_identifier_w_vn_nr])) - return redirect(reverse('submissions:editorial_page', args=[submission.arxiv_identifier_w_vn_nr])) + return redirect( + reverse('submissions:editorial_page', args=[submission.arxiv_identifier_w_vn_nr])) @login_required