diff --git a/scipost_django/scipost/views.py b/scipost_django/scipost/views.py index f7d59b9e750da947ae2b8abff420f9236480aa58..f418bedc0d6e82d5ea61314b3e01e478d26d337c 100644 --- a/scipost_django/scipost/views.py +++ b/scipost_django/scipost/views.py @@ -1258,11 +1258,7 @@ def personal_page_hx_submissions(request): context = {"contributor": contributor} context["nr_submission_authorships_to_claim"] = ( - Submission.objects.filter(author_list__contains=request.user.last_name) - .exclude(authors=contributor) - .exclude(authors_claims=contributor) - .exclude(authors_false_claims=contributor) - .count() + Submission.objects.with_potential_unclaimed_author(contributor).count() ) context["own_submissions"] = contributor.submissions.latest().order_by( "-submission_date" @@ -1473,21 +1469,27 @@ def claim_authorships(request): contributor = Contributor.objects.get(user=request.user) submission_authorships_to_claim = ( - Submission.objects.filter(author_list__contains=contributor.user.last_name) + Submission.objects.filter( + author_list__unaccent__icontains=contributor.user.last_name + ) .exclude(authors=contributor) .exclude(authors_claims=contributor) .exclude(authors_false_claims=contributor) ) sub_auth_claim_form = AuthorshipClaimForm() commentary_authorships_to_claim = ( - Commentary.objects.filter(author_list__contains=contributor.user.last_name) + Commentary.objects.filter( + author_list__unaccent__icontains=contributor.user.last_name + ) .exclude(authors=contributor) .exclude(authors_claims=contributor) .exclude(authors_false_claims=contributor) ) com_auth_claim_form = AuthorshipClaimForm() thesis_authorships_to_claim = ( - ThesisLink.objects.filter(author__contains=contributor.user.last_name) + ThesisLink.objects.filter( + author__unaccent__icontains=contributor.user.last_name + ) .exclude(author_as_cont=contributor) .exclude(author_claims=contributor) .exclude(author_false_claims=contributor) diff --git a/scipost_django/submissions/managers/submission.py b/scipost_django/submissions/managers/submission.py index 8d0361e816a4fdec8a928dd81596471e88a9636e..5c26f03fe12533b908baa5e80256c67e9d5a2d88 100644 --- a/scipost_django/submissions/managers/submission.py +++ b/scipost_django/submissions/managers/submission.py @@ -9,6 +9,11 @@ from django.utils import timezone from .. import constants +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ...scipost.models import Contributor + class SubmissionQuerySet(models.QuerySet): ################################## @@ -146,22 +151,30 @@ class SubmissionQuerySet(models.QuerySet): def latest(self): return self.exclude(status=self.model.RESUBMITTED) - def remove_COI(self, user): + def with_potential_unclaimed_author(self, contributor: "Contributor"): + """ + Return Submissions for which the contributor could potentially be an author. + """ + return ( + self.filter(author_list__unaccent__icontains=contributor.user.last_name) + .exclude(authors=contributor) + .exclude(authors_claims=contributor) + .exclude(authors_false_claims=contributor) + ) + + def remove_COI(self, contributor: "Contributor"): """ Filter on basic conflicts of interest. Prevent conflicts of interest by filtering out submissions which are possibly related to user. """ - try: - return self.exclude(authors=user.contributor).exclude( - models.Q( - author_list__unaccent__icontains=user.last_name - ), # TODO: replace by Profiles-based checks - ~models.Q(authors_false_claims=user.contributor), - ) - except AttributeError: - return self.none() + return self.exclude(authors=contributor).exclude( + models.Q( + author_list__unaccent__icontains=contributor.user.last_name + ), # TODO: replace by Profiles-based checks + ~models.Q(authors_false_claims=contributor), + ) def in_pool(self, user, latest: bool = True, historical: bool = False): """ @@ -213,7 +226,7 @@ class SubmissionQuerySet(models.QuerySet): ).exclude( competing_interests__related_profile=user.contributor.profile, ) - return qs.remove_COI(user) + return qs.remove_COI(user.contributor) def in_pool_filter_for_eic( self, diff --git a/scipost_django/submissions/templates/submissions/pool/pool.html b/scipost_django/submissions/templates/submissions/pool/pool.html index 3112374855abeb0773dd69627062f00ba4bb5370..24a9eb040f17efe5a3323c205cd24cc90009bf17 100644 --- a/scipost_django/submissions/templates/submissions/pool/pool.html +++ b/scipost_django/submissions/templates/submissions/pool/pool.html @@ -154,7 +154,16 @@ </div> </div> - <h4 class="bg-primary bg-opacity-10 p-2"><span class="text-primary">{% include "bi/info-circle-fill.html" %}</span> <em>Tip: click anywhere on a Submission header's light blue background to expand detailed tabs</em></h4> + <p class="bg-primary bg-opacity-10 p-2"><span class="text-primary fs-5 me-2">{% include "bi/info-circle-fill.html" %}</span>Tip: click anywhere on a Submission header's light blue background to expand detailed tabs</p> + + {% if nr_potential_author_conflicts %} + <p class="bg-warning bg-opacity-10 p-2"> + <span class="text-warning fs-5 me-2">{% include "bi/exclamation-triangle-fill.html" %}</span> + A total of {{nr_potential_author_conflicts}} submissions are hidden based on grounds of potential authorship, i.e. your last name is contained in the author-provided list of authors. + Verify or refute these claims in the <a href="{% url "scipost:claim_authorships" %}">claim authorships page</a>. + </p> + {% endif %} + <div id="search-results" class="mt-2"></div> {% endblock content %} diff --git a/scipost_django/submissions/views/pool/base.py b/scipost_django/submissions/views/pool/base.py index 7c8dcd79fabd958186e06a196d342cd882361167..ec755955b16752ded784f530a4b32b612de0d63e 100644 --- a/scipost_django/submissions/views/pool/base.py +++ b/scipost_django/submissions/views/pool/base.py @@ -40,6 +40,9 @@ def pool(request, identifier_w_vn_nr=None): nr_potfels_to_vote_on = PotentialFellowship.objects.to_vote_on( request.user.contributor ).count() + nr_potential_author_conflicts = Submission.objects.with_potential_unclaimed_author( + request.user.contributor + ).count() recs_to_vote_on = EICRecommendation.objects.user_must_vote_on(request.user) recs_current_voted = EICRecommendation.objects.user_current_voted(request.user) assignments_to_consider = EditorialAssignment.objects.invited().filter( @@ -49,6 +52,7 @@ def pool(request, identifier_w_vn_nr=None): if identifier_w_vn_nr: initial = {"identifier": identifier_w_vn_nr} context = { + "nr_potential_author_conflicts": nr_potential_author_conflicts, "nr_potfels_to_vote_on": nr_potfels_to_vote_on, "recs_to_vote_on": recs_to_vote_on, "recs_current_voted": recs_current_voted,