From 6ea638e3bac7c066fb124c215a082d81a431c1cd Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Mon, 16 Dec 2024 09:45:50 +0100 Subject: [PATCH 1/9] add is_obsolete to admin list --- data/admin/ingredient.py | 2 +- data/admin/microorganism.py | 2 +- data/admin/plant.py | 2 +- data/admin/substance.py | 11 ++++++++++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/data/admin/ingredient.py b/data/admin/ingredient.py index 0601bb1c..178d86fe 100644 --- a/data/admin/ingredient.py +++ b/data/admin/ingredient.py @@ -38,7 +38,7 @@ class IngredientAdmin(ElementAdminWithChangeReason): SubstanceInlineAdmin, IngredientSynonymInline, ) - list_display = ("name", "status", "is_risky", "novel_food") + list_display = ("name", "is_obsolete", "status", "is_risky", "novel_food") list_filter = ("is_obsolete", "status", "is_risky", "novel_food") show_facets = admin.ShowFacets.NEVER readonly_fields = ( diff --git a/data/admin/microorganism.py b/data/admin/microorganism.py index af37b145..20059202 100644 --- a/data/admin/microorganism.py +++ b/data/admin/microorganism.py @@ -57,7 +57,7 @@ class MicroorganismAdmin(ElementAdminWithChangeReason): ), ] - list_display = ("name", "status", "is_risky", "novel_food") + list_display = ("name", "is_obsolete", "status", "is_risky", "novel_food") list_filter = ("is_obsolete", "status", "is_risky", "novel_food") show_facets = admin.ShowFacets.NEVER readonly_fields = ( diff --git a/data/admin/plant.py b/data/admin/plant.py index 849506bc..dc7d44b0 100644 --- a/data/admin/plant.py +++ b/data/admin/plant.py @@ -80,7 +80,7 @@ class PlantAdmin(ElementAdminWithChangeReason): SubstanceInlineAdmin, PlantSynonymInline, ) - list_display = ("name", "family", "status", "is_risky", "novel_food") + list_display = ("name", "is_obsolete", "family", "status", "is_risky", "novel_food") list_filter = ("is_obsolete", "family", "status", "is_risky", "novel_food") show_facets = admin.ShowFacets.NEVER readonly_fields = ( diff --git a/data/admin/substance.py b/data/admin/substance.py index d915be72..b2e2f469 100644 --- a/data/admin/substance.py +++ b/data/admin/substance.py @@ -121,7 +121,16 @@ def get_ingredients(self, obj): "get_microorganisms", "get_ingredients", ] - list_display = ("name", "get_plants", "get_microorganisms", "get_ingredients", "status", "is_risky", "novel_food") + list_display = ( + "name", + "is_obsolete", + "get_plants", + "get_microorganisms", + "get_ingredients", + "status", + "is_risky", + "novel_food", + ) list_filter = ("is_obsolete", "status", "is_risky", "novel_food") show_facets = admin.ShowFacets.NEVER search_fields = ["id", "name"] From 68f0ac08b8d30754af3bdd225dab0a9c44070955 Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Mon, 16 Dec 2024 09:46:17 +0100 Subject: [PATCH 2/9] add synonym inline on substance admin --- data/admin/substance.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/data/admin/substance.py b/data/admin/substance.py index b2e2f469..bfc0a2d4 100644 --- a/data/admin/substance.py +++ b/data/admin/substance.py @@ -1,9 +1,10 @@ from django import forms from django.contrib import admin +from django.db import models from django.urls import reverse from django.utils.html import format_html -from data.models import Substance +from data.models import Substance, SubstanceSynonym from .abstract_admin import ElementAdminWithChangeReason @@ -19,6 +20,15 @@ class Meta: } +class SubstanceSynonymInline(admin.TabularInline): + model = SubstanceSynonym + extra = 1 + + formfield_overrides = { + models.TextField: {"widget": forms.Textarea(attrs={"cols": 60, "rows": 1})}, + } + + @admin.register(Substance) class SubstanceAdmin(ElementAdminWithChangeReason): @classmethod @@ -104,6 +114,7 @@ def get_ingredients(self, obj): }, ), ] + inlines = (SubstanceSynonymInline,) readonly_fields = [ "siccrf_name", "siccrf_name_en", From 87746f1f1ea4df11623113f108a62127b11fb16e Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Mon, 16 Dec 2024 09:48:57 +0100 Subject: [PATCH 3/9] avoid override of CA_status at import --- data/etl/utils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/etl/utils.py b/data/etl/utils.py index 8424c23c..85c7f5cf 100644 --- a/data/etl/utils.py +++ b/data/etl/utils.py @@ -23,8 +23,7 @@ def pre_import_treatments(field, value): new_fields = {"siccrf_max_quantity": clean_value(value, field), "ca_must_specify_quantity": True} elif field.name == "siccrf_status": new_fields = { - "siccrf_status": clean_value(value, field), - "ca_status": convert_status(clean_value(value, field)), + "siccrf_status": convert_status(clean_value(value, field)), } # si le status SICCRF correspond à "à inscrire" if int(value) == 3: From 32a5afdf8b0977f751445b9c63baa478f214f410 Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Mon, 16 Dec 2024 11:28:58 +0100 Subject: [PATCH 4/9] fix compare import date to execute only on import of each dump --- clevercloud/run_succeeded_hook.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clevercloud/run_succeeded_hook.sh b/clevercloud/run_succeeded_hook.sh index 538b78ea..0a1c51e7 100755 --- a/clevercloud/run_succeeded_hook.sh +++ b/clevercloud/run_succeeded_hook.sh @@ -6,7 +6,8 @@ DATE=${FILEPATH##"s3://csv-data/"} DATE=${DATE%"/"} mkdir csv-data # if this date doesn't exist yet -if ls csv-data/$DATE ; then +LAST_DATE=$(psql postgresql://$DB_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME -t -1 -c "select * from data_last_import order by import_date desc limit 1;") +if [[ "$LAST_DATE" == *"$DATE"* ]] ; then echo "This data has already been loaded" else # retrieve most recent files @@ -14,4 +15,5 @@ else s3cmd get s3://csv-data/$DATE/ --recursive csv-data/$DATE/ # import those files to database (django models) python ~/$APP_ID/manage.py load_ingredients -d csv-data/$DATE $DATE + psql postgresql://$DB_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME -c "insert into data_last_import (import_date) values ('$DATE');" fi From 737d12a1eafff8c418657488a4430bd818bb68b1 Mon Sep 17 00:00:00 2001 From: Alejandro MG Date: Mon, 16 Dec 2024 12:02:03 +0100 Subject: [PATCH 5/9] Ensures the image format is supported for declaration assignments --- frontend/src/views/ProducerFormPage/AttachmentTab.vue | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/frontend/src/views/ProducerFormPage/AttachmentTab.vue b/frontend/src/views/ProducerFormPage/AttachmentTab.vue index 70f6a875..2f6db5ae 100644 --- a/frontend/src/views/ProducerFormPage/AttachmentTab.vue +++ b/frontend/src/views/ProducerFormPage/AttachmentTab.vue @@ -20,7 +20,7 @@ { window.alert(`Le fichier ${files[i].name} dépasse la taille limite de 2 Mo`) continue } + const formatIsValid = acceptedTypes.indexOf(files[i].type) > -1 + if (!formatIsValid) { + window.alert( + `Le format du fichier ${files[i].name} n'est pas supporté. Merci de joindre un fichier en JPG, GIF, PNG ou PDF.` + ) + continue + } const base64 = await toBase64(files[i]) container.push({ ...{ From b2c9e2aa4cc91a4ce3b853450f878e8791cc8053 Mon Sep 17 00:00:00 2001 From: Alejandro MG Date: Mon, 16 Dec 2024 15:13:38 +0100 Subject: [PATCH 6/9] Shows the unauthorized status of an element --- frontend/src/views/ProducerFormPage/ElementCard.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/views/ProducerFormPage/ElementCard.vue b/frontend/src/views/ProducerFormPage/ElementCard.vue index 8101535a..b1752507 100644 --- a/frontend/src/views/ProducerFormPage/ElementCard.vue +++ b/frontend/src/views/ProducerFormPage/ElementCard.vue @@ -9,6 +9,9 @@
{{ synonyms }}
+
+ +
@@ -126,6 +129,7 @@ import { computed, watch } from "vue" import { getElementName } from "@/utils/elements" import { getActivityReadonlyByType } from "@/utils/mappings" import ElementCommentModal from "@/components/ElementCommentModal" +import ElementStatusBadge from "@/components/ElementStatusBadge" const model = defineModel() const store = useRootStore() From 1585196e73f066b25b439244beb8858dfc5c23ed Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Mon, 16 Dec 2024 15:28:35 +0100 Subject: [PATCH 7/9] fix tests --- data/tests/test_csv_importer.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data/tests/test_csv_importer.py b/data/tests/test_csv_importer.py index 6da021d9..14e2c7a0 100644 --- a/data/tests/test_csv_importer.py +++ b/data/tests/test_csv_importer.py @@ -216,11 +216,13 @@ def test_status_import(self): self.assertEqual(len(Plant.objects.filter(siccrf_status=1)), 2) self.assertEqual(len(Microorganism.objects.filter(status=IngredientStatus.AUTHORIZED)), 2) - self.assertEqual(len(Microorganism.objects.filter(siccrf_status=3)), 2) + self.assertEqual(len(Microorganism.objects.filter(siccrf_status=3)), 0) # ce status est converti + self.assertEqual(len(Microorganism.objects.filter(siccrf_status=1)), 2) self.assertEqual(len(Microorganism.objects.filter(to_be_entered_in_next_decree=True)), 2) self.assertEqual(len(Ingredient.objects.filter(status=IngredientStatus.NO_STATUS)), 2) - self.assertEqual(len(Ingredient.objects.filter(siccrf_status=4)), 2) + self.assertEqual(len(Ingredient.objects.filter(siccrf_status=4)), 0) # ce status est converti + self.assertEqual(len(Ingredient.objects.filter(siccrf_status=3)), 2) self.assertEqual(len(Ingredient.objects.filter(status=IngredientStatus.AUTHORIZED)), 0) self.assertEqual(len(Substance.objects.filter(status=IngredientStatus.NOT_AUTHORIZED)), 2) From 501eda92b8c33493dd009e2e599c0225d18c7140 Mon Sep 17 00:00:00 2001 From: Alejandro MG Date: Mon, 16 Dec 2024 15:32:56 +0100 Subject: [PATCH 8/9] Moves the badge to the correct component --- .../DeclarationSummary/SummaryElementItem.vue | 9 +++++++- .../DeclarationSummary/SummaryElementList.vue | 19 +++++++++++++--- .../SummaryElementListItems.vue | 3 ++- .../components/DeclarationSummary/index.vue | 22 ++++++++++++++++--- .../src/components/ElementStatusBadge.vue | 2 +- frontend/src/views/InstructionPage/index.vue | 2 ++ .../views/ProducerFormPage/ElementCard.vue | 4 ---- frontend/src/views/VisaPage/index.vue | 2 ++ 8 files changed, 50 insertions(+), 13 deletions(-) diff --git a/frontend/src/components/DeclarationSummary/SummaryElementItem.vue b/frontend/src/components/DeclarationSummary/SummaryElementItem.vue index 3ca9b99c..71829c45 100644 --- a/frontend/src/components/DeclarationSummary/SummaryElementItem.vue +++ b/frontend/src/components/DeclarationSummary/SummaryElementItem.vue @@ -10,6 +10,12 @@

+ + @@ -38,13 +44,14 @@ import { getElementName } from "@/utils/elements" import { useRootStore } from "@/stores/root" import { storeToRefs } from "pinia" import ElementCommentModal from "@/components/ElementCommentModal" +import ElementStatusBadge from "@/components/ElementStatusBadge" const { plantParts, units, preparations, loggedUser } = storeToRefs(useRootStore()) const isInstructor = computed(() => loggedUser.value?.globalRoles.some((x) => x.name === "InstructionRole")) const model = defineModel() -const props = defineProps({ objectType: { type: String } }) +const props = defineProps({ objectType: { type: String }, showElementAuthorization: { type: Boolean } }) const plantPartName = computed(() => plantParts.value?.find((x) => x.id === model.value.usedPart)?.name || "Aucune") const unitName = computed(() => units.value?.find((x) => x.id === model.value.unit)?.name || "") diff --git a/frontend/src/components/DeclarationSummary/SummaryElementList.vue b/frontend/src/components/DeclarationSummary/SummaryElementList.vue index 50bc5138..1aea1b4e 100644 --- a/frontend/src/components/DeclarationSummary/SummaryElementList.vue +++ b/frontend/src/components/DeclarationSummary/SummaryElementList.vue @@ -5,13 +5,21 @@ - +
- +
@@ -20,5 +28,10 @@ import SummaryElementListTitle from "./SummaryElementListTitle" import SummaryElementListItems from "./SummaryElementListItems" -defineProps({ objectType: { type: String }, elements: { type: Array }, useAccordions: { type: Boolean } }) +defineProps({ + objectType: { type: String }, + elements: { type: Array }, + useAccordions: { type: Boolean }, + showElementAuthorization: { type: Boolean }, +}) diff --git a/frontend/src/components/DeclarationSummary/SummaryElementListItems.vue b/frontend/src/components/DeclarationSummary/SummaryElementListItems.vue index 03f2ed74..0240f8e4 100644 --- a/frontend/src/components/DeclarationSummary/SummaryElementListItems.vue +++ b/frontend/src/components/DeclarationSummary/SummaryElementListItems.vue @@ -6,6 +6,7 @@ :key="`summary-${objectType}-${index}`" v-model="elements[index]" :objectType="objectType" + :showElementAuthorization="showElementAuthorization" /> @@ -13,5 +14,5 @@ diff --git a/frontend/src/components/DeclarationSummary/index.vue b/frontend/src/components/DeclarationSummary/index.vue index 9f36eef6..c2fe7b6e 100644 --- a/frontend/src/components/DeclarationSummary/index.vue +++ b/frontend/src/components/DeclarationSummary/index.vue @@ -27,38 +27,54 @@ - + - +

Substances contenues dans la composition :

@@ -107,7 +123,7 @@ const router = useRouter() const { units, populations, conditions, effects, galenicFormulations } = storeToRefs(useRootStore()) const payload = defineModel() -defineProps({ readonly: Boolean, showArticle: Boolean, useAccordions: Boolean }) +defineProps({ readonly: Boolean, showArticle: Boolean, useAccordions: Boolean, showElementAuthorization: Boolean }) const unitInfo = computed(() => { if (!payload.value.unitQuantity) return null const unitMeasurement = units.value?.find?.((x) => x.id === payload.value.unitMeasurement)?.name || "-" diff --git a/frontend/src/components/ElementStatusBadge.vue b/frontend/src/components/ElementStatusBadge.vue index 3de2957e..928a4ea9 100644 --- a/frontend/src/components/ElementStatusBadge.vue +++ b/frontend/src/components/ElementStatusBadge.vue @@ -1,6 +1,6 @@