From 2b26105d87f865d84f0ab6360f42f16dda55c029 Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Mon, 21 Oct 2024 10:39:33 +0200 Subject: [PATCH 1/4] add certificate-objected template --- .../certificates/certificate-objected.html | 43 +++++++++++++++++++ web/views/certificate.py | 2 + 2 files changed, 45 insertions(+) create mode 100644 web/templates/certificates/certificate-objected.html diff --git a/web/templates/certificates/certificate-objected.html b/web/templates/certificates/certificate-objected.html new file mode 100644 index 000000000..16236dc7f --- /dev/null +++ b/web/templates/certificates/certificate-objected.html @@ -0,0 +1,43 @@ +{% extends 'certificates/certificate-base-template.html' %} +{% block 'body' %} +

+ Réf. : n° {{declaration.id}} +

+
+

+ Madame, Monsieur, +

+

+ Le {{ last_submission_date|date:"l j F Y" }}, vous avez déclaré la mise sur le marché du produit : + + {{ declaration.name }} + +

+ L’examen de cette déclaration soulève les objections suivantes, qui la rendent irrecevable: + + {{ declaration.objection }} + +

+

+ Vous disposez d’un délai de 30 jours francs, à compter de la date de réception de la présente lettre, pour régulariser votre déclaration ou me faire part de vos observations. + Vous pouvez vous faire assister ou représenter par le conseil de votre choix. +

+

+ En l’absence de réponse de votre part dans ce délai, le dossier sera clos et la déclaration sera réputée rejetée. +

+

+ Je vous rappelle, à toutes fins utiles, que l’article 20 du décret du décret du 20 mars 2006 précité vous interdit d’importer pour la mise en libre pratique, + de détenir en vue de la vente ou de la distribution à titre gratuit, de mettre en vente, de vendre ou de distribuer à titre gratuit un complément alimentaire qui n’a pas été dûment déclaré. +

+

+ Je vous prie d’agréer, Madame, Monsieur, l’expression de ma considération distinguée. +

+

+ La Sous-Directrice de la sécurité sanitaire
+ des aliments +

+

+ Vanessa HUMMEL-FOURRAT +

+
+{% endblock %} diff --git a/web/views/certificate.py b/web/views/certificate.py index b4a1482ac..1024407df 100644 --- a/web/views/certificate.py +++ b/web/views/certificate.py @@ -53,6 +53,8 @@ def get_template_path(self, declaration): return f"certificates/certificate-submitted-art-{article}.html" if declaration.status in [status.AUTHORIZED, status.WITHDRAWN]: return f"certificates/certificate-art-{article}.html" + if declaration.status == status.OBJECTION: + return "certificates/certificate-objected.html" if declaration.status == status.REJECTED: return "certificates/certificate-rejected.html" From 953c6e41c868a09a8cb942ca3ac9de0cf78febcd Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Mon, 21 Oct 2024 10:40:00 +0200 Subject: [PATCH 2/4] reword certificate-rejected --- web/templates/certificates/certificate-rejected.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/templates/certificates/certificate-rejected.html b/web/templates/certificates/certificate-rejected.html index 93e519e8f..747934aa6 100644 --- a/web/templates/certificates/certificate-rejected.html +++ b/web/templates/certificates/certificate-rejected.html @@ -13,11 +13,11 @@

{{ declaration.name }}

- Des objections ont été émises à l’égard de cette déclaration. Aucune observation apportée n'a - été de nature à remettre en cause les objections opposées à la déclaration + Des objections ont été émises à l’égard de cette déclaration. Toutefois, les éléments apportés + à cette occasion ne sont pas de nature à remettre en cause les objections opposées à la déclaration.

- Votre déclaration est donc refusée. En application de l’article 20 du décret n°2006-352 du décret du 20 mars 2006, + Votre déclaration est donc refusée. En application de l’article 20 du décret n°2006-352 du 20 mars 2006, il vous est interdit d’importer pour la mise en libre pratique, de détenir en vue de la vente ou de la distribution à titre gratuit, de mettre en vente, de vendre ou de distribuer à titre gratuit le complément alimentaire cité ci-dessus.

From ea381792083b55b1d149222ab9014d86649f8b08 Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Mon, 21 Oct 2024 11:12:19 +0200 Subject: [PATCH 3/4] make certificate downloadable --- frontend/src/components/DeclarationAlert.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/DeclarationAlert.vue b/frontend/src/components/DeclarationAlert.vue index 4247d6d3f..0b6244c14 100644 --- a/frontend/src/components/DeclarationAlert.vue +++ b/frontend/src/components/DeclarationAlert.vue @@ -70,7 +70,7 @@ const declarantDisplayData = computed(() => { title: "Une objection a été emise sur cette déclaration", expirationDate: props.declaration?.expirationDate, body: blockingReasons.value, - canDownloadCertificate: false, + canDownloadCertificate: true, } case "OBSERVATION": return { From cecf808c605d875177fea2feadcc66fc838d6b24 Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Mon, 21 Oct 2024 14:30:34 +0200 Subject: [PATCH 4/4] blocking reason is a declaration property + wording --- api/serializers/declaration.py | 10 +--------- data/models/declaration.py | 10 ++++++++++ frontend/src/components/DeclarationAlert.vue | 16 ++++++++-------- .../certificates/certificate-objected.html | 14 +++++++++----- .../certificates/certificate-rejected.html | 4 ++-- 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/api/serializers/declaration.py b/api/serializers/declaration.py index 2ebe3a819..58aa36a0b 100644 --- a/api/serializers/declaration.py +++ b/api/serializers/declaration.py @@ -19,7 +19,6 @@ Plant, PlantPart, Population, - Snapshot, Substance, SubstanceUnit, ) @@ -322,7 +321,7 @@ class DeclarationSerializer(serializers.ModelSerializer): computed_substances = DeclaredListSerializer(child=ComputedSubstanceSerializer(), required=False) attachments = DeclaredListSerializer(child=AttachmentSerializer(), required=False) name = serializers.CharField(allow_blank=False, required=True) - blocking_reasons = serializers.SerializerMethodField(read_only=True) + blocking_reasons = serializers.ListField(read_only=True) class Meta: model = Declaration @@ -469,13 +468,6 @@ def to_representation(self, obj): ret.pop("private_notes") return ret - def get_blocking_reasons(self, obj): - try: - latest_snapshot = obj.snapshots.filter(blocking_reasons__isnull=False).latest("creation_date") - return latest_snapshot.blocking_reasons - except Snapshot.DoesNotExist: - return None - class DeclarationShortSerializer(serializers.ModelSerializer): author = SimpleUserSerializer(read_only=True) diff --git a/data/models/declaration.py b/data/models/declaration.py index 0098dbdbb..9e843de59 100644 --- a/data/models/declaration.py +++ b/data/models/declaration.py @@ -206,6 +206,16 @@ def create_snapshot( blocking_reasons=blocking_reasons, ) + @property + def blocking_reasons(self): + from data.models import Snapshot + + try: + latest_snapshot = self.snapshots.filter(blocking_reasons__isnull=False).latest("creation_date") + return latest_snapshot.blocking_reasons + except Snapshot.DoesNotExist: + return None + @property def json_representation(self): from api.serializers import DeclarationSerializer diff --git a/frontend/src/components/DeclarationAlert.vue b/frontend/src/components/DeclarationAlert.vue index 0b6244c14..2712479db 100644 --- a/frontend/src/components/DeclarationAlert.vue +++ b/frontend/src/components/DeclarationAlert.vue @@ -67,7 +67,7 @@ const declarantDisplayData = computed(() => { case "OBJECTION": return { type: "warning", - title: "Une objection a été emise sur cette déclaration", + title: "Une objection a été émise sur cette déclaration", expirationDate: props.declaration?.expirationDate, body: blockingReasons.value, canDownloadCertificate: true, @@ -75,7 +75,7 @@ const declarantDisplayData = computed(() => { case "OBSERVATION": return { type: "warning", - title: "Une observation a été emise sur cette déclaration", + title: "Une observation a été émise sur cette déclaration", expirationDate: props.declaration?.expirationDate, body: blockingReasons.value, canDownloadCertificate: false, @@ -125,14 +125,14 @@ const instructorDisplayData = computed(() => { case "OBJECTION": return { type: "info", - title: "Une objection a été emise sur cette déclaration", + title: "Une objection a été émise sur cette déclaration", body: blockingReasons.value, - canDownloadCertificate: false, + canDownloadCertificate: true, } case "OBSERVATION": return { type: "warning", - title: "Une observation a été emise sur cette déclaration", + title: "Une observation a été émise sur cette déclaration", body: blockingReasons.value, canDownloadCertificate: false, } @@ -181,14 +181,14 @@ const visorDisplayData = computed(() => { case "OBJECTION": return { type: "info", - title: "Une objection a été emise sur cette déclaration", + title: "Une objection a été émise sur cette déclaration", body: blockingReasons.value, - canDownloadCertificate: false, + canDownloadCertificate: true, } case "OBSERVATION": return { type: "warning", - title: "Une observation a été emise sur cette déclaration", + title: "Une observation a été émise sur cette déclaration", body: blockingReasons.value, canDownloadCertificate: false, } diff --git a/web/templates/certificates/certificate-objected.html b/web/templates/certificates/certificate-objected.html index 16236dc7f..51b1b7b2d 100644 --- a/web/templates/certificates/certificate-objected.html +++ b/web/templates/certificates/certificate-objected.html @@ -1,7 +1,7 @@ {% extends 'certificates/certificate-base-template.html' %} {% block 'body' %}

- Réf. : n° {{declaration.id}} + Réf. : Dossier n° {{declaration.id}}

@@ -10,13 +10,17 @@

Le {{ last_submission_date|date:"l j F Y" }}, vous avez déclaré la mise sur le marché du produit : - {{ declaration.name }} + {{ declaration.name }} / {{ declaration.galenic_formulation }}

- L’examen de cette déclaration soulève les objections suivantes, qui la rendent irrecevable: - - {{ declaration.objection }} + L’examen de cette déclaration soulève les objections suivantes, qui la rendent irrecevable : + +
+ {% for reason in declaration.blocking_reasons %} + - {{ reason }}
+ {% endfor %}
+

Vous disposez d’un délai de 30 jours francs, à compter de la date de réception de la présente lettre, pour régulariser votre déclaration ou me faire part de vos observations. diff --git a/web/templates/certificates/certificate-rejected.html b/web/templates/certificates/certificate-rejected.html index 747934aa6..e50be9c4c 100644 --- a/web/templates/certificates/certificate-rejected.html +++ b/web/templates/certificates/certificate-rejected.html @@ -1,7 +1,7 @@ {% extends 'certificates/certificate-base-template.html' %} {% block 'body' %}

- Réf. : n° {{declaration.id}} + Réf. : Dossier n° {{declaration.id}}

@@ -10,7 +10,7 @@

Le {{ last_submission_date|date:"l j F Y" }}, vous avez déclaré la mise sur le marché du produit : - {{ declaration.name }} + {{ declaration.name }} / {{ declaration.galenic_formulation }}

Des objections ont été émises à l’égard de cette déclaration. Toutefois, les éléments apportés