From c784a1b011e95c0f20af3b7101e3261ca18e764c Mon Sep 17 00:00:00 2001 From: ErnestaP Date: Thu, 22 Feb 2024 08:54:25 +0100 Subject: [PATCH] Added compliance flag * ref: https://github.com/cern-sis/issues-scoap3/issues/299 --- scoap3/articles/admin.py | 21 ++++++++ ...port_check_authors_affiliation_and_more.py | 22 ++++++++ scoap3/articles/models.py | 3 ++ scoap3/articles/tasks.py | 17 +++++++ .../articles/tests/test_article_compliance.py | 50 ++++++++++++++++++- 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 scoap3/articles/migrations/0014_compliancereport_check_authors_affiliation_and_more.py diff --git a/scoap3/articles/admin.py b/scoap3/articles/admin.py index 109917dee..6259186ac 100644 --- a/scoap3/articles/admin.py +++ b/scoap3/articles/admin.py @@ -27,6 +27,7 @@ class ComplianceReportAdmin(admin.ModelAdmin): "check_arxiv_category", "check_article_type", "check_doi_registration_time", + "check_authors_affiliation", "get_is_compliant", "report_date", ] @@ -50,6 +51,8 @@ class ComplianceReportAdmin(admin.ModelAdmin): "check_article_type_description", "check_doi_registration_time", "check_doi_registration_time_description", + "check_authors_affiliation", + "check_authors_affiliation_description", ] readonly_fields = [ "article", @@ -65,6 +68,8 @@ class ComplianceReportAdmin(admin.ModelAdmin): "check_article_type_description", "check_doi_registration_time", "check_doi_registration_time_description", + "check_authors_affiliation", + "check_authors_affiliation_description", ] list_filter = [ @@ -77,6 +82,7 @@ class ComplianceReportAdmin(admin.ModelAdmin): "article_id__report__check_arxiv_category", "article_id__report__check_article_type", "article_id__report__check_doi_registration_time", + "article_id__report__check_authors_affiliation", ] actions = ["export_as_csv"] @@ -154,6 +160,8 @@ class ArticleComplianceReportInline(admin.StackedInline): "check_article_type_description", "check_doi_registration_time", "check_doi_registration_time_description", + "check_authors_affiliation", + "check_authors_affiliation_description", ] can_delete = False can_create = False @@ -172,6 +180,10 @@ class ArticleComplianceReportInline(admin.StackedInline): "check_doi_registration_time", "check_doi_registration_time_description", ), + ( + "check_authors_affiliation", + "check_authors_affiliation_description", + ), ] }, ), @@ -228,6 +240,7 @@ class ArticleAdmin(admin.ModelAdmin): "check_arxiv_category", "check_article_type", "check_doi_registration_time", + "check_authors_affiliation", "_updated_at", "_created_at", ] @@ -247,6 +260,7 @@ class ArticleAdmin(admin.ModelAdmin): "report__check_arxiv_category", "report__check_article_type", "report__check_doi_registration_time", + "report__check_authors_affiliation", ] inlines = [ArticleAuthorsInline, ArticleComplianceReportInline] @@ -324,6 +338,13 @@ def check_doi_registration_time(self, obj): return report.check_doi_registration_time return False + @admin.display(description="Author affiliations", boolean=True) + def check_authors_affiliation(self, obj): + report = obj.report.first() + if report: + return report.check_authors_affiliation + return False + class ArticleIdentifierAdmin(admin.ModelAdmin): list_display = ["article_id", "identifier_type", "identifier_value"] diff --git a/scoap3/articles/migrations/0014_compliancereport_check_authors_affiliation_and_more.py b/scoap3/articles/migrations/0014_compliancereport_check_authors_affiliation_and_more.py new file mode 100644 index 000000000..9cc9745ba --- /dev/null +++ b/scoap3/articles/migrations/0014_compliancereport_check_authors_affiliation_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.5 on 2024-02-21 14:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("articles", "0013_compliancereport_check_article_type_description_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="compliancereport", + name="check_authors_affiliation", + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name="compliancereport", + name="check_authors_affiliation_description", + field=models.TextField(blank=True, default=""), + ), + ] diff --git a/scoap3/articles/models.py b/scoap3/articles/models.py index b88039262..b27f73766 100644 --- a/scoap3/articles/models.py +++ b/scoap3/articles/models.py @@ -101,6 +101,8 @@ class ComplianceReport(models.Model): check_article_type_description = models.TextField(blank=True, default="") check_doi_registration_time = models.BooleanField(default=False) check_doi_registration_time_description = models.TextField(blank=True, default="") + check_authors_affiliation = models.BooleanField(default=False) + check_authors_affiliation_description = models.TextField(blank=True, default="") def __str__(self): return f"Compliance Report for {self.article.title} on {self.report_date.strftime('%Y-%m-%d')}" @@ -113,5 +115,6 @@ def is_compliant(self): self.check_arxiv_category, self.check_article_type, self.check_doi_registration_time, + self.check_authors_affiliation, ] ) diff --git a/scoap3/articles/tasks.py b/scoap3/articles/tasks.py index 578d95da5..18087617d 100644 --- a/scoap3/articles/tasks.py +++ b/scoap3/articles/tasks.py @@ -6,6 +6,8 @@ from django_opensearch_dsl.registries import registry from scoap3.articles.models import Article, ComplianceReport +from scoap3.authors.models import Author +from scoap3.misc.models import Affiliation from scoap3.misc.utils import fetch_doi_registration_date logger = logging.getLogger(__name__) @@ -122,6 +124,15 @@ def check_doi_registration_time(obj): return False, "DOI not found in our system." +def check_authors_affiliation(article): + authors = Author.objects.filter(article_id=article) + for author in authors: + affiliations = Affiliation.objects.filter(author_id=author) + if len(affiliations) < 1: + return False, "Author does not have affiliations" + return True, "Authors' affiliations are compliant" + + @shared_task(name="compliance_checks", acks_late=True) def compliance_checks(article_id): try: @@ -145,6 +156,10 @@ def compliance_checks(article_id): article ) check_license_compliance, check_license_description = check_license(article) + ( + check_affiliations_compliance, + check_affiliations_description, + ) = check_authors_affiliation(article) article.report.all().delete() @@ -160,6 +175,8 @@ def compliance_checks(article_id): check_file_formats_description=check_file_formats_description, check_license=check_license_compliance, check_license_description=check_license_description, + check_authors_affiliation=check_affiliations_compliance, + check_authors_affiliation_description=check_affiliations_description, ) report.save() logger.info("Compliance checks completed for article %s", article_id) diff --git a/scoap3/articles/tests/test_article_compliance.py b/scoap3/articles/tests/test_article_compliance.py index 3836bd010..60a9695db 100644 --- a/scoap3/articles/tests/test_article_compliance.py +++ b/scoap3/articles/tests/test_article_compliance.py @@ -9,7 +9,15 @@ ComplianceReport, ) from scoap3.articles.tasks import compliance_checks -from scoap3.misc.models import ArticleArxivCategory, License, PublicationInfo, Publisher +from scoap3.authors.models import Author +from scoap3.misc.models import ( + Affiliation, + ArticleArxivCategory, + Country, + License, + PublicationInfo, + Publisher, +) @pytest.mark.django_db @@ -147,6 +155,46 @@ def test_create_article_with_not_compliant_arxiv_category(self): report = article.report.first() self.assertEqual(report.check_arxiv_category, False) + def test_create_author_with_no_affiliation(self): + Author.objects.create( + article_id=self.article, + last_name="ExampleSurname", + first_name="ExampleName", + email="ExampleName.ExampleSurname@gmail.com", + author_order=100, + ) + compliance_checks(self.article.id) + article = Article.objects.get(id=self.article.id) + report = article.report.first() + self.assertEqual(report.check_authors_affiliation, False) + + def test_create_author_with_affiliation(self): + Author.objects.create( + article_id=self.article, + last_name="ExampleSurname", + first_name="ExampleName", + email="ExampleName.ExampleSurname@gmail.com", + author_order=100, + ) + Country.objects.create( + code="BE", + name="Belgium", + ) + author_id = ( + Author.objects.get(last_name="ExampleSurname", first_name="ExampleName"), + ) + affiliation = Affiliation.objects.create( + country=Country.objects.get(code="BE", name="Belgium"), + value="Example", + organization="Example Organization", + ) + affiliation.author_id.set(author_id) + + compliance_checks(self.article.id) + article = Article.objects.get(id=self.article.id) + report = article.report.first() + self.assertEqual(report.check_authors_affiliation, True) + def test_create_article_with_not_compliant_category_having_not_partial_journal( self, ):