diff --git a/colleges/forms.py b/colleges/forms.py index 3c1c8f31148a8d5cc3efe8a798a7bdd5cc5bf83e..4968ae748ce693b1b9be65a9508c49474cac2b15 100644 --- a/colleges/forms.py +++ b/colleges/forms.py @@ -86,6 +86,30 @@ class FellowshipRemoveSubmissionForm(forms.ModelForm): return fellowship +class FellowVotingRemoveSubmissionForm(forms.ModelForm): + """ + Use this form in admin-accessible views only! It could possibly reveal the + identity of the Editor-in-charge! + """ + class Meta: + model = Fellowship + fields = [] + + def __init__(self, *args, **kwargs): + self.submission = kwargs.pop('submission') + super().__init__(*args, **kwargs) + + def clean(self): + if self.submission.editor_in_charge == self.instance.contributor: + self.add_error(None, ('Submission cannot be removed as the Fellow is' + ' Editor-in-charge of this Submission.')) + + def save(self): + fellowship = self.instance + fellowship.voting_pool.remove(self.submission) + return fellowship + + class FellowshipAddSubmissionForm(forms.ModelForm): submission = forms.ModelChoiceField(queryset=None, to_field_name='arxiv_identifier_w_vn_nr', empty_label="Please choose the Submission to add to the pool") @@ -126,6 +150,28 @@ class SubmissionAddFellowshipForm(forms.ModelForm): return submission +class SubmissionAddVotingFellowForm(forms.ModelForm): + fellowship = forms.ModelChoiceField( + queryset=None, to_field_name='id', + empty_label="Please choose the Fellow to add to the Submission's Voting Fellows") + + class Meta: + model = Submission + fields = [] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + pool = self.instance.voting_fellows.values_list('id', flat=True) + self.fields['fellowship'].queryset = Fellowship.objects.active().exclude(id__in=pool) + + def save(self): + fellowship = self.cleaned_data['fellowship'] + submission = self.instance + submission.fellows.add(fellowship) + submission.voting_fellows.add(fellowship) + return submission + + class FellowshipRemoveProceedingsForm(forms.ModelForm): """ Use this form in admin-accessible views only! It could possibly reveal the 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/colleges/templates/colleges/fellowship_submission_remove_voting.html b/colleges/templates/colleges/fellowship_submission_remove_voting.html new file mode 100644 index 0000000000000000000000000000000000000000..837f1955a07c873134d63a767a177a1db28dea08 --- /dev/null +++ b/colleges/templates/colleges/fellowship_submission_remove_voting.html @@ -0,0 +1,28 @@ +{% extends 'submissions/admin/base.html' %} + +{% load bootstrap %} + +{% block breadcrumb_items %} + {{ block.super }} + <a href="{% url 'colleges:submission_voting_fellows' submission.arxiv_identifier_w_vn_nr %}" class="breadcrumb-item">Submission's Voting Fellows</a> + <span class="breadcrumb-item">Remove Fellow</span> +{% endblock %} + +{% block pagetitle %}: Remove Fellow from Submission's Voting Fellows{% endblock pagetitle %} + +{% block content %} + <h1>Remove Fellow from Submission's Voting Fellows</h1> + <h2 class="text-primary">Fellowship {{ fellowship }}</h2> + + <h3>Submission details</h3> + {% include 'submissions/_submission_summary_short.html' with submission=submission %} + <br> + + <form method="post"> + {% csrf_token %} + {{ form|bootstrap }} + <input class="btn btn-danger px-3" type="submit" value="Remove from Submission's Voting Fellows"> + </form> + + +{% endblock %} diff --git a/colleges/templates/colleges/submission_add_for_voting.html b/colleges/templates/colleges/submission_add_for_voting.html new file mode 100644 index 0000000000000000000000000000000000000000..35338669f512ce63787f41bef781d4a37b929e2e --- /dev/null +++ b/colleges/templates/colleges/submission_add_for_voting.html @@ -0,0 +1,30 @@ +{% extends 'submissions/admin/base.html' %} + +{% load bootstrap %} + +{% block breadcrumb_items %} + {{ block.super }} + <a href="{% url 'colleges:submission_voting_fellows' submission.arxiv_identifier_w_vn_nr %}" class="breadcrumb-item">Submission's Voting Fellows</a> + <span class="breadcrumb-item">Add Fellowship for voting</span> +{% endblock %} + +{% block pagetitle %}: Add Fellowship for voting{% endblock pagetitle %} + +{% block content %} + <h1>Add Fellowship to Submission's Voting Fellows</h1> + <h2 class="text-primary">{{submission.title}}</h2> + <h3 class="mb-3">by {{submission.author_list}}</h3> + {% include 'submissions/_submission_summary.html' with submission=submission hide_title=1 %} + <br> + + <h3>Choose one of the following (active) Fellowships to add to the Submission's Voting Fellows:</h3> + {% include 'partials/colleges/conflicts_of_interests.html' with submission=submission %} + <br> + <form method="post"> + {% csrf_token %} + {{ form|bootstrap }} + <input class="btn btn-primary" type="submit" value="Add Fellowship"> + </form> + + +{% endblock %} diff --git a/colleges/templates/colleges/submission_voting_fellows.html b/colleges/templates/colleges/submission_voting_fellows.html new file mode 100644 index 0000000000000000000000000000000000000000..bfd44e8702f682ec40da09c67c6048cbe8d8dc85 --- /dev/null +++ b/colleges/templates/colleges/submission_voting_fellows.html @@ -0,0 +1,48 @@ +{% extends 'submissions/admin/base.html' %} + +{% load bootstrap %} + +{% block breadcrumb_items %} + {{ block.super }} + <span class="breadcrumb-item">Submission's Voting Fellows</span> +{% endblock %} + +{% block pagetitle %}: Submission's Voting Fellows{% endblock pagetitle %} + +{% block content %} + <h1>Submission's Voting Fellows</h1> + <h2 class="text-primary">{{submission.title}}</h2> + <h3 class="mb-3">by {{submission.author_list}}</h3> + {% include 'submissions/_submission_summary.html' with submission=submission hide_title=1 %} + <br> + + <h3>Voting Fellows</h3> + {% include 'partials/colleges/conflicts_of_interests.html' with submission=submission %} + <table class="table table-hover"> + <thead> + <tr> + <th>Fellowship ID</th> + <th>Fellow</th> + <th>Type</th> + <th colspan="2">Date range</th> + </tr> + </thead> + <tbody> + {% for fellowship in submission.voting_fellows.all %} + <tr> + <td>{{ fellowship.id }}</td> + <td>{{ fellowship.contributor }}</td> + <td>{{ fellowship.guest|yesno:"Guest fellowship,Regular fellowship"|safe }}</td> + <td> + <a class="text-danger" href="{% url 'colleges:fellowship_remove_submission_voting' fellowship.id submission.arxiv_identifier_w_vn_nr %}">Remove this Fellowship from Submission's Voting Fellows</a> + </td> + </tr> + {% endfor %} + <tr> + <td colspan="4" class="py-3 text-center"><a href="{% url 'colleges:submission_add_fellowship_voting' submission.arxiv_identifier_w_vn_nr %}">Add Fellowship to this Submission's Voting Fellows</a></td> + </tr> + </tbody> + </table> + + +{% endblock %} diff --git a/colleges/urls.py b/colleges/urls.py index e5ddb94593e636403f50668cb851337abfa3e211..5b9f0faaa9c5b31cf18a60b7475402ba7eb1947e 100644 --- a/colleges/urls.py +++ b/colleges/urls.py @@ -15,9 +15,19 @@ urlpatterns = [ url(r'^fellowships/submissions/{regex}/$'.format( regex=SUBMISSIONS_COMPLETE_REGEX), views.submission_pool, name='submission'), + url(r'^fellowships/submissions/{regex}/voting$'.format( + regex=SUBMISSIONS_COMPLETE_REGEX), views.submission_voting_fellows, + name='submission_voting_fellows'), url(r'^fellowships/submissions/{regex}/add$'.format( regex=SUBMISSIONS_COMPLETE_REGEX), views.submission_add_fellowship, name='submission_add_fellowship'), + url(r'^fellowships/submissions/{regex}/voting/add$'.format( + regex=SUBMISSIONS_COMPLETE_REGEX), views.submission_add_fellowship_voting, + name='submission_add_fellowship_voting'), + url(r'^fellowships/(?P<id>[0-9]+)/submissions/{regex}/remove$'.format( + regex=SUBMISSIONS_COMPLETE_REGEX), views.fellowship_remove_submission_voting, + name='fellowship_remove_submission_voting'), + url(r'^fellowships/(?P<id>[0-9]+)/submissions/{regex}/remove$'.format( regex=SUBMISSIONS_COMPLETE_REGEX), views.fellowship_remove_submission, name='fellowship_remove_submission'), diff --git a/colleges/views.py b/colleges/views.py index 81bc5f917f3c16d522aedcd778f2fedfd4bee4d2..56920ea4df84449dec4d4ac8f53a87292b877719 100644 --- a/colleges/views.py +++ b/colleges/views.py @@ -3,12 +3,13 @@ from django.contrib.auth.decorators import login_required, permission_required from django.shortcuts import get_object_or_404, render, redirect from django.core.urlresolvers import reverse -from proceedings.models import Proceedings +# from proceedings.models import Proceedings from submissions.models import Submission from .forms import FellowshipForm, FellowshipTerminateForm, FellowshipRemoveSubmissionForm,\ FellowshipAddSubmissionForm, AddFellowshipForm, SubmissionAddFellowshipForm,\ - FellowshipRemoveProceedingsForm, FellowshipAddProceedingsForm + FellowshipRemoveProceedingsForm, FellowshipAddProceedingsForm, SubmissionAddVotingFellowForm,\ + FellowVotingRemoveSubmissionForm from .models import Fellowship @@ -111,6 +112,71 @@ def submission_pool(request, arxiv_identifier_w_vn_nr): return render(request, 'colleges/submission_pool.html', context) +@login_required +@permission_required('scipost.can_manage_college_composition', raise_exception=True) +def submission_voting_fellows(request, arxiv_identifier_w_vn_nr): + """ + List all Fellowships selected for voting on the EIC related to Submission. + """ + submission = get_object_or_404(Submission, arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr) + + context = { + 'submission': submission + } + return render(request, 'colleges/submission_voting_fellows.html', context) + + +@login_required +@permission_required('scipost.can_manage_college_composition', raise_exception=True) +def submission_add_fellowship_voting(request, arxiv_identifier_w_vn_nr): + """ + Add Fellowship to the Fellows voting on the EICRecommendation of a Submission. + """ + submission = get_object_or_404(Submission, arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr) + form = SubmissionAddVotingFellowForm(request.POST or None, instance=submission) + + if form.is_valid(): + form.save() + messages.success(request, 'Fellowship {fellowship} ({id}) added to voting Fellows.'.format( + fellowship=form.cleaned_data['fellowship'].contributor, + id=form.cleaned_data['fellowship'].id)) + return redirect(reverse('colleges:submission_voting_fellows', + args=(submission.arxiv_identifier_w_vn_nr,))) + + context = { + 'submission': submission, + 'form': form, + } + return render(request, 'colleges/submission_add_for_voting.html', context) + + +@login_required +@permission_required('scipost.can_manage_college_composition', raise_exception=True) +def fellowship_remove_submission_voting(request, id, arxiv_identifier_w_vn_nr): + """ + Remove Fellow from the EICRecommendation voting group for the Submission. + """ + fellowship = get_object_or_404(Fellowship, id=id) + submission = get_object_or_404(fellowship.voting_pool.all(), + arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr) + form = FellowVotingRemoveSubmissionForm(request.POST or None, + submission=submission, instance=fellowship) + + if form.is_valid() and request.POST: + form.save() + messages.success(request, 'Submission {sub} removed from Fellowship.'.format( + sub=arxiv_identifier_w_vn_nr)) + return redirect(reverse('colleges:submission_voting_fellows', + args=(submission.arxiv_identifier_w_vn_nr,))) + + context = { + 'fellowship': fellowship, + 'form': form, + 'submission': submission + } + return render(request, 'colleges/fellowship_submission_remove_voting.html', context) + + @login_required @permission_required('scipost.can_manage_college_composition', raise_exception=True) def submission_add_fellowship(request, arxiv_identifier_w_vn_nr): diff --git a/commentaries/forms.py b/commentaries/forms.py index e0df7db0437beb4251d5377eaeabbd71cea8b620..d92ccae78b24e3b2f62bda14953464a1f3f26514 100644 --- a/commentaries/forms.py +++ b/commentaries/forms.py @@ -9,6 +9,7 @@ from django.template.loader import get_template from .models import Commentary from .constants import COMMENTARY_PUBLISHED, COMMENTARY_PREPRINT +from comments.forms import CommentForm from scipost.services import DOICaller, ArxivCaller from scipost.models import Contributor @@ -101,7 +102,7 @@ class RequestCommentaryForm(forms.ModelForm): super().__init__(*args, **kwargs) def save(self, *args, **kwargs): - self.instance.parse_links_into_urls() + self.instance.parse_links_into_urls(commit=False) if self.requested_by: self.instance.requested_by = self.requested_by return super().save(*args, **kwargs) @@ -291,3 +292,66 @@ class CommentarySearchForm(forms.Form): title__icontains=self.cleaned_data['title'], pub_abstract__icontains=self.cleaned_data['abstract'], author_list__icontains=self.cleaned_data['author']).order_by('-pub_date') + + +class CommentSciPostPublication(CommentForm): + """ + This Form will let authors of an SciPost publication comment on their Publication + using the Commentary functionalities. It will create an Commentary page if it does not + exist yet. + + It inherits from ModelForm: CommentForm and thus will, by default, return a Comment! + """ + + def __init__(self, *args, **kwargs): + self.publication = kwargs.pop('publication') + self.current_user = kwargs.pop('current_user') + super().__init__(*args, **kwargs) + + def save(self, commit=True): + """ + Create (vetted) Commentary page if not exist and do save actions as + per original CommentForm. + """ + if not commit: + raise AssertionError('CommentSciPostPublication can only be used with commit=True') + + try: + commentary = self.publication.commentary + except Commentary.DoesNotExist: + submission = self.publication.accepted_submission + commentary = Commentary(**{ + # 'vetted_by': None, + 'requested_by': self.current_user.contributor, + 'vetted': True, + 'type': COMMENTARY_PUBLISHED, + 'discipline': self.publication.discipline, + 'domain': self.publication.domain, + 'subject_area': self.publication.subject_area, + 'title': self.publication.title, + 'arxiv_identifier': submission.arxiv_identifier_w_vn_nr, + 'arxiv_link': submission.arxiv_link, + 'pub_DOI': self.publication.doi_string, + 'metadata': self.publication.metadata, + 'scipost_publication': self.publication, + 'author_list': self.publication.author_list, + 'journal': self.publication.in_issue.in_volume.in_journal.get_name_display(), + 'pages': self.publication.in_issue.number, + 'volume': self.publication.in_issue.in_volume.number, + 'pub_date': self.publication.publication_date, + 'pub_abstract': self.publication.abstract, + }) + commentary.parse_links_into_urls(commit=False) + commentary.save() + commentary.authors.add(*self.publication.authors.all()) + commentary.authors_claims.add(*self.publication.authors_claims.all()) + commentary.authors_false_claims.add(*self.publication.authors_false_claims.all()) + + # Original saving steps + comment = super().save(commit=False) + comment.author = self.current_user.contributor + comment.is_author_reply = True + comment.content_object = commentary + comment.save() + comment.grant_permissions() + return comment diff --git a/commentaries/migrations/0020_auto_20171111_1153.py b/commentaries/migrations/0020_auto_20171111_1153.py new file mode 100644 index 0000000000000000000000000000000000000000..529c8c7d9e10a7d53155730031873343c9f4b68a --- /dev/null +++ b/commentaries/migrations/0020_auto_20171111_1153.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2017-11-11 10:53 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0052_auto_20171107_1354'), + ('commentaries', '0019_auto_20170925_2124'), + ] + + operations = [ + migrations.AddField( + model_name='commentary', + name='scipost_publication', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='commentary', to='journals.Publication'), + ), + migrations.AlterField( + model_name='commentary', + name='title', + field=models.CharField(max_length=300), + ), + ] diff --git a/commentaries/models.py b/commentaries/models.py index add1f6b8ca87771c4527dd64646ccb71cb405ff6..56e5f467efe795e6082410663202f94c427465d4 100644 --- a/commentaries/models.py +++ b/commentaries/models.py @@ -28,7 +28,9 @@ class Commentary(TimeStampedModel): subject_area = models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS, default='Phys:QP') open_for_commenting = models.BooleanField(default=True) - title = models.CharField(max_length=300, verbose_name='title') + + # Article/publication data + title = models.CharField(max_length=300) arxiv_identifier = models.CharField(max_length=100, blank=True, verbose_name="arXiv identifier (including version nr)") arxiv_link = models.URLField(verbose_name='arXiv link (including version nr)', blank=True) @@ -41,9 +43,11 @@ class Commentary(TimeStampedModel): arxiv_or_DOI_string = models.CharField(max_length=100, verbose_name='string form of arxiv nr or' ' DOI for commentary url') - author_list = models.CharField(max_length=1000) + scipost_publication = models.OneToOneField('journals.Publication', null=True, blank=True, + related_name='commentary') # Authors which have been mapped to contributors: + author_list = models.CharField(max_length=1000) authors = models.ManyToManyField('scipost.Contributor', blank=True, related_name='commentaries') authors_claims = models.ManyToManyField('scipost.Contributor', blank=True, @@ -71,7 +75,7 @@ class Commentary(TimeStampedModel): def get_absolute_url(self): return reverse('commentaries:commentary', args=(self.arxiv_or_DOI_string,)) - def parse_links_into_urls(self, commit=False): + def parse_links_into_urls(self, commit=True): """ Takes the arXiv nr or DOI and turns it into the urls """ if self.pub_DOI: self.arxiv_or_DOI_string = self.pub_DOI diff --git a/commentaries/templates/commentaries/_commentary_summary.html b/commentaries/templates/commentaries/_commentary_summary.html index 914dd82eadc074a2b44a9ca2c396aa7837c2fbe3..7567fea0d99cbf2d19e9d17abae4c852be517e06 100644 --- a/commentaries/templates/commentaries/_commentary_summary.html +++ b/commentaries/templates/commentaries/_commentary_summary.html @@ -18,28 +18,33 @@ </td> </tr> {% if commentary.type == 'published' %} - <tr> - <td>Journal ref.:</td> - <td>{{commentary.journal}} {{commentary.volume}}, {{commentary.pages}}</td> - </tr> - <tr> - <td>DOI:</td> - <td> - <a href="{{commentary.pub_DOI_link}}" target="_blank">{{commentary.pub_DOI_link}}</a> - </td> - </tr> + <tr> + <td>Journal ref.:</td> + <td>{{commentary.journal}} {{commentary.volume}}{% if commentary.pages %}, {{commentary.pages}}{% endif %}</td> + </tr> + <tr> + <td>DOI:</td> + <td> + <a href="{{commentary.pub_DOI_link}}" target="_blank">{{commentary.pub_DOI_link}}</a> + </td> + </tr> {% elif commentary.type == 'preprint' %} - <tr> - <td>arxiv Link:</td> - <td> - <a href="{{commentary.arxiv_link}}" target="_blank">{{commentary.arxiv_link}}</a> - </td> - </tr> + <tr> + <td>arxiv Link:</td> + <td> + <a href="{{commentary.arxiv_link}}" target="_blank">{{commentary.arxiv_link}}</a> + </td> + </tr> {% endif %} {% if commentary.pub_date %} - <tr> - <td>Date:</td> - <td>{{commentary.pub_date}}</td> - </tr> + <tr> + <td>Date:</td> + <td>{{commentary.pub_date}}</td> + </tr> {% endif %} </table> + +{% if commentary.scipost_publication %} + <br> + <p class="my-0">Published in {{commentary.scipost_publication.in_issue.in_volume.in_journal.get_name_display}}: <a href="{{commentary.scipost_publication.get_absolute_url}}">{{commentary.scipost_publication.in_issue.in_volume.in_journal.get_abbreviation_citation}} <strong>{{commentary.scipost_publication.in_issue.in_volume.number}}</strong>, {{commentary.scipost_publication.get_paper_nr}} ({{commentary.scipost_publication.publication_date|date:'Y'}})</a></p> +{% endif %} diff --git a/commentaries/templates/commentaries/base.html b/commentaries/templates/commentaries/base.html new file mode 100644 index 0000000000000000000000000000000000000000..61d1457ba3b5e42318b32650a2adb8dff66d941b --- /dev/null +++ b/commentaries/templates/commentaries/base.html @@ -0,0 +1,11 @@ +{% extends 'scipost/base.html' %} + +{% block breadcrumb %} + <nav class="breadcrumb py-md-2 px-0"> + <div class="container"> + {% block breadcrumb_items %} + <a href="{% url 'commentaries:commentaries' %}" class="breadcrumb-item">Commentaries</a> + {% endblock %} + </div> + </nav> +{% endblock %} diff --git a/commentaries/templates/commentaries/comment_on_publication.html b/commentaries/templates/commentaries/comment_on_publication.html new file mode 100644 index 0000000000000000000000000000000000000000..2471db9caa1cca22efdaca2a182af16b85b65a3a --- /dev/null +++ b/commentaries/templates/commentaries/comment_on_publication.html @@ -0,0 +1,22 @@ +{% extends 'journals/base_detail_page.html' %} + +{% block pagetitle %}: Comment on your Publication{% endblock pagetitle %} + +{% block breadcrumb_items %} + {{ block.super }} + <span class="breadcrumb-item">Comment on your Publication</span> +{% endblock %} + +{% block content %} + +<h1 class="highlight">Comment on your Publication</h1> + +{% include 'partials/journals/publication_li_content.html' with publication=publication %} + +<h3 class="mt-2">Abstract</h3> +<p>{{ publication.abstract|default:'No abstract found' }}</p> + +{% url 'comments:new_comment' object_id=object_id type_of_object=type_of_object as url %} +{% include 'comments/_add_comment_form.html' with form=form url=url %} + +{% endblock content %} diff --git a/commentaries/templates/commentaries/commentary_detail.html b/commentaries/templates/commentaries/commentary_detail.html index ad8cee7adb14d5cf208ef086a3dc79d3065cfe17..4d0160aa6a71bb8447f9fcb3fd1aed472e771f25 100644 --- a/commentaries/templates/commentaries/commentary_detail.html +++ b/commentaries/templates/commentaries/commentary_detail.html @@ -1,34 +1,25 @@ -{% extends 'scipost/base.html' %} +{% extends 'commentaries/base.html' %} + +{% load scipost_extras %} {% block pagetitle %}: Commentary detail{% endblock pagetitle %} -{% block headsup %} +{% block breadcrumb_items %} + {{ block.super }} + <span class="breadcrumb-item">{{ commentary }}</span> +{% endblock %} -{% load scipost_extras %} +{% block content %} -{% endblock headsup %} +<h1 class="highlight">SciPost Commentary Page</h1> -{% block content %} +<h3>Original publication:</h3> +{% include 'commentaries/_commentary_summary.html' with commentary=commentary %} + +<br> -<div class="row"> - <div class="col-12"> - <h1 class="highlight">SciPost Commentary Page (non-SciPost publications)</h1> - </div> -</div> - -<div class="row"> - <div class="col-12"> - <h2>Original publication: </h2> - {% include 'commentaries/_commentary_summary.html' with commentary=commentary %} - </div> -</div> - -<div class="row"> - <div class="col-12"> - <h3>Abstract:</h3> - <p>{{ commentary.pub_abstract }}</p> - </div> -</div> +<h3>Abstract:</h3> +<p>{{ commentary.pub_abstract }}</p> {% include 'scipost/comments_block.html' with comments=commentary.comments.vetted type_of_object='Commentary' %} diff --git a/commentaries/urls.py b/commentaries/urls.py index b3c4e999c7119ae5d1b063efd5c80c3820cffd71..0679f78bb7523a5e6f74f514d8c560ee6c526b63 100644 --- a/commentaries/urls.py +++ b/commentaries/urls.py @@ -35,4 +35,8 @@ urlpatterns = [ name='vet_commentary_requests_submit'), url(r'^vet_commentary_requests/(?P<commentary_id>[0-9]+)/modify$', views.modify_commentary_request, name='modify_commentary_request'), + + # Commentaries on SciPost Publications + url(r'^publications/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/comment$', + views.comment_on_publication, name='comment_on_publication') ] diff --git a/commentaries/views.py b/commentaries/views.py index dd60ecd04fe4c11fe0b4be93ae4f4db60f8d9a6b..015fb814d1a87c8739186b1c1001ecdad39df58c 100644 --- a/commentaries/views.py +++ b/commentaries/views.py @@ -3,6 +3,7 @@ from django.contrib import messages from django.contrib.auth.decorators import login_required, permission_required from django.core.mail import EmailMessage from django.core.urlresolvers import reverse, reverse_lazy +from django.db import transaction from django.shortcuts import redirect from django.template.loader import render_to_string from django.views.generic.edit import CreateView @@ -12,10 +13,12 @@ from django.http import Http404 from .models import Commentary from .forms import DOIToQueryForm, ArxivQueryForm, VetCommentaryForm, RequestCommentaryForm,\ - CommentarySearchForm, RequestPublishedArticleForm, RequestArxivPreprintForm + CommentarySearchForm, RequestPublishedArticleForm, RequestArxivPreprintForm,\ + CommentSciPostPublication from comments.models import Comment from comments.forms import CommentForm +from journals.models import Publication from scipost.mixins import PaginationMixin import strings @@ -238,3 +241,26 @@ def commentary_detail(request, arxiv_or_DOI_string): context = {'commentary': commentary, 'author_replies': author_replies, 'form': form} return render(request, 'commentaries/commentary_detail.html', context) + + +@login_required +@permission_required('scipost.can_submit_comments', raise_exception=True) +@transaction.atomic +def comment_on_publication(request, doi_label): + """ + This will let authors of an SciPost publication comment on their Publication by + automatically creating a Commentary page if not exist already. + """ + publication = get_object_or_404(Publication.objects.published(), + doi_label=doi_label, authors=request.user.contributor) + form = CommentSciPostPublication(request.POST or None, request.FILES or None, + publication=publication, current_user=request.user) + if form.is_valid(): + comment = form.save() + messages.success(request, strings.acknowledge_request_commentary) + return redirect(comment.content_object.get_absolute_url()) + context = { + 'publication': publication, + 'form': form + } + return render(request, 'commentaries/comment_on_publication.html', context) diff --git a/comments/templates/comments/_add_comment_form.html b/comments/templates/comments/_add_comment_form.html index 034d32a09f17a2ab79db85e75f482d43c481a86a..8225e51af3c7c597a496901cf3505b347e02678c 100644 --- a/comments/templates/comments/_add_comment_form.html +++ b/comments/templates/comments/_add_comment_form.html @@ -14,7 +14,7 @@ </script> {% endblock %} -<form enctype="multipart/form-data" action="{{url}}" method="post"> +<form enctype="multipart/form-data" {% if url %}action="{{url}}" {% endif %}method="post"> {% csrf_token %} <div class="row"> <div class="col-md-9"> diff --git a/funders/models.py b/funders/models.py index 5ef9a4119c2a97da0fd36c758998004b93cf94e2..828d275f9751206067c9ac07bd80f9472f9d970b 100644 --- a/funders/models.py +++ b/funders/models.py @@ -1,5 +1,6 @@ from django.db import models from django.db.models import Q +from django.urls import reverse from journals.models import Publication @@ -22,6 +23,9 @@ class Funder(models.Model): result += ' (%s)' % self.acronym return result + def get_absolute_url(self): + return reverse('funders:funder_publications', args=(self.id,)) + def all_related_publications(self): return Publication.objects.filter( Q(funders_generic=self) | Q(grants__funder=self)).distinct() diff --git a/funders/templates/funders/funder_details.html b/funders/templates/funders/funder_details.html index cbb87326329e6355de796200919563e75fd01ed0..382cb69bb5ec80832975e65ba26e9bf61f000bd5 100644 --- a/funders/templates/funders/funder_details.html +++ b/funders/templates/funders/funder_details.html @@ -2,8 +2,6 @@ {% block pagetitle %}: Funder details{% endblock pagetitle %} -{% load bootstrap %} - {% block content %} <h1 class="highlight">Funder {{ funder.name }}</h1> diff --git a/funders/urls.py b/funders/urls.py index b424202a907b91320ab7dddbbb75d4e3d08a2376..6766a095b6aead907943bc6f501317e76d1ce5ff 100644 --- a/funders/urls.py +++ b/funders/urls.py @@ -6,8 +6,8 @@ urlpatterns = [ url(r'^$', views.funders, name='funders'), url(r'^query_crossref_for_funder$', views.query_crossref_for_funder, name='query_crossref_for_funder'), - url(r'^funders/add$', views.add_funder, name='add_funder'), - url(r'^funders/(?P<funder_id>[0-9]+)/$', views.funder_publications, + url(r'^add$', views.add_funder, name='add_funder'), + url(r'^(?P<funder_id>[0-9]+)/$', views.funder_publications, name='funder_publications'), url(r'^grants/add$', views.add_grant, name='add_grant'), ] diff --git a/funders/views.py b/funders/views.py index 1b3d3b8c20ab40e39a335be12f57d250615c24f6..b11b7a15baf0991b61bb864575f8d9e4a34a510f 100644 --- a/funders/views.py +++ b/funders/views.py @@ -53,10 +53,10 @@ def add_funder(request): return redirect(reverse('funders:funders')) -@permission_required('scipost.can_view_all_funding_info', raise_exception=True) +# @permission_required('scipost.can_view_all_funding_info', raise_exception=True) def funder_publications(request, funder_id): """ - See details of specific Funder. + See details of specific Funder (publicly accessible). """ funder = get_object_or_404(Funder, id=funder_id) context = {'funder': funder} diff --git a/journals/managers.py b/journals/managers.py index 3d5c8e9168a1ca9800edae2e5e5a267efcc42670..0b058c1b3a78d47baca5c366cf9d94c8a71e60a3 100644 --- a/journals/managers.py +++ b/journals/managers.py @@ -39,7 +39,7 @@ class IssueManager(models.Manager): **kwargs).order_by('-until_date').first() -class PublicationManager(models.Manager): +class PublicationQuerySet(models.QuerySet): def get_published(self, *args, **kwargs): try: return self.published(*args, **kwargs)[0] diff --git a/journals/models.py b/journals/models.py index d1ea12b9da0affde8039631ac717e3bfd8bb4364..de8c4ded3df04c91c56932294efde0f48bbfde03 100644 --- a/journals/models.py +++ b/journals/models.py @@ -11,7 +11,7 @@ from .constants import SCIPOST_JOURNALS, SCIPOST_JOURNALS_DOMAINS,\ STATUS_DRAFT, STATUS_PUBLISHED, ISSUE_STATUSES,\ CCBY4, CC_LICENSES, CC_LICENSES_URI from .helpers import paper_nr_string, journal_name_abbrev_citation -from .managers import IssueManager, PublicationManager, JournalManager +from .managers import IssueManager, PublicationQuerySet, JournalManager from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS from scipost.fields import ChoiceArrayField @@ -53,7 +53,7 @@ class Journal(models.Model): class Volume(models.Model): - in_journal = models.ForeignKey(Journal, on_delete=models.CASCADE) + in_journal = models.ForeignKey('journals.Journal', on_delete=models.CASCADE) number = models.PositiveSmallIntegerField() start_date = models.DateField(default=timezone.now) until_date = models.DateField(default=timezone.now) @@ -72,7 +72,7 @@ class Volume(models.Model): class Issue(models.Model): - in_volume = models.ForeignKey(Volume, on_delete=models.CASCADE) + in_volume = models.ForeignKey('journals.Volume', on_delete=models.CASCADE) number = models.PositiveSmallIntegerField() start_date = models.DateField(default=timezone.now) until_date = models.DateField(default=timezone.now) @@ -129,7 +129,7 @@ class Publication(models.Model): """ # Publication data accepted_submission = models.OneToOneField('submissions.Submission', on_delete=models.CASCADE) - in_issue = models.ForeignKey(Issue, on_delete=models.CASCADE) + in_issue = models.ForeignKey('journals.Issue', on_delete=models.CASCADE) paper_nr = models.PositiveSmallIntegerField() # Core fields @@ -187,7 +187,7 @@ class Publication(models.Model): latest_metadata_update = models.DateTimeField(blank=True, null=True) latest_activity = models.DateTimeField(default=timezone.now) - objects = PublicationManager() + objects = PublicationQuerySet.as_manager() def __str__(self): header = (self.citation() + ', ' diff --git a/journals/templates/journals/add_author.html b/journals/templates/journals/add_author.html index 89686e236c86c06fe66a52372e098f01f4922d0b..23e924b7ee3d0660bb95f4908c36055bbea3d0e6 100644 --- a/journals/templates/journals/add_author.html +++ b/journals/templates/journals/add_author.html @@ -19,94 +19,78 @@ {% block content %} -<div class="row"> - <div class="col-12"> - <h1 class="highlight">Add author to publication</h1> - </div> -</div> - -<div class="row"> - <div class="col-12"> - {% include 'journals/_publication_details.html' with publication=publication %} - </div> -</div> +<h1 class="highlight">Add author to publication</h1> +{% include 'partials/journals/publication_li_content.html' with publication=publication %} +<br> -<div class="row"> - <div class="col-12"> - <h2 class="highlight">Add an (unregistered) author</h2> - </div> -</div> - <div class="row"> <div class="col-12"> <h3>Current list of authors as contributors:</h3> - <ul class="list-group list-group-noborder"> + <ul> {% for author in publication.authors.all %} - <li class="list-group-item py-1 pl-2"> - <a href="{% url 'scipost:contributor_info' author.id %}">{{ author.user.first_name }} {{ author.user.last_name }}</a> - </li> + <li><a href="{% url 'scipost:contributor_info' author.id %}">{{ author.user.first_name }} {{ author.user.last_name }}</a></li> {% empty %} - No unregistered authors known. + <li>No unregistered authors known.</li> {% endfor %} </ul> <h3>Current list of additional authors (unregistered):</h3> - <ul class="list-group list-group-noborder"> + <ul> {% for author in publication.authors_unregistered.all %} - <li class="list-group-item py-1 pl-2">{{ author }}</li> + <li>{{ author }}</li> {% empty %} - No unregistered authors known. + <li>No unregistered authors known.</li> {% endfor %} </ul> - <hr class="small"> - - <div class="row"> - <div class="col-md-8"> - <h3>Search for missing author:</h3> - <form action="{% url 'journals:add_author' publication.id %}" method="post"> - {% csrf_token %} - {{form|bootstrap}} - <input class="btn btn-secondary" type="submit" value="Search"> - </form> - - {% if form.has_changed %} - <h3 class="mt-4">Identified as contributor:</h3> - <ul class="list-group"> - {% for contributor in contributors_found %} - <li class="list-group-item p-2"> - <div class="d-block w-100 font-weight-bold">{{ contributor.user.first_name }} {{ contributor.user.last_name }}</div> - <a class="d-block" href="{% url 'journals:add_author' publication_id=publication.id contributor_id=contributor.id %}">Add this Contributor as author of this Publication</a> - </li> - {% empty %} - <span class="text-danger">No Contributor with this name could be identified.</span> - {% endfor %} - </ul> - - <h3 class="mt-2">Identified as existing unregistered author:</h3> - <ul class="list-group"> - {% for unreg_auth in unregistered_authors_found %} - <li class="list-group-item"> - <div class="d-block w-100 font-weight-bold">{{ unreg_auth }} - <a class="d-block" href="{% url 'journals:add_unregistered_author' publication_id=publication.id unregistered_author_id=unreg_auth.id %}">Add this unregistered author as author of this Publication</a> - </li> - {% empty %} - <span class="text-danger">No UnregisteredAuthor with this name could be found in the database.</span> - {% endfor %} - </ul> - - <h3 class="mt-3">You can otherwise create an UnregisteredAuthor object instance and link it to this publication:</h3> - <form action="{% url 'journals:add_new_unreg_author' publication_id=publication.id %}" method="post"> - {% csrf_token %} - {{ new_unreg_author_form|bootstrap }} - <input class="btn btn-secondary" type="submit" value="Add"> - </form> - - {% endif %} - </div> - </div> + <br> + <h2 class="highlight">Add an (unregistered) author</h2> + + <h3>Search for missing author:</h3> + <form action="{% url 'journals:add_author' publication.id %}" method="post"> + {% csrf_token %} + {{form|bootstrap}} + <input class="btn btn-primary" type="submit" value="Search"> + </form> + + {% if form.has_changed %} + <br> + <h3 class="mt-2">Identified as contributor:</h3> + <ul class="list-group"> + {% for contributor in contributors_found %} + <li class="list-group-item p-2"> + <div class="d-block w-100 font-weight-bold">{{ contributor.user.first_name }} {{ contributor.user.last_name }}</div> + <a class="d-block" href="{% url 'journals:add_author' publication_id=publication.id contributor_id=contributor.id %}">Add this Contributor as author of this Publication</a> + </li> + {% empty %} + <span class="text-danger">No Contributor with this name could be identified.</span> + {% endfor %} + </ul> + + <h3 class="mt-2">Identified as existing unregistered author:</h3> + <ul class="list-group"> + {% for unreg_auth in unregistered_authors_found %} + <li class="list-group-item"> + <div class="d-block w-100 font-weight-bold">{{ unreg_auth }} + <a class="d-block" href="{% url 'journals:add_unregistered_author' publication_id=publication.id unregistered_author_id=unreg_auth.id %}">Add this unregistered author as author of this Publication</a> + </li> + {% empty %} + <span class="text-danger">No UnregisteredAuthor with this name could be found in the database.</span> + {% endfor %} + </ul> + + <h3 class="mt-3">You can otherwise create an UnregisteredAuthor object instance and link it to this publication:</h3> + <form action="{% url 'journals:add_new_unreg_author' publication_id=publication.id %}" method="post"> + {% csrf_token %} + {{ new_unreg_author_form|bootstrap }} + <input class="btn btn-primary" type="submit" value="Add"> + </form> + + {% endif %} + + <br> <h3> - <a href="{{publication.get_absolute_url}}">Return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a> + <a href="{{publication.get_absolute_url}}">Return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a>. </h3> </div> </div> diff --git a/journals/templates/journals/base_detail_page.html b/journals/templates/journals/base_detail_page.html new file mode 100644 index 0000000000000000000000000000000000000000..5881a76d967e44d57bdbbcadb0217a8ddd56b5ec --- /dev/null +++ b/journals/templates/journals/base_detail_page.html @@ -0,0 +1,17 @@ +{% extends 'scipost/base.html' %} + +{% load staticfiles %} + +{% block pagetitle %}: {{journal}}{% endblock pagetitle %} +{% block body_class %}{{block.super}} journals{% endblock %} + +{% block breadcrumb %} + <nav class="breadcrumb py-md-2 px-0 hidden-sm-down"> + <div class="container"> + {% block breadcrumb_items %} + <a href="{% url 'journals:journals' %}" class="breadcrumb-item">Journals</a> + <a href="{% url 'scipost:publication_detail' publication.doi_label %}" class="breadcrumb-item">{{ publication.doi_label }}</a> + {% endblock %} + </div> + </nav> +{% endblock %} diff --git a/journals/templates/journals/publication_detail.html b/journals/templates/journals/publication_detail.html index b86f7d42920366287c78f855a41abf1eb8f13cbb..a02fa03f8809361ed24f0dac7de156c36278cee4 100644 --- a/journals/templates/journals/publication_detail.html +++ b/journals/templates/journals/publication_detail.html @@ -49,7 +49,14 @@ {% block content %} {% is_edcol_admin request.user as is_edcol_admin %} - {% include 'journals/_publication_details.html' with publication=publication %} + {% include 'partials/journals/publication_summary.html' with publication=publication %} + + {% if publication.commentary and publication.commentary.comments.vetted.exists %} + <h3>Post-publication commentaries</h3> + <p> + This Publication ({{ publication.commentary.comments.vetted.count }}) has been commented on, see <a href="{{ publication.commentary.get_absolute_url }}">this Publication's Commentary page</a> for details. + </p> + {% endif %} <hr> {% if publication.citedby|length >= 1 %} @@ -90,16 +97,35 @@ {% if is_edcol_admin %} {# This function is not available for public yet! #} - <h3>Institutions related to this Publication: <small>(adminstrator only)</small></h3> - <ul> - {% for institution in publication.institutions.all %} - <li>{{ institution }}</li> - {% endfor %} - </ul> + <em>The following is not available for the public yet:</em> + {% if publication.funders_generic.exists %} + <h3>Funder{{ publication.funders_generic.count|pluralize }} for this publication:</h3> + <ul> + {% for funder in publication.funders_generic.all %} + <li><a href="{{ funder.get_absolute_url }}">{{ funder }}</a></li> + {% endfor %} + </ul> + {% endif %} + + {% if publication.institutions.exists %} + <h3>Institution{{ publication.institutions.count|pluralize }} related to this Publication:</h3> + <ul> + {% for institution in publication.institutions.all %} + <li>{{ institution }}</li> + {% endfor %} + </ul> + {% endif %} {% endif %} </div> </div> + {% if request.user and request.user.contributor in publication.authors.all %} + <h3>Author actions</h3> + <ul> + <li><a href="{% url 'commentaries:comment_on_publication' publication.doi_label %}">Place a comment on this publication</a></li> + </ul> + {% endif %} + {% if is_edcol_admin %} <hr> <div class="row"> diff --git a/journals/templates/journals/_publication_details_small.html b/journals/templates/partials/journals/publication_li_content.html similarity index 85% rename from journals/templates/journals/_publication_details_small.html rename to journals/templates/partials/journals/publication_li_content.html index a7a1376c2488114e9688d73059a4cb1fd1a3183d..2f8346ba21f8b2516f3cc1698d256f787030363d 100644 --- a/journals/templates/journals/_publication_details_small.html +++ b/journals/templates/partials/journals/publication_li_content.html @@ -1,7 +1,7 @@ <h5 class="pb-0">{{publication.get_subject_area_display}}</h5> <h3><a href="{{publication.get_absolute_url}}">{{publication.title}}</a></h3> -<p class="mt-0 mb-3">{{ publication.author_list }}</p> +<p class="mt-0 mb-2">{{ publication.author_list }}</p> <p class="text-muted mb-0"> {{ publication.citation }} · <span class="font-weight-light">published {{ publication.publication_date|date:'j F Y' }}</span> </p> diff --git a/journals/templates/journals/_publication_details.html b/journals/templates/partials/journals/publication_summary.html similarity index 100% rename from journals/templates/journals/_publication_details.html rename to journals/templates/partials/journals/publication_summary.html diff --git a/production/admin.py b/production/admin.py index 2880659cd81d1d9efe90260d12ff1c7c9bbc23b5..e0452b589e599e8d32bf05776fe9668fa0c5bf92 100644 --- a/production/admin.py +++ b/production/admin.py @@ -2,7 +2,8 @@ from django.contrib import admin from guardian.admin import GuardedModelAdmin -from .models import ProductionStream, ProductionEvent, ProductionUser, Proofs +from .models import ProductionStream, ProductionEvent, ProductionUser, Proofs,\ + ProductionEventAttachment def event_count(obj): @@ -38,4 +39,5 @@ class ProductionProofsAdmin(admin.ModelAdmin): admin.site.register(Proofs, ProductionProofsAdmin) admin.site.register(ProductionUser) admin.site.register(ProductionEvent) +admin.site.register(ProductionEventAttachment) admin.site.register(ProductionStream, ProductionStreamAdmin) diff --git a/production/forms.py b/production/forms.py index 1768d6d12d07e8e59cf64f72db7e501dea1d64ae..dabd1d19de44952673b90a7206f8439a361b0a91 100644 --- a/production/forms.py +++ b/production/forms.py @@ -3,7 +3,8 @@ import datetime from django import forms from . import constants -from .models import ProductionUser, ProductionStream, ProductionEvent, Proofs +from .models import ProductionUser, ProductionStream, ProductionEvent, Proofs,\ + ProductionEventAttachment from .signals import notify_stream_status_change today = datetime.datetime.today() @@ -144,6 +145,7 @@ class ProofsDecisionForm(forms.ModelForm): decision = forms.ChoiceField(choices=[(True, 'Accept Proofs for publication'), (False, 'Decline Proofs for publication')]) feedback = forms.CharField(required=False, widget=forms.Textarea) + feedback_attachment = forms.FileField(required=False) class Meta: model = Proofs @@ -173,9 +175,14 @@ class ProofsDecisionForm(forms.ModelForm): prodevent = ProductionEvent( stream=proofs.stream, event='status', - comments='Received feedback from the authors: {comments}'.format( + comments='<em>Received feedback from the authors:</em><br>{comments}'.format( comments=comments), noted_by=proofs.stream.supervisor ) prodevent.save() + if self.cleaned_data.get('feedback_attachment'): + attachment = ProductionEventAttachment( + attachment=self.cleaned_data['feedback_attachment'], + production_event=prodevent) + attachment.save() return proofs diff --git a/production/migrations/0033_productioneventattachment.py b/production/migrations/0033_productioneventattachment.py new file mode 100644 index 0000000000000000000000000000000000000000..a9a7fdaa7381c413eb64499b7b856aca5f8061c9 --- /dev/null +++ b/production/migrations/0033_productioneventattachment.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2017-11-12 16:05 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import production.models +import scipost.storage + + +class Migration(migrations.Migration): + + dependencies = [ + ('production', '0032_auto_20171010_1008'), + ] + + operations = [ + migrations.CreateModel( + name='ProductionEventAttachment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('attachment', models.FileField(storage=scipost.storage.SecureFileStorage(), upload_to=production.models.production_event_upload_location)), + ('production_event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='production.ProductionEvent')), + ], + ), + ] diff --git a/production/models.py b/production/models.py index 65ace229bff3e4de8987e7199005eeb600c4b2f6..12c461b7d0523b84404f1f3fef6b112779ec9eb8 100644 --- a/production/models.py +++ b/production/models.py @@ -106,6 +106,29 @@ class ProductionEvent(models.Model): return self.stream.notification_name +def production_event_upload_location(instance, filename): + submission = instance.production_event.stream.submission + return 'UPLOADS/PRODSTREAMS/{year}/{arxiv}/{filename}'.format( + year=submission.submission_date.year, + arxiv=submission.arxiv_identifier_wo_vn_nr, + filename=filename) + + +class ProductionEventAttachment(models.Model): + """ + An ProductionEventAttachment is in general used by authors to reply to an Proofs version + with their version of the Proofs with comments. + """ + production_event = models.ForeignKey('production.ProductionEvent', on_delete=models.CASCADE, + related_name='attachments') + attachment = models.FileField(upload_to=production_event_upload_location, + storage=SecureFileStorage()) + + def get_absolute_url(self): + return reverse('production:production_event_attachment_pdf', + args=(self.production_event.stream.id, self.id,)) + + def proofs_upload_location(instance, filename): submission = instance.stream.submission return 'UPLOADS/PROOFS/{year}/{arxiv}/{filename}'.format( diff --git a/production/templates/production/partials/production_events.html b/production/templates/production/partials/production_events.html index 653f9c3df4bbf1999172d6fd62d320206a720b41..74fbd57a54ee493a522c938c6f1e6fd311ae9857 100644 --- a/production/templates/production/partials/production_events.html +++ b/production/templates/production/partials/production_events.html @@ -34,10 +34,18 @@ {% if event.noted_to %} {{ event.noted_by.user.first_name }} {{ event.noted_by.user.last_name }} {{ event.comments|linebreaksbr }} {{ event.noted_to.user.first_name }} {{ event.noted_to.user.last_name }}. {% else %} - {{ event.comments|linebreaksbr }} + {{ event.comments|safe|linebreaksbr }} {% endif %} </p> {% endif %} + + {% if event.attachments.exists %} + <ul> + {% for attachment in event.attachments.all %} + <li><a href="{{ attachment.get_absolute_url }}" target="_blank">Download Attachment {{ forloop.counter }}</a></li> + {% endfor %} + </ul> + {% endif %} </li> {% empty %} <li>No events were found.</li> diff --git a/production/templates/production/partials/production_stream_card_completed.html b/production/templates/production/partials/production_stream_card_completed.html index e938b1d37d4c21929b5156d3595f5f10fd54976b..38f1c7fa637e5fafee9117caf225492c8dad3abb 100644 --- a/production/templates/production/partials/production_stream_card_completed.html +++ b/production/templates/production/partials/production_stream_card_completed.html @@ -54,8 +54,8 @@ <ul> {% for proofs in stream.proofs.all %} <li class="py-1"> - <a href="{% url 'production:proofs' stream_id=stream.id version=proofs.version %}">Version {{ proofs.version }}</a><br> - Uploaded by {{ proofs.uploaded_by.user.first_name }} {{ proofs.uploaded_by.user.last_name }}<br> + <a href="{% url 'production:proofs' stream_id=stream.id version=proofs.version %}">Version {{ proofs.version }}</a> · <span class="label label-secondary label-sm">{{ proofs.get_status_display }}</span><br> + Uploaded by: {{ proofs.uploaded_by.user.first_name }} {{ proofs.uploaded_by.user.last_name }}<br> Accessible for authors: {{ proofs.accessible_for_authors|yesno:'<strong>Yes</strong>,No'|safe }}<br> {% if perms.scipost.can_run_proofs_by_authors %} @@ -71,8 +71,6 @@ </ul> {% endif %} {% endif %} - - <span class="label label-secondary label-sm">{{ proofs.get_status_display }}</span> </li> {% empty %} <li>No Proofs found.</li> diff --git a/production/templates/production/proofs.html b/production/templates/production/proofs.html index bfbaa7937fdd75a7a6d0a230882174e77609428c..b939acd9743c71e4413761dc6d3ce4007bb1ea30 100644 --- a/production/templates/production/proofs.html +++ b/production/templates/production/proofs.html @@ -38,8 +38,7 @@ </li> {% elif proofs.status == 'accepted_sup' %} <li><a href="{% url 'production:send_proofs' proofs.stream.id proofs.version %}">Send proofs to authors</a></li> - {% endif %} - {% if proofs.status != 'uploaded' %} + {% else %} <li><a href="{% url 'production:toggle_accessibility' proofs.stream.id proofs.version %}">{{ proofs.accessible_for_authors|yesno:'Hide,Make accessible' }} for authors</a></li> {% endif %} {% endif %} diff --git a/production/urls.py b/production/urls.py index c44ef6554601b294b125872607bb94f85bd7dcc5..e0ecebf5d00fe77d42d40e79c8533a40fdeea3d1 100644 --- a/production/urls.py +++ b/production/urls.py @@ -21,6 +21,8 @@ urlpatterns = [ production_views.send_proofs, name='send_proofs'), url(r'^streams/(?P<stream_id>[0-9]+)/proofs/(?P<version>[0-9]+)/toggle_access$', production_views.toggle_accessibility, name='toggle_accessibility'), + url(r'^streams/(?P<stream_id>[0-9]+)/proofs/(?P<attachment_id>[0-9]+)/reply/pdf$', + production_views.production_event_attachment_pdf, name='production_event_attachment_pdf'), url(r'^streams/(?P<stream_id>[0-9]+)/events/add$', production_views.add_event, name='add_event'), url(r'^streams/(?P<stream_id>[0-9]+)/logs/add$', diff --git a/production/views.py b/production/views.py index cc7e0d4063e42b191d0b4074367e3d58ee4b259e..f368999aa87719819176a8ef2b3a22073c402cc1 100644 --- a/production/views.py +++ b/production/views.py @@ -18,7 +18,8 @@ from finances.forms import WorkLogForm from mails.views import MailEditingSubView from . import constants -from .models import ProductionUser, ProductionStream, ProductionEvent, Proofs +from .models import ProductionUser, ProductionStream, ProductionEvent, Proofs,\ + ProductionEventAttachment from .forms import ProductionEventForm, AssignOfficerForm, UserToOfficerForm,\ AssignSupervisorForm, StreamStatusForm, ProofsUploadForm, ProofsDecisionForm,\ AssignInvitationsOfficerForm @@ -492,7 +493,7 @@ def proofs_pdf(request, slug): # because now it will return 404 instead of a redirect to the login page. raise Http404 - proofs = Proofs.objects.get(id=proofs_slug_to_id(slug)) + proofs = get_object_or_404(Proofs, id=proofs_slug_to_id(slug)) stream = proofs.stream # Check if user has access! @@ -511,6 +512,34 @@ def proofs_pdf(request, slug): return response +def production_event_attachment_pdf(request, stream_id, attachment_id): + """ Open ProductionEventAttachment pdf. """ + if not request.user.is_authenticated: + # Don't use the decorator but this strategy, + # because now it will return 404 instead of a redirect to the login page. + raise Http404 + + stream = get_object_or_404(ProductionStream, id=stream_id) + attachment = get_object_or_404( + ProductionEventAttachment.objects.filter(production_event__stream=stream), + id=attachment_id) + + # Check if user has access! + checker = ObjectPermissionChecker(request.user) + access = checker.has_perm('can_work_for_stream', stream) and request.user.has_perm('scipost.can_view_production') + if not access and request.user.contributor: + access = request.user.contributor in stream.submission.authors.all() + if not access: + raise Http404 + + # Passed the test! The user may see the file! + content_type, encoding = mimetypes.guess_type(attachment.attachment.path) + content_type = content_type or 'application/octet-stream' + response = HttpResponse(attachment.attachment.read(), content_type=content_type) + response["Content-Encoding"] = encoding + return response + + @login_required @transaction.atomic def author_decision(request, slug): @@ -526,7 +555,7 @@ def author_decision(request, slug): if request.user.contributor not in proofs.stream.submission.authors.all(): raise Http404 - form = ProofsDecisionForm(request.POST or None, instance=proofs) + form = ProofsDecisionForm(request.POST or None, request.FILES or None, instance=proofs) if form.is_valid(): proofs = form.save() notify_stream_status_change(request.user, stream, False) @@ -595,7 +624,7 @@ def decision(request, stream_id, version, decision): ) prodevent.save() messages.success(request, 'Proofs have been {decision}.'.format(decision=decision)) - return redirect(stream.get_absolute_url()) + return redirect(reverse('production:proofs', args=(stream.id, proofs.version))) @is_production_user() diff --git a/scipost/static/scipost/assets/js/scripts.js b/scipost/static/scipost/assets/js/scripts.js index d3478c7210700de698ea232ae6c0ef3f30c63a50..62d164fb742284d5822e5663d37e7cab1e401187 100644 --- a/scipost/static/scipost/assets/js/scripts.js +++ b/scipost/static/scipost/assets/js/scripts.js @@ -87,6 +87,8 @@ $(function(){ .removeClass('active') $(self).parents('[data-target="active-list"] > li') .addClass('active'); + + window.history.replaceState('scipost', document.title, url); }); }); }); diff --git a/scipost/templates/feeds/latest_publications_title.html b/scipost/templates/feeds/latest_publications_title.html index 803096e517c87ad96d23facd9051d04f2936010d..6558e2da81b6a1766d69447f71d5d776a4f81485 100644 --- a/scipost/templates/feeds/latest_publications_title.html +++ b/scipost/templates/feeds/latest_publications_title.html @@ -1 +1 @@ -{{obj.in_issue.in_volume.in_journal.get_abbreviation_citation}} <strong>{{obj.in_issue.in_volume.number}}</strong>, {{obj.get_paper_nr}} ({{obj.publication_date|date:'Y'}}), by {{ obj.author_list }} +{{obj.in_issue.in_volume.in_journal.get_abbreviation_citation}} {{obj.in_issue.in_volume.number}}, {{obj.get_paper_nr}} ({{obj.publication_date|date:'Y'}}), by {{ obj.author_list }} diff --git a/scipost/templates/scipost/feeds.html b/scipost/templates/scipost/feeds.html index e0f84121905f0a6def7ac31a8f11083b61b4cdc0..a547ec5038981110545a04bacab62ba6826d1cf4 100644 --- a/scipost/templates/scipost/feeds.html +++ b/scipost/templates/scipost/feeds.html @@ -13,23 +13,23 @@ <h2>News feeds</h2> <p> We provide both RSS (2.0) and Atom feeds for latest news and announcements. - The URL of the RSS feed is <a href="https://scipost.org/rss/news/">https://scipost.org/rss/news/</a>. - The URL of the Atom feed is <a href="https://scipost.org/atom/news/">https://scipost.org/atom/news/</a>. + The URL of the RSS feed is <a href="{% url 'scipost:feeds_rss_news' %}">https://scipost.org/rss/news/</a>. + The URL of the Atom feed is <a href="{% url 'scipost:feeds_atom_news' %}">https://scipost.org/atom/news/</a>. </p> <h2>Publications feeds</h2> <p> Similarly, we provide feeds for the latest publications. - The URL of the general RSS feed is <a href="https://scipost.org/rss/publications/">https://scipost.org/rss/publications</a>. - The URL of the general Atom feed is <a href="https://scipost.org/atom/publications/">https://scipost.org/atom/publications/</a>. + The URL of the general RSS feed is <a href="{% url 'scipost:feeds_rss_publications' %}">https://scipost.org/rss/publications</a>. + The URL of the general Atom feed is <a href="{% url 'scipost:feeds_atom_publications' %}">https://scipost.org/atom/publications/</a>. </p> <p>You can also obtain feeds only for any specific specialization by using the links in the table below.</p> <h2>Submissions feeds</h2> <p> We also provide feeds for the latest submissions. - The URL of the general RSS feed is <a href="https://scipost.org/rss/submissions/">https://scipost.org/rss/submissions</a>. - The URL of the general Atom feed is <a href="https://scipost.org/atom/submissions/">https://scipost.org/atom/submissions/</a>. + The URL of the general RSS feed is <a href="{% url 'scipost:feeds_rss_submissions' %}">https://scipost.org/rss/submissions</a>. + The URL of the general Atom feed is <a href="{% url 'scipost:feeds_atom_submissions' %}">https://scipost.org/atom/submissions/</a>. </p> <p>You can also obtain feeds only for any specific specialization by using the links in the table below.</p> diff --git a/scipost/templates/scipost/index.html b/scipost/templates/scipost/index.html index 36cd4a79dc0af6b6ad7844469e2327b0bf9d26b1..59862ebd0256875d6e3b27ead7f7c84647c147d6 100644 --- a/scipost/templates/scipost/index.html +++ b/scipost/templates/scipost/index.html @@ -35,7 +35,7 @@ {% for publication in publications %} <li class="list-group-item"> <div class="card-body px-0"> - {% include 'journals/_publication_details_small.html' with publication=publication %} + {% include 'partials/journals/publication_li_content.html' with publication=publication %} </div> </li> {% endfor %} diff --git a/scipost/urls.py b/scipost/urls.py index fe4aaefa27501031192cb6ce51fddc74cbe10a87..3389075ecd634d4edeeecb7fc0f6a3522f58c16d 100644 --- a/scipost/urls.py +++ b/scipost/urls.py @@ -37,27 +37,23 @@ urlpatterns = [ # Feeds url(r'^feeds$', views.feeds, name='feeds'), - url(r'^rss/news/$', LatestNewsFeedRSS()), - url(r'^atom/news/$', LatestNewsFeedAtom()), - url(r'^rss/comments/$', LatestCommentsFeedRSS()), - url(r'^atom/comments/$', LatestCommentsFeedAtom()), - url(r'^rss/submissions/$', - LatestSubmissionsFeedRSS()), + url(r'^rss/news/$', LatestNewsFeedRSS(), name='feeds_rss_news'), + url(r'^atom/news/$', LatestNewsFeedAtom(), name='feeds_atom_news'), + url(r'^rss/comments/$', LatestCommentsFeedRSS(), name='feeds_rss_comments'), + url(r'^atom/comments/$', LatestCommentsFeedAtom(), name='feeds_atom_comments'), + url(r'^rss/submissions/$', LatestSubmissionsFeedRSS(), name='feeds_rss_submissions'), url(r'^rss/submissions/(?P<subject_area>[a-zA-Z]+:[A-Z]{2,})$', LatestSubmissionsFeedRSS(), name='sub_feed_spec_rss'), - url(r'^atom/submissions/$', - LatestSubmissionsFeedAtom()), + url(r'^atom/submissions/$', LatestSubmissionsFeedAtom(), name='feeds_atom_submissions'), url(r'^atom/submissions/(?P<subject_area>[a-zA-Z]+:[A-Z]{2,})$', LatestSubmissionsFeedAtom(), name='sub_feed_spec_atom'), - url(r'^rss/publications/$', - LatestPublicationsFeedRSS()), + url(r'^rss/publications/$', LatestPublicationsFeedRSS(), name='feeds_rss_publications'), url(r'^rss/publications/(?P<subject_area>[a-zA-Z]+:[A-Z]{2,})$', LatestPublicationsFeedRSS(), name='pub_feed_spec_rss'), - url(r'^atom/publications/$', - LatestPublicationsFeedAtom()), + url(r'^atom/publications/$', LatestPublicationsFeedAtom(), name='feeds_atom_publications'), url(r'^atom/publications/(?P<subject_area>[a-zA-Z]+:[A-Z]{2,})$', LatestPublicationsFeedAtom(), name='pub_feed_spec_atom'), diff --git a/submissions/admin.py b/submissions/admin.py index 8a2f0f0e8b2c17c38316d4457694c62ba59aa519..0f52fe45e9c9a0c93e0579f4b2e6f1ce8ca05596 100644 --- a/submissions/admin.py +++ b/submissions/admin.py @@ -114,7 +114,8 @@ class SubmissionAdmin(GuardedModelAdmin): 'proceedings', 'pdf_refereeing_pack', 'plagiarism_report', - 'fellows'), + 'fellows', + 'voting_fellows'), }), ('Meta', { 'classes': ('collapse',), diff --git a/submissions/migrations/0081_submission_voting_fellows.py b/submissions/migrations/0081_submission_voting_fellows.py new file mode 100644 index 0000000000000000000000000000000000000000..32e51c4615181f9fe216109f1f48b74baf7e219e --- /dev/null +++ b/submissions/migrations/0081_submission_voting_fellows.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2017-11-05 13:21 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('colleges', '0002_auto_20171020_0931'), + ('submissions', '0080_auto_20171101_0944'), + ] + + operations = [ + migrations.AddField( + model_name='submission', + name='voting_fellows', + field=models.ManyToManyField(blank=True, related_name='voting_pool', to='colleges.Fellowship'), + ), + ] diff --git a/submissions/models.py b/submissions/models.py index fdacfc9f99876b495e2ec5835d4ffed5a0468c13..5a526bf214336075cb7e142fe344827efa6a0f59 100644 --- a/submissions/models.py +++ b/submissions/models.py @@ -67,6 +67,8 @@ class Submission(models.Model): blank=True, null=True, default=None) submitted_by = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE, related_name='submitted_submissions') + voting_fellows = models.ManyToManyField('colleges.Fellowship', blank=True, + related_name='voting_pool') # Replace this by foreignkey? submitted_to_journal = models.CharField(max_length=30, choices=SCIPOST_JOURNALS_SUBMIT, diff --git a/submissions/templates/partials/submissions/pool/submission_details.html b/submissions/templates/partials/submissions/pool/submission_details.html index 770936a3dfb2bd08e486a1633e606d8058c36120..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> @@ -41,6 +41,9 @@ {% if is_editorial_admin %} <h3>Editorial Administration</h3> <ul class="pl-4 mb-3"> + <li><a href="{% url 'colleges:submission' submission.arxiv_identifier_w_vn_nr %}">Manage Pool composition</a></li> + <li><a href="{% url 'colleges:submission_voting_fellows' submission.arxiv_identifier_w_vn_nr %}">Manage Voting Fellows</a></li> + {# EIC Assignments #} {% if perms.scipost.can_assign_submissions %} <li>EIC Assignment requests:</li> @@ -86,6 +89,7 @@ <li><a href="{% url 'submissions:treated_submission_pdf_compile' submission.arxiv_identifier_w_vn_nr %}">Update the Refereeing Package pdf</a></li> <li>After proofs have been accepted, you can <a href="{% url 'journals:initiate_publication' %}">initiate the publication process</a> (leads to the validation page)</li> {% endif %} + </ul> <h3>Events</h3> diff --git a/submissions/templates/partials/submissions/pool/submission_info_table.html b/submissions/templates/partials/submissions/pool/submission_info_table.html index 62ae68a23c23a9f5d0826dc998502880cbfa4c8d..49ec884f6b0d51add7cdc85e399e81cf4fc808b5 100644 --- a/submissions/templates/partials/submissions/pool/submission_info_table.html +++ b/submissions/templates/partials/submissions/pool/submission_info_table.html @@ -77,8 +77,13 @@ {% if perms.scipost.can_manage_college_composition %} <tr> <td>Pool composition</td> - <td><a href="{% url 'colleges:submission' submission.arxiv_identifier_w_vn_nr %}">{{ submission.fellows.count }} Fellowships</a></td> + <td><a href="{% url 'colleges:submission' submission.arxiv_identifier_w_vn_nr %}">{{ submission.fellows.count }} Fellowship{{ submission.fellows.count|pluralize }}</a></td> </tr> + <tr> + <td>Fellows voting</td> + <td><a href="{% url 'colleges:submission_voting_fellows' submission.arxiv_identifier_w_vn_nr %}">{{ submission.voting_fellows.count }} Fellowship{{ submission.voting_fellows.count|pluralize }}</a></td> + </tr> + {% endif %} </table> 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/templates/submissions/pool.html b/submissions/templates/submissions/pool.html deleted file mode 100644 index d52f9fa2c8d4cdd245166b497cbd6db3016ef165..0000000000000000000000000000000000000000 --- a/submissions/templates/submissions/pool.html +++ /dev/null @@ -1,361 +0,0 @@ -{% extends 'submissions/_pool_base.html' %} - -{% block pagetitle %}: Submissions Pool{% endblock pagetitle %} - -{% load bootstrap %} -{% load guardian_tags %} -{% load scipost_extras %} -{% load submissions_extras %} - -{% block breadcrumb_items %} - {{block.super}} - <span class="breadcrumb-item">Pool</span> -{% endblock %} - -{% block content %} - -{% with is_ECAdmin=request.user|is_in_group:'Editorial Administrators' %} - -<!-- Page content --> -<div class="row"> - <div class="col-lg-8"> - - {% if is_ECAdmin %} - {% if recommendations.put_to_voting.exists %} - <div class="row"> - <div class="col-12"> - <h3 class="highlight mt-0">Administrative actions on recommendations undergoing voting:</h3> - <ul> - <li>To send an email reminder to each Fellow with at least one voting duty, <a href="{% url 'submissions:remind_Fellows_to_vote' %}">click here</a></li> - </ul> - </div> - </div> - - <div class="row"> - <div class="col-12"> - <h1 class="highlight mt-0">Recommendations undergoing voting</h1> - </div> - </div> - - <div class="row"> - {% for rec in recommendations.put_to_voting %} - {% if not forloop.first %} - <hr> - {% endif %} - - <div class="col-12" id="undergoing_rec_{{rec.id}}"> - <div class="card"> - <div class="card-body"> - {% include 'partials/submissions/submission_title.html' with submission=rec.submission %} - {% include 'partials/submissions/pool/submission_info_table.html' with submission=rec.submission %} - </div> - </div> - - <div class="card card-outline-secondary"> - {% include 'submissions/_recommendation_fellow_content.html' with recommendation=rec %} - <div class="card-body"> - - <h3 class="card-title">Fellows eligible to vote:</h3> - <ul> - <li> - {% for eligible in rec.eligible_to_vote.all|sort_by:'user__last_name' %} - {{ eligible.user.last_name }}, - {% endfor %} - </li> - </ul> - - <h3 class="card-title">Voting results up to now:</h3> - <ul> - <li> - Agreed: ({{ rec.voted_for.all.count }}) - {% for agreed in rec.voted_for.all|sort_by:'user__last_name' %} - {{ agreed.user.last_name }}, - {% endfor %} - </li> - <li> - Disagreed: ({{ rec.voted_against.all.count }}) - {% for disagreed in rec.voted_against.all|sort_by:'user__last_name' %} - {{ disagreed.user.last_name }}, - {% endfor %} - </li> - <li> - Abstained: ({{ rec.voted_abstain.all.count }}) - {% for abstained in rec.voted_abstain.all|sort_by:'user__last_name' %} - {{ abstained.user.last_name }}, - {% endfor %} - </li> - </ul> - - <h3 class="card-title">Remarks:</h3> - <ul> - {% for rem in rec.remarks.all %} - <li>{% include 'partials/submissions/remark_small.html' with remark=rem %}</li> - {% empty %} - <li><em>No remarks</em></li> - {% endfor %} - </ul> - </div> - <div class="card-footer"> - <h3 class="card-title">Actions:</h3> - <ul> - <li>To fix the College decision and follow the Editorial Recommendation as is: <a href="{% url 'submissions:fix_College_decision' rec_id=rec.id %}">click here</a></li> - <li>To request a modification of the Recommendation to request for revision: click here</li> - </ul> - </div> - </div> - </div> - {% endfor %} - </div> - <hr> - {% endif %} - - {% if recommendations.voting_in_preparation.exists %} - <div class="row"> - <div class="col-12"> - <h1 class="highlight mt-0">Recommendations to prepare for voting</h1> - </div> - </div> - - {% for rec in recommendations.voting_in_preparation %} - {% if not forloop.first %} - <hr> - {% endif %} - - <div class="row"> - <div class="col-12" id="prepare_rec_{{rec.id}}"> - <div class="card"> - <div class="card-body"> - {% include 'partials/submissions/submission_title.html' with submission=rec.submission %} - {% include 'partials/submissions/pool/submission_info_table.html' with submission=rec.submission %} - </div> - </div> - - <div class="card card-outline-secondary"> - {% include 'submissions/_recommendation_fellow_content.html' with recommendation=rec %} - <div class="card-footer"> - <h3>Actions:</h3> - <ul> - <li><a href="{% url 'submissions:prepare_for_voting' rec_id=rec.id %}">Prepare for voting</a></li> - </ul> - </div> - </div> - </div> - </div> - {% endfor %} - <hr> - {% endif %} - {% endif %} - - {% if assignments_to_consider %} - <div class="row"> - <div class="col-12"> - <div class="highlight p-3"> - <h1 class="p-0">Assignment request</h1> - <h3 class="p-0 mt-1 d-block text-muted">Can you act as Editor-in-charge? (see below to accept/decline)</h3> - </div> - </div> - </div> - {% for assignment_to_consider in assignments_to_consider %} - <div class="row"> - <div class="col-12"> - <div class="card"> - {% include 'partials/submissions/pool/submission_assignment_request.html' with assignment=assignment_to_consider %} - </div> - </div> - </div> - {% endfor %} - <hr> - {% endif %} - - {% if recs_to_vote_on %} - <div class="row"> - <div class="col-12"> - <h1 class="highlight mt-0">Recommendations to vote on</h1> - </div> - </div> - {% for recommendation in recs_to_vote_on %} - {% if not forloop.first %} - <hr> - {% endif %} - - <div class="row"> - <div class="col-12"> - <div class="card"> - <div class="card-body"> - {% include 'partials/submissions/submission_title.html' with submission=recommendation.submission %} - {% include 'partials/submissions/pool/submission_info_table.html' with submission=recommendation.submission %} - </div> - </div> - - <div class="card card-outline-secondary"> - {% include 'submissions/_recommendation_fellow_content.html' with recommendation=recommendation %} - <div class="card-body"> - <h3 class="card-title">Voting results up to now:</h3> - <ul> - <li> - Agreed ({{ recommendation.voted_for.all.count }}): - {% for agreed in recommendation.voted_for.all|sort_by:'user__last_name' %} - {{ agreed.user.last_name }}{% if not forloop.last %},{% endif %} - {% endfor %} - </li> - <li> - Disagreed ({{ recommendation.voted_against.all.count }}): - {% for disagreed in recommendation.voted_against.all|sort_by:'user__last_name' %} - {{ disagreed.user.last_name }}{% if not forloop.last %},{% endif %} - {% endfor %} - </li> - <li> - Abstained ({{ recommendation.voted_abstain.all.count }}): - {% for abstained in recommendation.voted_abstain.all|sort_by:'user__last_name' %} - {{ abstained.user.last_name }}{% if not forloop.last %},{% endif %} - {% endfor %} - </li> - </ul> - - <h3 class="card-title">Remarks:</h3> - <ul> - {% for rem in recommendation.remarks.all %} - <li>{% include 'partials/submissions/remark_small.html' with remark=rem %}</li> - {% empty %} - <li><em>No remarks</em></li> - {% endfor %} - </ul> - </div> - <div class="card-footer"> - <h3>Your position on this recommendation</h3> - <form action="{% url 'submissions:vote_on_rec' rec_id=recommendation.id %}" method="post"> - {% csrf_token %} - {{ rec_vote_form|bootstrap:'0,12' }} - <input type="submit" name="submit" value="Cast your vote" class="btn btn-primary submitButton" id="submit-id-submit"> - </form> - </div> - </div> - </div> - </div> - {% endfor %} - <hr> - {% endif %} - - <div class="row"> - <div class="col-12"> - <h1 class="highlight mt-0">SciPost Submissions Pool</h1> - </div> - </div> - - <div class="row hidden-lg-up"> - <div class="col-12"> - <h3>Submissions by status:</h3> - <ul> - {% for key, val in submission_status %} - <li> - <a href="{% url 'submissions:submissions_by_status' status=key %}">{{ val }}</a> - </li> - {% endfor %} - </ul> - </div> - </div> - - <hr class="hidden-lg-up"> - - <div class="row"> - <div class="col-12"> - <!-- Submissions list --> - {% for sub in submissions %} - <div class="card card-outline-secondary mt-1" id="pool_submission_{{sub.id}}"> - {% include 'submissions/_submission_card_in_pool.html' with submission=sub remark_form=remark_form is_ECAdmin=is_ECAdmin user=request.user %} - </div> - {% endfor %} - </div> - </div> - </div><!-- End page content --> - - <!-- Sidebar --> - <div class="col-lg-4 hidden-md-down"> - <div class="card card-outline-secondary"> - <div class="card-body"> - <h2 class="card-title">Pool</h2> - <!-- Status --> - <a href="#pool_filter_status" data-toggle="collapse" class="collapsed"> - <h3 class="card-title text-gray-dark">Submissions by status</h3> - </a> - <div id="pool_filter_status" class="collapse"> - <ul class="pl-4"> - {% for key, val in submission_status %} - <li> - <a href="{% url 'submissions:submissions_by_status' status=key %}">{{ val }}</a> - </li> - {% endfor %} - </ul> - </div><!-- end status --> - - {% if is_ECAdmin %} - {% if recommendations.put_to_voting.exists %} - <!-- Preparing --> - <a href="#rec_filter_voting" data-toggle="collapse" class="collapsed"> - <h3 class="card-title text-gray-dark">Recommendations undergoing voting ({{recommendations_undergoing_voting|length}})</h3> - </a> - <div id="rec_filter_voting" class="collapse"> - <ul class="list-group list-group-flush"> - {% for recommendation in recommendations.put_to_voting %} - <li class="list-group-item"> - <div class="card-body"> - <a href="#undergoing_rec_{{recommendation.id}}">{{recommendation.submission.title}}</a> - <p class="text-muted my-0">{{recommendation.submission.author_list}}</p> - <p class="my-0">Formulated on {{recommendation.date_submitted}}</p> - </div> - </li> - {% endfor %} - </ul> - </div><!-- end preparing --> - {% endif %} - - {% if recommendations.voting_in_preparation.exists %} - <!-- Preparing --> - <a href="#rec_filter_prepare" data-toggle="collapse" class="collapsed"> - <h3 class="card-title text-gray-dark">Recommendations to prepare ({{recommendations_to_prepare_for_voting|length}})</h3> - </a> - <div id="rec_filter_prepare" class="collapse"> - <ul class="list-group list-group-flush"> - {% for recommendation in recommendations.voting_in_preparation %} - <li class="list-group-item"> - <div class="card-body"> - <a href="#prepare_rec_{{recommendation.id}}">{{recommendation.submission.title}}</a> - <p class="text-muted my-0">{{recommendation.submission.author_list}}</p> - <p class="my-0">Formulated on {{recommendation.date_submitted}}</p> - </div> - </li> - {% endfor %} - </ul> - </div><!-- end preparing --> - {% endif %} - {% endif %} - - <!-- Pool --> - <a href="#pool_filter_submissions" data-toggle="collapse"> - <h3 class="card-title text-gray-dark">Submissions in pool ({{submissions|length}})</h3> - </a> - <div id="pool_filter_submissions" class="collapse show"> - <ul class="list-group list-group-flush"> - {% for submission in submissions %} - <li class="list-group-item"> - <div class="card-body" style="overflow: auto;"> - <a href="#pool_submission_{{submission.id}}">{{submission.title}}</a> - <p class="text-muted mb-1">{{submission.author_list}}</p> - <p class="label label-secondary label-sm my-2">{{submission.get_status_display}}</p> - </div> - </li> - {% empty %} - <li class="list-group-item"> - <h4 class="card-title"><em>No submission in the pool</em></h4> - </li> - {% endfor %} - </ul> - </div><!-- end pool --> - </div> - </div> - </div> -</div> - -{% endwith %} - -{% endblock %} diff --git a/submissions/templates/submissions/submission_detail.html b/submissions/templates/submissions/submission_detail.html index 0010c1e89e760112bcce533f491945214cd63edc..1e66d5504f90db0c682f1200c7ca359b3e341c83 100644 --- a/submissions/templates/submissions/submission_detail.html +++ b/submissions/templates/submissions/submission_detail.html @@ -105,13 +105,15 @@ <li> <a href="{{ proofs.get_absolute_url }}" target="_blank">Download version {{ proofs.version }}</a> · uploaded: {{ proofs.created|date:"DATE_FORMAT" }} · status: <span class="label label-secondary label-sm">{{ proofs.get_status_display }}</span> - {% if proofs.status == 'accepted_sup' and proofs_decision_form and is_author %} - <h3 class="mb-0 mt-2">Please advise the Production Team on your findings on Proofs version {{ proof.version }}</h3> - <form method="post" action="{% url 'production:author_decision' proofs.slug %}" class="my-2"> - {% csrf_token %} - {{ proofs_decision_form|bootstrap }} - <input class="btn btn-primary btn-sm" type="submit" value="Submit"> - </form> + {% if proofs.status == 'accepted_sup' or proofs.status == 'sent' %} + {% if proofs_decision_form and is_author %} + <h3 class="mb-0 mt-2">Please advise the Production Team on your findings on Proofs version {{ proofs.version }}</h3> + <form method="post" enctype="multipart/form-data" action="{% url 'production:author_decision' proofs.slug %}" class="my-2"> + {% csrf_token %} + {{ proofs_decision_form|bootstrap }} + <input class="btn btn-primary btn-sm" type="submit" value="Submit"> + </form> + {% endif %} {% endif %} </li> {% endfor %} 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/urls.py b/submissions/urls.py index 1a10cce67d167e0ad3fa722d52c4c57d0188d9ad..3981f846e168f36a98797b95874c8b942ac59615 100644 --- a/submissions/urls.py +++ b/submissions/urls.py @@ -45,8 +45,6 @@ urlpatterns = [ name='prefill_using_identifier'), url(r'^pool/$', views.pool, name='pool'), url(r'^pool/{regex}/$'.format(regex=SUBMISSIONS_COMPLETE_REGEX), views.pool, name='pool'), - url(r'^submissions_by_status/(?P<status>[a-zA-Z_]+)$', - views.submissions_by_status, name='submissions_by_status'), # DEPRECATED url(r'^add_remark/{regex}$'.format(regex=SUBMISSIONS_COMPLETE_REGEX), views.add_remark, name='add_remark'), diff --git a/submissions/views.py b/submissions/views.py index 24564a1a2ace125c92c93abc6596a82ddb05e2e0..64a46d737063629aaf608ae054fd03d28e08a5d3 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -33,12 +33,12 @@ 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 from scipost.models import Contributor, Remark, RegistrationInvitation from scipost.utils import Utils -from scipost.permissions import is_tester from comments.forms import CommentForm from production.forms import ProofsDecisionForm @@ -331,7 +331,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 @@ -339,10 +339,6 @@ def pool(request, arxiv_identifier_w_vn_nr=None): to publication acceptance or rejection. All members of the Editorial College have access. """ - # Objects - - # The following is in test phase. Update if test is done - # -- # Search search_form = SubmissionPoolFilterForm(request.GET or None) if search_form.is_valid(): @@ -354,7 +350,8 @@ def pool(request, arxiv_identifier_w_vn_nr=None): # submissions = Submission.objects.pool(request.user) recommendations = EICRecommendation.objects.filter(submission__in=submissions) recs_to_vote_on = recommendations.user_may_vote_on(request.user) - assignments_to_consider = EditorialAssignment.objects.open().filter(to=request.user.contributor) + assignments_to_consider = EditorialAssignment.objects.open().filter( + to=request.user.contributor) # Forms consider_assignment_form = ConsiderAssignmentForm() @@ -373,9 +370,6 @@ def pool(request, arxiv_identifier_w_vn_nr=None): 'remark_form': remark_form, } - # The following is in test phase. Update if test is done - # -- - # Show specific submission in the pool context['submission'] = None if arxiv_identifier_w_vn_nr: @@ -392,36 +386,12 @@ 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'): - template = 'submissions/pool/pool.html' else: - template = 'submissions/pool.html' + template = 'submissions/pool/pool.html' return render(request, template, context) @login_required -@permission_required('scipost.can_view_pool', raise_exception=True) -def submissions_by_status(request, status): - # --- - # DEPRECATED AS PER NEW POOL - # --- - status_dict = dict(SUBMISSION_STATUS) - if status not in status_dict.keys(): - errormessage = 'Unknown status.' - return render(request, 'scipost/error.html', {'errormessage': errormessage}) - submissions_of_status = (Submission.objects.pool_full(request.user) - .filter(status=status).order_by('-submission_date')) - - context = { - 'submissions_of_status': submissions_of_status, - 'status': status_dict[status], - 'remark_form': RemarkForm() - } - return render(request, 'submissions/submissions_by_status.html', context) - - -@login_required -# @permission_required('scipost.can_view_pool', raise_exception=True) def add_remark(request, arxiv_identifier_w_vn_nr): """ With this method, an Editorial Fellow or Board Member @@ -679,13 +649,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 +694,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