Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix le bug sur les plantes dans le CompositionStep et les preparations viennent du backend #897

Merged
merged 8 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/serializers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .condition import ConditionSerializer
from .effect import EffectSerializer
from .galenic_formulation import GalenicFormulationSerializer
from .preparation import PreparationSerializer
from .unit import SubstanceUnitSerializer
from .autocomplete_item import AutocompleteItemSerializer
from .declaration import DeclarationSerializer, DeclarationShortSerializer, SimpleDeclarationSerializer
Expand Down
15 changes: 15 additions & 0 deletions api/serializers/preparation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from rest_framework import serializers

from data.models import Preparation


class PreparationSerializer(serializers.ModelSerializer):
# TODO make a unique abstract class for all simple models (Condition, Effect, Preparation, Population...)
class Meta:
model = Preparation
fields = [
"id",
"name",
"name_en",
]
read_only_fields = fields
1 change: 1 addition & 0 deletions api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
path("conditions/", views.ConditionListView.as_view(), name="condition_list"),
path("effects/", views.EffectListView.as_view(), name="effect_list"),
path("galenic-formulations/", views.GalenicFormulationListView.as_view(), name="galenic_formulation_list"),
path("preparations/", views.PreparationListView.as_view(), name="preparation_list"),
path("units/", views.UnitListView.as_view(), name="unit_list"),
# Authentication
path("login/", views.LoginView.as_view(), name="login"),
Expand Down
1 change: 1 addition & 0 deletions api/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
)
from .effect import EffectListView
from .galenic_formulation import GalenicFormulationListView
from .preparation import PreparationListView
from .ingredient import IngredientRetrieveView
from .microorganism import MicroorganismRetrieveView
from .newsletter import SubscribeNewsletter
Expand Down
3 changes: 3 additions & 0 deletions data/csv_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
PlantPart,
PlantSynonym,
Population,
Preparation,
Substance,
SubstanceSynonym,
SubstanceUnit,
Expand All @@ -49,6 +50,7 @@
"REF_ICA_OBJECTIFS_EFFETS.csv": Effect,
"REF_ICA_FORME_GALENIQUE.csv": GalenicFormulation,
"REF_ICA_UNITE.csv": SubstanceUnit,
"REF_ICA_TYPE_PREPARATION.csv": Preparation,
# Les fichiers csv avec les Foreign Keys
"REF_ICA_INGREDIENT_AUTRE_SYNONYME.csv": IngredientSynonym,
"REF_ICA_PLANTE_SYNONYME.csv": PlantSynonym,
Expand Down Expand Up @@ -82,6 +84,7 @@ class CSVImporter:
"UNT": SubstanceUnit,
"OBJEFF": Effect,
"FRMGAL": GalenicFormulation,
"TYPPREP": Preparation,
"STINGSBS": IngredientStatus,
# Pour les tables de relation on garde le prefix correspondant au modèle dans lequel les données vont être importées
# "REF_ICA_AUTREING_SUBSTACTIVE.csv": "INGA",
Expand Down
182 changes: 182 additions & 0 deletions data/migrations/0086_preparation_historicalpreparation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# Generated by Django 5.1 on 2024-08-26 14:26

import django.db.models.deletion
import django.db.models.functions.comparison
import simple_history.models
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("data", "0085_companyaccessclaim_declarant_role_and_more"),
]

operations = [
migrations.CreateModel(
name="Preparation",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("creation_date", models.DateTimeField(auto_now_add=True)),
("modification_date", models.DateTimeField(auto_now=True)),
(
"missing_import_data",
models.BooleanField(
blank=True, default=False, editable=False, null=True
),
),
(
"siccrf_id",
models.IntegerField(
blank=True,
db_index=True,
editable=False,
null=True,
unique=True,
verbose_name="id dans les tables et tables relationnelles SICCRF",
),
),
(
"siccrf_name",
models.TextField(editable=False, verbose_name="nom SICCRF"),
),
("ca_name", models.TextField(blank=True, verbose_name="nom CA")),
(
"name",
models.GeneratedField(
db_persist=True,
expression=django.db.models.functions.comparison.Coalesce(
django.db.models.functions.comparison.NullIf(
models.F("ca_name"), models.Value("")
),
models.F("siccrf_name"),
),
output_field=models.TextField(verbose_name="nom"),
),
),
(
"siccrf_is_obsolete",
models.BooleanField(
default=False,
editable=False,
verbose_name="objet obsolète selon SICCRF",
),
),
(
"ca_is_obsolete",
models.BooleanField(
default=None, null=True, verbose_name="objet obsolète selon CA"
),
),
(
"is_obsolete",
models.GeneratedField(
db_persist=True,
expression=django.db.models.functions.comparison.Coalesce(
models.F("ca_is_obsolete"), models.F("siccrf_is_obsolete")
),
output_field=models.BooleanField(verbose_name="objet obsolète"),
),
),
(
"siccrf_name_en",
models.TextField(
blank=True, verbose_name="nom en anglais selon la base SICCRF"
),
),
],
options={
"verbose_name": "préparation de plantes",
"verbose_name_plural": "préparations de plantes",
},
),
migrations.CreateModel(
name="HistoricalPreparation",
fields=[
(
"id",
models.BigIntegerField(
auto_created=True, blank=True, db_index=True, verbose_name="ID"
),
),
("creation_date", models.DateTimeField(blank=True, editable=False)),
("modification_date", models.DateTimeField(blank=True, editable=False)),
(
"missing_import_data",
models.BooleanField(
blank=True, default=False, editable=False, null=True
),
),
(
"siccrf_id",
models.IntegerField(
blank=True,
db_index=True,
editable=False,
null=True,
verbose_name="id dans les tables et tables relationnelles SICCRF",
),
),
(
"siccrf_name",
models.TextField(editable=False, verbose_name="nom SICCRF"),
),
("ca_name", models.TextField(blank=True, verbose_name="nom CA")),
(
"siccrf_is_obsolete",
models.BooleanField(
default=False,
editable=False,
verbose_name="objet obsolète selon SICCRF",
),
),
(
"ca_is_obsolete",
models.BooleanField(
default=None, null=True, verbose_name="objet obsolète selon CA"
),
),
(
"siccrf_name_en",
models.TextField(
blank=True, verbose_name="nom en anglais selon la base SICCRF"
),
),
("history_id", models.AutoField(primary_key=True, serialize=False)),
("history_date", models.DateTimeField(db_index=True)),
("history_change_reason", models.CharField(max_length=100, null=True)),
(
"history_type",
models.CharField(
choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")],
max_length=1,
),
),
(
"history_user",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"verbose_name": "historical préparation de plantes",
"verbose_name_plural": "historical préparations de plantes",
"ordering": ("-history_date", "-history_id"),
"get_latest_by": ("history_date", "history_id"),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
]
3 changes: 2 additions & 1 deletion data/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .condition import Condition
from .effect import Effect
from .galenic_formulation import GalenicFormulation
from .preparation import Preparation
from .unit import SubstanceUnit
from .ingredient_status import IngredientStatus
from .global_roles import InstructionRole, VisaRole
Expand Down Expand Up @@ -41,4 +42,4 @@
SubstanceUnit,
]

DECLARATION_MODELS = [Condition, Effect, GalenicFormulation, Population]
DECLARATION_MODELS = [Condition, Effect, GalenicFormulation, Population, Preparation]
18 changes: 18 additions & 0 deletions data/models/preparation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from django.db import models

from simple_history.models import HistoricalRecords

from .abstract_models import CommonModel


class Preparation(CommonModel):
class Meta:
verbose_name = "préparation de plantes"
verbose_name_plural = "préparations de plantes"

siccrf_name_en = models.TextField(blank=True, verbose_name="nom en anglais selon la base SICCRF")
history = HistoricalRecords(inherit=True, excluded_fields=["name", "is_obsolete"])

@property
def name_en(self):
return self.siccrf_name_en
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ import { useRootStore } from "@/stores/root"
import { storeToRefs } from "pinia"
import ElementCommentModal from "@/components/ElementCommentModal"

const { plantParts, units } = storeToRefs(useRootStore())
const { plantParts, units, preparations } = storeToRefs(useRootStore())

const model = defineModel()
const props = defineProps({ objectType: { type: String } })

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 || "")
const preparationName = computed(
() => preparations.value?.find((x) => x.id === parseInt(model.value.preparation))?.name || ""
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ici, je n'ai pas compris pourquoi l'id (IntegerField) est sérialisé en tant que string.
C'est le cas aussi pour le modèle GalenicFormulation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

La sérialisation backend est bien un integer, mais le input select du html renvoi toujours un string. Sur cette question SO ça parle du pourquoi on ne peut pas retourner un int d'un select.

)

const elementInfo = computed(() => {
if (props.objectType === "microorganism") {
Expand All @@ -40,7 +43,7 @@ const elementInfo = computed(() => {
if (props.objectType === "plant") {
const used_part_label = `Partie utilisée : « ${plantPartName.value} »`
const quantity_label = model.value.quantity ? `Qté par DJR : ${model.value.quantity} ${unitName.value}` : null
const preparation_label = model.value.preparation ? `Préparation : ${model.value.preparation}` : null
const preparation_label = model.value.preparation ? `Préparation : ${preparationName.value}` : null
return [used_part_label, quantity_label, preparation_label].filter(Boolean).join(` | `)
}
if (props.objectType === "form_of_supply" || props.objectType === "active_ingredient")
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/stores/root.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const useRootStore = defineStore("root", () => {
const conditions = ref(null)
const effects = ref(null)
const galenicFormulations = ref(null)
const preparations = ref(null)
const plantParts = ref(null)
const units = ref(null)

Expand Down Expand Up @@ -52,6 +53,10 @@ export const useRootStore = defineStore("root", () => {
const { data } = await useFetch("/api/v1/galenic-formulations/").json()
galenicFormulations.value = otherFieldsAtTheEnd(data.value)
}
const fetchPreparations = async () => {
const { data } = await useFetch("/api/v1/preparations/").json()
preparations.value = data.value
}
const fetchPlantParts = async () => {
const { data } = await useFetch("/api/v1/plant-parts/").json()
plantParts.value = data.value
Expand All @@ -66,6 +71,7 @@ export const useRootStore = defineStore("root", () => {
fetchPopulations()
fetchPlantParts()
fetchGalenicFormulations()
fetchPreparations()
fetchUnits()
}
return {
Expand All @@ -80,6 +86,7 @@ export const useRootStore = defineStore("root", () => {
fetchConditions,
fetchEffects,
fetchGalenicFormulations,
fetchPreparations,
fetchDeclarationFieldsData,
fetchPlantParts,
fetchUnits,
Expand All @@ -88,6 +95,7 @@ export const useRootStore = defineStore("root", () => {
conditions,
effects,
galenicFormulations,
preparations,
units,
}
})
32 changes: 1 addition & 31 deletions frontend/src/views/ProducerFormPage/ElementCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<DsfrInputGroup class="max-w-sm">
<DsfrSelect
label="Préparation"
:options="preparations"
:options="store.preparations?.map((preparation) => ({ text: preparation.name, value: preparation.id }))"
v-model="model.preparation"
defaultUnselectedText=""
:required="true"
Expand Down Expand Up @@ -131,34 +131,4 @@ const showFields = computed(() => {
return true
return false
})

// TODO: vérifier qu'on ait ces infos en base ou accepter de les avoir en front only
const preparations = [
"Alcoolature",
"Autre extrait fluide",
"Autre extrait sec",
"Autre macérât",
"Baume",
"Distillation",
"Extrait au CO2 supercritique",
"Extrait fluide alcoolique",
"Extrait fluide aqueux",
"Extrait fluide hydroalcoolique",
"Extrait fluide hydroglycériné",
"Extrait mou",
"Extrait sec alcoolique",
"Extrait sec aqueux",
"Extrait sec hydroalcoolique",
"Extrait sec hydroglycériné",
"Hydrolât (eau florale)",
"Macérât alcoolique",
"Macérât aqueux",
"Macérât huileux",
"Macérât hydroalcoolique",
"Macérât hydroglycériné",
"Oléorésine et gomme-oléorésine",
"Poudre (de plantes séchées ou broyées)",
"Pression à froid",
"Teinture",
]
</script>
Loading