diff --git a/data/README.md b/data/README.md index 7c2ec3706..a54200fc4 100644 --- a/data/README.md +++ b/data/README.md @@ -44,7 +44,7 @@ REF_ICA_FONCTION_INGREDIENT | | | | | | |ICA_POPULATION_RISQUE_DECLAREE | | | |ICA_SUBSTANCE_DECLAREE | | | |ICA_USAGER | | 🕵️anonymisée (contient Foreign Key vers USR, ADM, ETAB) | -|REF_ICA_TYPE_DECLARATION | |Enum ? ou obsolète ? (Art 1(, Art 1-, Simplifiée)) | +|REF_ICA_TYPE_DECLARATION | |Enum ? ou obsolète ? (Art 15, Art 16, Simplifiée)) | |REF_ICA_TYPE_HERITAGE | | Enum ? (Simplifié ou Nouvelle formule)| |REF_ICA_TYPE_VERSION_DECLARATION | | | |REF_ICA_FORME_GALENIQUE | | | diff --git a/data/etl/teleicare_history/extractor.py b/data/etl/teleicare_history/extractor.py index 9ca33f281..a2d917c7f 100644 --- a/data/etl/teleicare_history/extractor.py +++ b/data/etl/teleicare_history/extractor.py @@ -4,18 +4,46 @@ from datetime import date, datetime, timezone from django.core.exceptions import MultipleObjectsReturned, ValidationError -from django.db import IntegrityError +from django.db import IntegrityError, transaction from phonenumber_field.phonenumber import PhoneNumber -from data.models import GalenicFormulation, SubstanceUnit +from data.models import ( + Condition, + Effect, + GalenicFormulation, + Ingredient, + Microorganism, + Plant, + PlantPart, + Population, + Preparation, + Substance, + SubstanceUnit, +) from data.models.company import ActivityChoices, Company -from data.models.declaration import Declaration +from data.models.declaration import ( + ComputedSubstance, + Declaration, + DeclaredIngredient, + DeclaredMicroorganism, + DeclaredPlant, +) from data.models.teleicare_history.ica_declaration import ( IcaComplementAlimentaire, IcaDeclaration, + IcaEffetDeclare, + IcaPopulationCibleDeclaree, + IcaPopulationRisqueDeclaree, IcaVersionDeclaration, ) +from data.models.teleicare_history.ica_declaration_composition import ( + IcaIngredient, + IcaIngredientAutre, + IcaMicroOrganisme, + IcaPreparation, + IcaSubstanceDeclaree, +) from data.models.teleicare_history.ica_etablissement import IcaEtablissement logger = logging.getLogger(__name__) @@ -177,6 +205,144 @@ def convert_str_date(value, aware=False): 8: Declaration.DeclarationStatus.ABANDONED, # 'abandonné' } +DECLARATION_TYPE_TO_ARTICLE_MAPPING = { + 1: Declaration.Article.ARTICLE_15, + 2: Declaration.Article.ARTICLE_16, + 3: None, # Type "simplifié" dans Teleicare, normalement liées à des modifications de déclarations déjà instruites +} + + +MANY_TO_MANY_PRODUCT_MODELS_MATCHING = { + "effects": {"teleIcare_model": IcaEffetDeclare, "teleIcare_pk": "objeff_ident", "CA_model": Effect}, + "conditions_not_recommended": { + "teleIcare_model": IcaPopulationRisqueDeclaree, + "teleIcare_pk": "poprs_ident", + "CA_model": Condition, + }, + "populations": { + "teleIcare_model": IcaPopulationCibleDeclaree, + "teleIcare_pk": "popcbl_ident", + "CA_model": Population, + }, +} + + +def create_declared_plant(declaration, teleIcare_plant, active): + declared_plant = DeclaredPlant( + declaration=declaration, + plant=Plant.objects.get(siccrf_id=teleIcare_plant.plte_ident), + active=active, + quantity=teleIcare_plant.prepa_qte if active else None, + unit=SubstanceUnit.objects.get(siccrf_id=teleIcare_plant.unt_ident) if active else None, + preparation=Preparation.objects.get(siccrf_id=teleIcare_plant.typprep_ident) if active else None, + used_part=PlantPart.objects.get(siccrf_id=teleIcare_plant.pplan_ident) if active else None, + ) + return declared_plant + + +def create_declared_microorganism(declaration, teleIcare_microorganism, active): + declared_microorganism = DeclaredMicroorganism( + declaration=declaration, + microorganism=Microorganism.objects.get(siccrf_id=teleIcare_microorganism.morg_ident), + active=active, + activated=True, # dans TeleIcare, le champ `activated` n'existait pas, les MO inactivés étaient des `ingrédients autres` + strain=teleIcare_microorganism.ingmorg_souche, + quantity=teleIcare_microorganism.ingmorg_quantite_par_djr, + ) + return declared_microorganism + + +def create_declared_ingredient(declaration, teleIcare_ingredient, active): + declared_ingredient = DeclaredIngredient( + declaration=declaration, + ingredient=Ingredient.objects.get(siccrf_id=teleIcare_ingredient.inga_ident), + active=active, + quantity=None, # dans TeleIcare, les ingrédients n'avaient pas de quantité associée + ) + return declared_ingredient + + +def create_computed_substance(declaration, teleIcare_substance): + computed_substance = ComputedSubstance( + declaration=declaration, + substance=Substance.objects.get(siccrf_id=teleIcare_substance.sbsact_ident), + quantity=teleIcare_substance.sbsactdecl_quantite_par_djr, + # le champ de TeleIcare 'sbsact_commentaires' n'est pas repris + ) + return computed_substance + + +@transaction.atomic +def add_product_info_from_teleicare_history(declaration, vrsdecl_ident): + """ + Cette function importe les champs ManyToMany des déclarations, relatifs à l'onglet "Produit" + Il est nécessaire que les objets soient enregistrés en base (et aient obtenu un id) grâce à la fonction + `create_declaration_from_teleicare_history` pour updater leurs champs ManyToMany. + """ + # TODO: other_conditions=conditions_not_recommended, + # TODO: other_effects= + for CA_field_name, struct in MANY_TO_MANY_PRODUCT_MODELS_MATCHING.items(): + # par exemple Declaration.populations + CA_field = getattr(declaration, CA_field_name) + # TODO: utiliser les dataclass ici + pk_field = struct["teleIcare_pk"] + CA_model = struct["CA_model"] + teleIcare_model = struct["teleIcare_model"] + CA_field.set( + [ + CA_model.objects.get(siccrf_id=getattr(TI_object, pk_field)) + for TI_object in (teleIcare_model.objects.filter(vrsdecl_ident=vrsdecl_ident)) + ] + ) + + +@transaction.atomic +def add_composition_from_teleicare_history(declaration, vrsdecl_ident): + """ + Cette function importe les champs ManyToMany des déclarations, relatifs à l'onglet "Composition" + Il est nécessaire que les objets soient enregistrés en base (et aient obtenu un id) grâce à la fonction + `create_declaration_from_teleicare_history` pour updater leurs champs ManyToMany. + """ + bulk_ingredients = {DeclaredPlant: [], DeclaredMicroorganism: [], DeclaredIngredient: [], ComputedSubstance: []} + for ingredient in IcaIngredient.objects.filter(vrsdecl_ident=vrsdecl_ident): + if ingredient.tying_ident == 1: + declared_plant = create_declared_plant( + declaration=declaration, + teleIcare_plant=IcaPreparation.objects.get( + ingr_ident=ingredient.ingr_ident, + ), + active=ingredient.fctingr_ident == 1, + ) + bulk_ingredients[DeclaredPlant].append(declared_plant) + elif ingredient.tying_ident == 2: + declared_microorganism = create_declared_microorganism( + declaration=declaration, + teleIcare_microorganism=IcaMicroOrganisme.objects.get( + ingr_ident=ingredient.ingr_ident, + ), + active=ingredient.fctingr_ident == 1, + ) + bulk_ingredients[DeclaredMicroorganism].append(declared_microorganism) + elif ingredient.tying_ident == 3: + declared_ingredient = create_declared_ingredient( + declaration=declaration, + teleIcare_ingredient=IcaIngredientAutre.objects.get( + ingr_ident=ingredient.ingr_ident, + ), + active=ingredient.fctingr_ident == 1, + ) + bulk_ingredients[DeclaredIngredient].append(declared_ingredient) + # dans TeleIcare les `declared_substances` étaient des ingrédients + # donc on ne rempli pas le champ declaration.declared_substances grâce à l'historique + for teleIcare_substance in IcaSubstanceDeclaree.objects.filter(vrsdecl_ident=vrsdecl_ident): + computed_substance = create_computed_substance( + declaration=declaration, teleIcare_substance=teleIcare_substance + ) + bulk_ingredients[ComputedSubstance].append(computed_substance) + + for model, bulk_of_objects in bulk_ingredients.items(): + model.objects.bulk_create(bulk_of_objects) + def create_declaration_from_teleicare_history(): """ @@ -248,12 +414,8 @@ def create_declaration_from_teleicare_history(): minimum_duration=latest_ica_version_declaration.vrsdecl_durabilite, instructions=latest_ica_version_declaration.vrsdecl_mode_emploi or "", warning=latest_ica_version_declaration.vrsdecl_mise_en_garde or "", - # TODO: ces champs proviennent de tables pas encore importées - # populations= - # conditions_not_recommended= - # other_conditions= - # effects= - # other_effects= + calculated_article=DECLARATION_TYPE_TO_ARTICLE_MAPPING[latest_ica_declaration.tydcl_ident], + # TODO: ces champs sont à importer # address= # postal_code= # city= @@ -266,6 +428,12 @@ def create_declaration_from_teleicare_history(): try: with suppress_autotime(declaration, ["creation_date", "modification_date"]): declaration.save() + add_product_info_from_teleicare_history( + declaration, latest_ica_version_declaration.vrsdecl_ident + ) + add_composition_from_teleicare_history( + declaration, latest_ica_version_declaration.vrsdecl_ident + ) nb_created_declarations += 1 except IntegrityError: # cette Déclaration a déjà été créée diff --git a/data/etl/teleicare_history/sql/company_table_creation.sql b/data/etl/teleicare_history/sql/company_table_creation.sql new file mode 100644 index 000000000..4c7548087 --- /dev/null +++ b/data/etl/teleicare_history/sql/company_table_creation.sql @@ -0,0 +1,43 @@ +-- Le but de ce fichier est de permettre la recréation des tables Teleicare correspondant +-- au modèle de Declaration Compl'Alim + + +-- int int smallint -> integer +-- vachar -> text +-- bit -> boolean +-- datetime -> text (pour une conversion ensuite) + +CREATE TABLE ICA_ETABLISSEMENT ( + ETAB_IDENT integer PRIMARY KEY, + COG_IDENT integer NULL, + ETAB_IDENT_PARENT integer NULL, + PAYS_IDENT integer NOT NULL, + ETAB_SIRET text NULL, + ETAB_NUMERO_TVA_INTRA text NULL, + ETAB_RAISON_SOCIALE text NOT NULL, + ETAB_ENSEIGNE text NULL, + ETAB_ADRE_VILLE text NULL, + ETAB_ADRE_CP text NULL, + ETAB_ADRE_VOIE text NULL, + ETAB_ADRE_COMP text NULL, + ETAB_ADRE_COMP2 text NULL, + ETAB_ADRE_DIST text NULL, + ETAB_TELEPHONE text NULL, + ETAB_FAX text NULL, + ETAB_COURRIEL text NULL, + ETAB_SITE_INTERNET text NULL, + ETAB_ICA_FACONNIER boolean NULL, + ETAB_ICA_FABRICANT boolean NULL, + ETAB_ICA_CONSEIL boolean NULL, + ETAB_ICA_IMPORTATEUR boolean NULL, + ETAB_ICA_INTRODUCTEUR boolean NULL, + ETAB_ICA_DISTRIBUTEUR boolean NULL, + ETAB_ICA_ENSEIGNE text NULL, + ETAB_ADRE_REGION text NULL, + ETAB_DT_AJOUT_IDENT_PARENT text NULL, + ETAB_NUM_ADH_TELE_PROC text NULL, + ETAB_COMMENTAIRE_IDENT_PARENT text NULL, + ETAB_NOM_DOMAINE text NULL, + ETAB_DATE_ADHESION text NULL, + ETAB_NB_COMPTE_AUTORISE integer NOT NULL +); diff --git a/data/etl/teleicare_history/sql/declaration_composition_table_creation.sql b/data/etl/teleicare_history/sql/declaration_composition_table_creation.sql new file mode 100644 index 000000000..8ebb619e3 --- /dev/null +++ b/data/etl/teleicare_history/sql/declaration_composition_table_creation.sql @@ -0,0 +1,44 @@ +CREATE TABLE ICA_INGREDIENT ( + INGR_IDENT integer PRIMARY KEY, + VRSDECL_IDENT integer NOT NULL, + FCTINGR_IDENT integer NOT NULL, + TYING_IDENT integer NOT NULL, + INGR_COMMENTAIRES text NULL +); + + + + +CREATE TABLE ICA_MICRO_ORGANISME ( + INGR_IDENT integer PRIMARY KEY, + MORG_IDENT integer NOT NULL, + INGMORG_SOUCHE text NULL, + INGMORG_QUANTITE_PAR_DJR bigint NULL +); + + + +CREATE TABLE ICA_INGREDIENT_AUTRE ( + INGR_IDENT integer PRIMARY KEY, + INGA_IDENT integer NOT NULL +); + + + +CREATE TABLE ICA_PREPARATION ( + INGR_IDENT integer PRIMARY KEY, + PLTE_IDENT integer NOT NULL, + PPLAN_IDENT integer NULL, + UNT_IDENT integer NULL, + TYPPREP_IDENT integer NULL, + PREPA_QTE float NULL +); + + +CREATE TABLE ICA_SUBSTANCE_DECLAREE( + VRSDECL_IDENT integer NOT NULL, + SBSACT_IDENT integer NOT NULL, + SBSACT_COMMENTAIRES text NULL, + SBSACTDECL_QUANTITE_PAR_DJR float NULL, + PRIMARY KEY (VRSDECL_IDENT, SBSACT_IDENT) +); diff --git a/data/etl/teleicare_history/sql/company_declaration_table_creation.sql b/data/etl/teleicare_history/sql/declaration_table_creation.sql similarity index 71% rename from data/etl/teleicare_history/sql/company_declaration_table_creation.sql rename to data/etl/teleicare_history/sql/declaration_table_creation.sql index 9e5e6bdec..1dfb63054 100644 --- a/data/etl/teleicare_history/sql/company_declaration_table_creation.sql +++ b/data/etl/teleicare_history/sql/declaration_table_creation.sql @@ -1,48 +1,3 @@ --- Le but de ce fichier est de permettre la recréation des tables Teleicare correspondant --- au modèle de Declaration Compl'Alim - - --- int int smallint -> integer --- vachar -> text --- bit -> boolean --- datetime -> text (pour une conversion ensuite) - -CREATE TABLE ICA_ETABLISSEMENT ( - ETAB_IDENT integer PRIMARY KEY, - COG_IDENT integer NULL, - ETAB_IDENT_PARENT integer NULL, - PAYS_IDENT integer NOT NULL, - ETAB_SIRET text NULL, - ETAB_NUMERO_TVA_INTRA text NULL, - ETAB_RAISON_SOCIALE text NOT NULL, - ETAB_ENSEIGNE text NULL, - ETAB_ADRE_VILLE text NULL, - ETAB_ADRE_CP text NULL, - ETAB_ADRE_VOIE text NULL, - ETAB_ADRE_COMP text NULL, - ETAB_ADRE_COMP2 text NULL, - ETAB_ADRE_DIST text NULL, - ETAB_TELEPHONE text NULL, - ETAB_FAX text NULL, - ETAB_COURRIEL text NULL, - ETAB_SITE_INTERNET text NULL, - ETAB_ICA_FACONNIER boolean NULL, - ETAB_ICA_FABRICANT boolean NULL, - ETAB_ICA_CONSEIL boolean NULL, - ETAB_ICA_IMPORTATEUR boolean NULL, - ETAB_ICA_INTRODUCTEUR boolean NULL, - ETAB_ICA_DISTRIBUTEUR boolean NULL, - ETAB_ICA_ENSEIGNE text NULL, - ETAB_ADRE_REGION text NULL, - ETAB_DT_AJOUT_IDENT_PARENT text NULL, - ETAB_NUM_ADH_TELE_PROC text NULL, - ETAB_COMMENTAIRE_IDENT_PARENT text NULL, - ETAB_NOM_DOMAINE text NULL, - ETAB_DATE_ADHESION text NULL, - ETAB_NB_COMPTE_AUTORISE integer NOT NULL -); - - CREATE TABLE ICA_COMPLEMENTALIMENTAIRE ( CPLALIM_IDENT integer PRIMARY KEY, FRMGAL_IDENT integer NULL, @@ -144,3 +99,30 @@ CREATE TABLE ICA_VERSIONDECLARATION ( -- when 1 then 'nouvelle' -- when 2 then 'compléments d'information' -- when 3 then 'observation' + + + +CREATE TABLE ICA_POPULATION_CIBLE_DECLAREE ( + VRSDECL_IDENT integer NOT NULL, + POPCBL_IDENT integer NOT NULL, + VRSPCB_POPCIBLE_AUTRE text NULL, + PRIMARY KEY (VRSDECL_IDENT, POPCBL_IDENT) +); + + + + +CREATE TABLE ICA_POPULATION_RISQUE_DECLAREE ( + VRSDECL_IDENT integer NOT NULL, + POPRS_IDENT integer NOT NULL, + VRSPRS_POPRISQUE_AUTRE text NULL, + PRIMARY KEY (VRSDECL_IDENT, POPRS_IDENT) +); + + +CREATE TABLE ICA_EFFET_DECLARE ( + VRSDECL_IDENT integer NOT NULL, + OBJEFF_IDENT integer NOT NULL, + VRS_AUTRE_OBJECTIF text NULL, + PRIMARY KEY (VRSDECL_IDENT, OBJEFF_IDENT) +); diff --git a/data/factories/teleicare_history/__init__.py b/data/factories/teleicare_history/__init__.py index a446b86cd..932a8a042 100644 --- a/data/factories/teleicare_history/__init__.py +++ b/data/factories/teleicare_history/__init__.py @@ -68,7 +68,8 @@ class Meta: dcl_ident = factory.Sequence(lambda n: n + 1) cplalim = factory.SubFactory(ComplementAlimentaireFactory) - tydcl_ident = factory.Faker("pyint", min_value=0, max_value=20) + # 3 valeurs possibles dans TeleIcare {1: "Article 15", 2: "Article 16", 3: "Simplifiée"} + tydcl_ident = factory.Faker("pyint", min_value=1, max_value=3) etab = factory.SubFactory(EtablissementFactory) etab_ident_rmm_declarant = factory.Faker("pyint", min_value=0, max_value=20) dcl_date = datetime.strftime(random_date(start=datetime(2016, 1, 1)), "%m/%d/%Y %H:%M:%S %p") diff --git a/data/migrations/0118_icaeffetdeclare_icapopulationcibledeclaree_and_more.py b/data/migrations/0118_icaeffetdeclare_icapopulationcibledeclaree_and_more.py new file mode 100644 index 000000000..792d87e52 --- /dev/null +++ b/data/migrations/0118_icaeffetdeclare_icapopulationcibledeclaree_and_more.py @@ -0,0 +1,49 @@ +# Generated by Django 5.1.5 on 2025-01-24 09:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('data', '0117_remove_blogpost_body'), + ] + + operations = [ + migrations.CreateModel( + name='IcaEffetDeclare', + fields=[ + ('vrsdecl_ident', models.IntegerField(primary_key=True, serialize=False)), + ('objeff_ident', models.IntegerField()), + ('vrs_autre_objectif', models.TextField(blank=True, null=True)), + ], + options={ + 'db_table': 'ica_effet_declare', + 'managed': False, + }, + ), + migrations.CreateModel( + name='IcaPopulationCibleDeclaree', + fields=[ + ('vrsdecl_ident', models.IntegerField(primary_key=True, serialize=False)), + ('popcbl_ident', models.IntegerField()), + ('vrspcb_popcible_autre', models.TextField(blank=True, null=True)), + ], + options={ + 'db_table': 'ica_population_cible_declaree', + 'managed': False, + }, + ), + migrations.CreateModel( + name='IcaPopulationRisqueDeclaree', + fields=[ + ('vrsdecl_ident', models.IntegerField(primary_key=True, serialize=False)), + ('poprs_ident', models.IntegerField()), + ('vrsprs_poprisque_autre', models.TextField(blank=True, null=True)), + ], + options={ + 'db_table': 'ica_population_risque_declaree', + 'managed': False, + }, + ), + ] diff --git a/data/migrations/0119_merge_20250128_1101.py b/data/migrations/0119_merge_20250128_1101.py new file mode 100644 index 000000000..897e484c3 --- /dev/null +++ b/data/migrations/0119_merge_20250128_1101.py @@ -0,0 +1,14 @@ +# Generated by Django 5.1.5 on 2025-01-28 10:01 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('data', '0118_icaeffetdeclare_icapopulationcibledeclaree_and_more'), + ('data', '0118_rename_overriden_article_declaration_overridden_article_and_more'), + ] + + operations = [ + ] diff --git a/data/models/teleicare_history/ica_declaration.py b/data/models/teleicare_history/ica_declaration.py index f235b3099..b6bc813bf 100644 --- a/data/models/teleicare_history/ica_declaration.py +++ b/data/models/teleicare_history/ica_declaration.py @@ -35,13 +35,14 @@ class IcaDeclaration(models.Model): # dcl_ident et cplalim_ident ne sont pas égaux dcl_ident = models.IntegerField(primary_key=True) cplalim = models.ForeignKey(IcaComplementAlimentaire, on_delete=models.CASCADE, db_column="cplalim_ident") - tydcl_ident = models.IntegerField() + tydcl_ident = models.IntegerField() # Article 15 ou 16 etab = models.ForeignKey( IcaEtablissement, on_delete=models.CASCADE, db_column="etab_ident" ) # correspond à l'entreprise gestionnaire de la déclaration etab_ident_rmm_declarant = models.IntegerField() dcl_date = models.TextField() dcl_saisie_administration = models.BooleanField(null=True) # rendu nullable pour simplifier les Factories + # l'identifiant Teleicare est constitué ainsi {dcl_annee}-{dcl_mois}-{dcl_numero} dcl_annee = models.IntegerField(null=True) # rendu nullable pour simplifier les Factories dcl_mois = models.IntegerField(null=True) # rendu nullable pour simplifier les Factories dcl_numero = models.IntegerField(null=True) # rendu nullable pour simplifier les Factories @@ -55,7 +56,8 @@ class Meta: class IcaVersionDeclaration(models.Model): vrsdecl_ident = models.IntegerField(primary_key=True) ag_ident = models.IntegerField(blank=True, null=True) - typvrs_ident = models.IntegerField(null=True) # rendu nullable pour simplifier les Factories + typvrs_ident = models.IntegerField(null=True) # 1: Nouvelle 2: Complément d'information 3: Observations + # rendu nullable pour simplifier les Factories unt_ident = models.IntegerField(blank=True, null=True) pays_ident_adre = models.IntegerField(blank=True, null=True) etab = models.ForeignKey( @@ -95,3 +97,36 @@ class IcaVersionDeclaration(models.Model): class Meta: managed = False db_table = "ica_versiondeclaration" + + +class IcaPopulationCibleDeclaree(models.Model): + vrsdecl_ident = models.IntegerField() + popcbl_ident = models.IntegerField() + vrspcb_popcible_autre = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = "ica_population_cible_declaree" + unique_together = (("vrsdecl_ident", "popcbl_ident"),) + + +class IcaPopulationRisqueDeclaree(models.Model): + vrsdecl_ident = models.IntegerField() + poprs_ident = models.IntegerField() + vrsprs_poprisque_autre = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = "ica_population_risque_declaree" + unique_together = (("vrsdecl_ident", "poprs_ident"),) + + +class IcaEffetDeclare(models.Model): + vrsdecl_ident = models.IntegerField() + objeff_ident = models.IntegerField() + vrs_autre_objectif = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = "ica_effet_declare" + unique_together = (("vrsdecl_ident", "objeff_ident"),) diff --git a/data/models/teleicare_history/ica_declaration_composition.py b/data/models/teleicare_history/ica_declaration_composition.py new file mode 100644 index 000000000..1fbd4ec0d --- /dev/null +++ b/data/models/teleicare_history/ica_declaration_composition.py @@ -0,0 +1,64 @@ +# This is an auto-generated Django model module. +# Feel free to rename the models, but don't rename db_table values or field names. +# Pour plus de simplicité, le nom de ces modèles suivent le nom de la table de données provenant du SICCRF, +# initialement stockée dans un système MSSQL, +# et non la nomenclature habituellement utilisée par Compl'Alim + +from django.db import models + + +class IcaIngredient(models.Model): + ingr_ident = models.IntegerField(primary_key=True) + vrsdecl_ident = models.IntegerField() + fctingr_ident = models.IntegerField() + tying_ident = models.IntegerField() + ingr_commentaires = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = "ica_ingredient" + + +class IcaIngredientAutre(models.Model): + ingr_ident = models.IntegerField(primary_key=True) + inga_ident = models.IntegerField() + + class Meta: + managed = False + db_table = "ica_ingredient_autre" + + +class IcaMicroOrganisme(models.Model): + ingr_ident = models.IntegerField(primary_key=True) + morg_ident = models.IntegerField() + ingmorg_souche = models.TextField(blank=True, null=True) + ingmorg_quantite_par_djr = models.BigIntegerField(blank=True, null=True) + + class Meta: + managed = False + db_table = "ica_micro_organisme" + + +class IcaPreparation(models.Model): + ingr_ident = models.IntegerField(primary_key=True) + plte_ident = models.IntegerField() + pplan_ident = models.IntegerField(blank=True, null=True) + unt_ident = models.IntegerField(blank=True, null=True) + typprep_ident = models.IntegerField(blank=True, null=True) + prepa_qte = models.FloatField(blank=True, null=True) + + class Meta: + managed = False + db_table = "ica_preparation" + + +class IcaSubstanceDeclaree(models.Model): + vrsdecl_ident = models.IntegerField() + sbsact_ident = models.IntegerField() + sbsact_commentaires = models.TextField(blank=True, null=True) + sbsactdecl_quantite_par_djr = models.FloatField(blank=True, null=True) + + class Meta: + managed = False + db_table = "ica_substance_declaree" + unique_together = (("vrsdecl_ident", "sbsact_ident"),) diff --git a/data/tests/test_teleicare_history_importer.py b/data/tests/test_teleicare_history_importer.py index e3d0e4909..81a17121d 100644 --- a/data/tests/test_teleicare_history_importer.py +++ b/data/tests/test_teleicare_history_importer.py @@ -123,7 +123,9 @@ def test_create_new_companies(self): self.assertEqual(created_company.postal_code, etablissement_to_create_as_company.etab_adre_cp) self.assertEqual(created_company.city, etablissement_to_create_as_company.etab_adre_ville) - def test_create_declaration_from_history(self): + @patch("data.etl.teleicare_history.extractor.add_composition_from_teleicare_history") + @patch("data.etl.teleicare_history.extractor.add_product_info_from_teleicare_history") + def test_create_declaration_from_history(self, mocked_add_composition_function, mocked_add_product_function): """ Les déclarations sont créées à partir d'object historiques des modèles Ica_ """ @@ -136,7 +138,7 @@ def test_create_declaration_from_history(self): CA_to_create_as_declaration = ComplementAlimentaireFactory( etab=etablissement_to_create_as_company, frmgal_ident=galenic_formulation_id ) - declaration_to_create_as_declaration = DeclarationFactory(cplalim=CA_to_create_as_declaration) + declaration_to_create_as_declaration = DeclarationFactory(cplalim=CA_to_create_as_declaration, tydcl_ident=1) version_declaration_to_create_as_declaration = VersionDeclarationFactory( dcl=declaration_to_create_as_declaration, stadcl_ident=8, @@ -157,6 +159,7 @@ def test_create_declaration_from_history(self): self.assertEqual(created_declaration.galenic_formulation, galenic_formulation) self.assertEqual(created_declaration.unit_quantity, 32) self.assertEqual(created_declaration.unit_measurement, unit) + self.assertEqual(created_declaration.article, Declaration.Article.ARTICLE_15) self.assertEqual( created_declaration.conditioning, version_declaration_to_create_as_declaration.vrsdecl_conditionnement ) @@ -165,5 +168,6 @@ def test_create_declaration_from_history(self): str(version_declaration_to_create_as_declaration.vrsdecl_poids_uc), ) self.assertEqual( - created_declaration.minimum_duration, str(version_declaration_to_create_as_declaration.vrsdecl_durabilite) + created_declaration.minimum_duration, + str(version_declaration_to_create_as_declaration.vrsdecl_durabilite), )