From 9df148b1feabbe95dad8ebfd2e4e1c2d6cffcf81 Mon Sep 17 00:00:00 2001 From: ErnestaP Date: Fri, 19 Jul 2024 14:34:19 +0200 Subject: [PATCH] Publication info: take date from created_at if is not sent by workflows * Fix publication_info creation. * ref: https://github.com/cern-sis/issues-scoap3/issues/338 --- scoap3/articles/api/serializers.py | 7 ++ scoap3/articles/tests/test_article_views.py | 90 +++++++++++++++++++ scoap3/articles/util.py | 6 ++ .../0018_alter_publicationinfo_volume_year.py | 17 ++++ scoap3/misc/models.py | 2 +- scoap3/tasks.py | 20 ++++- 6 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 scoap3/misc/migrations/0018_alter_publicationinfo_volume_year.py diff --git a/scoap3/articles/api/serializers.py b/scoap3/articles/api/serializers.py index d86e64f15..e5ddaa1b7 100644 --- a/scoap3/articles/api/serializers.py +++ b/scoap3/articles/api/serializers.py @@ -10,6 +10,7 @@ ArticleIdentifier, ArticleIdentifierType, ) +from scoap3.articles.util import parse_string_to_date_object from scoap3.misc.api.serializers import ( ArticleArxivCategorySerializer, CopyrightSerializer, @@ -44,6 +45,12 @@ def to_representation(self, instance): representation = super().to_representation(instance) if instance.publication_date is None: representation["publication_date"] = instance._created_at + if instance.publication_info.exists(): + for pub_info in representation["publication_info"]: + if pub_info.get("volume_year") is None: + pub_info["volume_year"] = parse_string_to_date_object( + instance._created_at + ).year return representation diff --git a/scoap3/articles/tests/test_article_views.py b/scoap3/articles/tests/test_article_views.py index 7e12258e9..6ee47238a 100644 --- a/scoap3/articles/tests/test_article_views.py +++ b/scoap3/articles/tests/test_article_views.py @@ -5,6 +5,8 @@ from rest_framework import status from scoap3.articles.models import Article +from scoap3.articles.util import parse_string_to_date_object +from scoap3.misc.models import PublicationInfo pytestmark = pytest.mark.django_db @@ -238,6 +240,94 @@ def test_create_update_from_workflow_with_publication_date( == "2024-06-20" ) + def test_create_update_from_workflow_with_journal_year( + self, + client, + user, + record, + ): + client.force_login(user) + response = client.post( + reverse("api:article-workflow-import-list"), + record, + content_type="application/json", + ) + assert response.status_code == status.HTTP_200_OK + + article_id_with_journal_year = response.data["id"] + publication_info_with_journal_year = PublicationInfo.objects.get( + article_id=article_id_with_journal_year + ) + assert publication_info_with_journal_year.volume_year == "2023" + + record["publication_info"][0]["year"] = "2024" + response = client.post( + reverse("api:article-workflow-import-list"), + record, + content_type="application/json", + ) + article_id_with_updated_journal_year = response.data["id"] + assert article_id_with_journal_year == article_id_with_updated_journal_year + journal_info_with_updated_journal_year = PublicationInfo.objects.get( + article_id=article_id_with_updated_journal_year + ) + assert journal_info_with_updated_journal_year.volume_year == "2024" + + del record["publication_info"][0]["year"] + response = client.post( + reverse("api:article-workflow-import-list"), + record, + content_type="application/json", + ) + assert response.status_code == status.HTTP_200_OK + journal_info_with_deleted_journal_year = PublicationInfo.objects.get( + article_id=article_id_with_journal_year + ) + assert journal_info_with_deleted_journal_year.volume_year == "2024" + + def test_create_update_from_workflow_without_journal_year( + self, + client, + user, + record, + ): + client.force_login(user) + del record["publication_info"][0]["year"] + response = client.post( + reverse("api:article-workflow-import-list"), + record, + content_type="application/json", + ) + assert response.status_code == status.HTTP_200_OK + + article_id_with_publication_date = response.data["id"] + article_with_publication_date = PublicationInfo.objects.get( + article_id=article_id_with_publication_date + ) + assert article_with_publication_date.volume_year is None + + assert ( + response.data["publication_info"][0]["volume_year"] + == parse_string_to_date_object(response.data["_created_at"]).year + ) + + record["publication_info"][0]["year"] = "2024" + response = client.post( + reverse("api:article-workflow-import-list"), + record, + content_type="application/json", + ) + assert response.status_code == status.HTTP_200_OK + + article_id_with_updated_publication_date = response.data["id"] + assert ( + article_id_with_publication_date == article_id_with_updated_publication_date + ) + article_with_updated_publication_date = PublicationInfo.objects.get( + article_id=article_id_with_updated_publication_date + ) + assert article_with_updated_publication_date.volume_year == "2024" + class TestArticleIdentifierViewSet: def test_get_article_identifier(self, client): diff --git a/scoap3/articles/util.py b/scoap3/articles/util.py index 0ffd8f9c0..92c21c45d 100644 --- a/scoap3/articles/util.py +++ b/scoap3/articles/util.py @@ -1,3 +1,5 @@ +from datetime import datetime + from scoap3.articles.models import ArticleIdentifierType @@ -19,3 +21,7 @@ def get_arxiv_primary_category(article_document): for arxiv_category in article_document.article_arxiv_category: if arxiv_category.primary: return arxiv_category.category + + +def parse_string_to_date_object(date_string): + return datetime.fromisoformat(date_string.replace("Z", "+00:00")) diff --git a/scoap3/misc/migrations/0018_alter_publicationinfo_volume_year.py b/scoap3/misc/migrations/0018_alter_publicationinfo_volume_year.py new file mode 100644 index 000000000..f7fa74c83 --- /dev/null +++ b/scoap3/misc/migrations/0018_alter_publicationinfo_volume_year.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.5 on 2024-07-19 11:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("misc", "0017_alter_copyright_article_id"), + ] + + operations = [ + migrations.AlterField( + model_name="publicationinfo", + name="volume_year", + field=models.CharField(blank=True, max_length=255, null=True), + ), + ] diff --git a/scoap3/misc/models.py b/scoap3/misc/models.py index 9c33b242c..0fb209379 100644 --- a/scoap3/misc/models.py +++ b/scoap3/misc/models.py @@ -73,7 +73,7 @@ class PublicationInfo(models.Model): page_start = models.CharField(blank=True) page_end = models.CharField(blank=True) artid = models.CharField(max_length=255, blank=True, default="") - volume_year = models.CharField(max_length=255) + volume_year = models.CharField(max_length=255, blank=True, null=True) journal_issue_date = models.DateField(blank=True, null=True) publisher = models.ForeignKey("misc.Publisher", on_delete=models.CASCADE) diff --git a/scoap3/tasks.py b/scoap3/tasks.py index aa17f0057..f832ef6b1 100644 --- a/scoap3/tasks.py +++ b/scoap3/tasks.py @@ -208,19 +208,31 @@ def _create_publisher(data): def _create_publication_info(data, article, publishers): for idx, publication_info in enumerate(data.get("publication_info", [])): publication_info_data = { - "article_id": article, "journal_volume": publication_info.get("journal_volume", ""), "journal_title": publication_info.get("journal_title", ""), "journal_issue": publication_info.get("journal_issue", ""), "page_start": publication_info.get("page_start", ""), "page_end": publication_info.get("page_end", ""), "artid": publication_info.get("artid", ""), - "volume_year": publication_info.get("year"), "journal_issue_date": publication_info.get("journal_issue_date"), "publisher_id": publishers[idx].id, } - - PublicationInfo.objects.get_or_create(**publication_info_data) + volume_year = publication_info.get("year", "") + if PublicationInfo.objects.filter(article_id=article.id).exists(): + if volume_year: + publication_info_data["volume_year"] = volume_year + publication_info_obj = PublicationInfo.objects.filter( + article_id=article.id + ).first() + publication_info_obj.__dict__.update(**publication_info_data) + else: + if volume_year: + publication_info_data["volume_year"] = volume_year + publication_info_data["article_id"] = article + publication_info_obj = PublicationInfo.objects.create( + **publication_info_data + ) + publication_info_obj.save() def _create_experimental_collaborations(data):