diff --git a/backend/geonature/core/gn_synthese/imports/actions.py b/backend/geonature/core/gn_synthese/imports/actions.py
index 6b8b7d356f..55e4350acb 100644
--- a/backend/geonature/core/gn_synthese/imports/actions.py
+++ b/backend/geonature/core/gn_synthese/imports/actions.py
@@ -89,6 +89,7 @@ def check_transient_data(task, logger, imprt: TImports):
field_name: fields[field_name]
for field_name, source_field in imprt.fieldmapping.items()
if source_field.get("column_src", None) in imprt.columns
+ or source_field.get("default_value", None) is not None
}
init_rows_validity(imprt)
task.update_state(state="PROGRESS", meta={"progress": 0.05})
@@ -246,7 +247,6 @@ def update_batch_progress(batch, step):
entity,
fields["id_nomenclature_blurring"],
fields["id_dataset"],
- fields["unique_dataset_id"],
)
if current_app.config["IMPORT"]["CHECK_REF_BIBLIO_LITTERATURE"]:
check_nomenclature_source_status(
@@ -276,15 +276,18 @@ def update_batch_progress(batch, step):
if "unique_id_sinp" in selected_fields:
check_duplicate_uuid(imprt, entity, selected_fields["unique_id_sinp"])
if current_app.config["IMPORT"]["PER_DATASET_UUID_CHECK"]:
- whereclause = Synthese.id_dataset == imprt.id_dataset
+ check_existing_uuid(
+ imprt,
+ entity,
+ selected_fields["unique_id_sinp"],
+ id_dataset_field=fields["id_dataset"],
+ )
else:
- whereclause = sa.true()
- check_existing_uuid(
- imprt,
- entity,
- selected_fields["unique_id_sinp"],
- whereclause=whereclause,
- )
+ check_existing_uuid(
+ imprt,
+ entity,
+ selected_fields["unique_id_sinp"],
+ )
if imprt.fieldmapping.get(
"unique_id_sinp_generate",
current_app.config["IMPORT"]["DEFAULT_GENERATE_MISSING_UUID"],
@@ -334,6 +337,7 @@ def import_data_to_destination(imprt: TImports) -> None:
fields["the_geom_local"],
fields["the_geom_point"],
fields["id_area_attachment"], # XXX sure?
+ fields["id_dataset"],
}
if imprt.fieldmapping.get(
"unique_id_sinp_generate",
@@ -358,14 +362,11 @@ def import_data_to_destination(imprt: TImports) -> None:
):
insert_fields |= {field}
- insert_fields -= {fields["unique_dataset_id"]} # Column only used for filling `id_dataset`
-
select_stmt = (
sa.select(
*[transient_table.c[field.dest_field] for field in insert_fields],
sa.literal(source.id_source),
sa.literal(source.module.id_module),
- sa.literal(imprt.id_dataset),
sa.literal(imprt.id_import),
sa.literal("I"),
)
@@ -375,7 +376,6 @@ def import_data_to_destination(imprt: TImports) -> None:
names = [field.dest_field for field in insert_fields] + [
"id_source",
"id_module",
- "id_dataset",
"id_import",
"last_action",
]
diff --git a/backend/geonature/core/imports/checks/dataframe/cast.py b/backend/geonature/core/imports/checks/dataframe/cast.py
index d946f754c3..72ad16cec0 100644
--- a/backend/geonature/core/imports/checks/dataframe/cast.py
+++ b/backend/geonature/core/imports/checks/dataframe/cast.py
@@ -74,6 +74,14 @@ def convert_to_uuid(value):
return None
+def is_valid_uuid(value):
+ try:
+ uuid_obj = UUID(value)
+ except Exception as e:
+ return False
+ return str(uuid_obj) == value
+
+
def convert_to_integer(value):
try:
return int(value)
diff --git a/backend/geonature/core/imports/checks/dataframe/core.py b/backend/geonature/core/imports/checks/dataframe/core.py
index f20c1f6b14..bf9d15cfb6 100644
--- a/backend/geonature/core/imports/checks/dataframe/core.py
+++ b/backend/geonature/core/imports/checks/dataframe/core.py
@@ -12,7 +12,7 @@
from geonature.core.imports.models import BibFields, TImports
from .utils import dataframe_check, error_replace
-
+from .cast import is_valid_uuid
__all__ = ["check_required_values", "check_counts", "check_datasets"]
@@ -194,7 +194,7 @@ def check_datasets(
) -> Set[str]:
"""
Check if datasets exist and are authorized for the user and import.
-
+ It also fill the id_field based on the content of uuid_field
Parameters
----------
imprt : TImports
@@ -222,72 +222,86 @@ def check_datasets(
"""
updated_cols = set()
- uuid_col = uuid_field.dest_field
- id_col = id_field.dest_field
+ uuid_col = uuid_field.source_column
+ uuid = df[uuid_col].unique().tolist()
+
+ # check uuid format
+ valid_uuid_mask = df[uuid_col].apply(lambda x: is_valid_uuid(x))
+ invalid_uuid_mask = ~valid_uuid_mask
+ if invalid_uuid_mask.any():
+ yield {
+ "error_code": ImportCodeError.INVALID_UUID,
+ "column": uuid_field.name_field,
+ "invalid_rows": df[invalid_uuid_mask],
+ }
- if uuid_col in df:
- has_uuid_mask = df[uuid_col].notnull()
- uuid = df.loc[has_uuid_mask, uuid_col].unique().tolist()
+ filtered_ds_mask = valid_uuid_mask
+ uuid = df[filtered_ds_mask][uuid_col].unique().tolist()
- datasets = {
- ds.unique_dataset_id.hex: ds
- for ds in TDatasets.query.filter(TDatasets.unique_dataset_id.in_(uuid))
- .options(sa.orm.joinedload(TDatasets.nomenclature_data_origin))
- .options(sa.orm.raiseload("*"))
- .all()
+ # check dataset existance
+ datasets = {
+ str(ds.unique_dataset_id): ds
+ for ds in TDatasets.query.filter(TDatasets.unique_dataset_id.in_(uuid))
+ .options(sa.orm.joinedload(TDatasets.nomenclature_data_origin))
+ .options(sa.orm.raiseload("*"))
+ .all()
+ }
+ valid_ds_mask = df[uuid_col].isin(datasets.keys())
+ invalid_ds_mask = ~valid_ds_mask & filtered_ds_mask
+ if invalid_ds_mask.any():
+ yield {
+ "error_code": ImportCodeError.DATASET_NOT_FOUND,
+ "column": uuid_field.name_field,
+ "invalid_rows": df[invalid_ds_mask],
}
- valid_ds_mask = df[uuid_col].isin(datasets.keys())
- invalid_ds_mask = has_uuid_mask & ~valid_ds_mask
- if invalid_ds_mask.any():
- yield {
- "error_code": ImportCodeError.DATASET_NOT_FOUND,
- "column": uuid_field.name_field,
- "invalid_rows": df[invalid_ds_mask],
- }
-
- inactive_dataset = [uuid for uuid, ds in datasets.items() if not ds.active]
- inactive_dataset_mask = df[uuid_col].isin(inactive_dataset)
- if inactive_dataset_mask.any():
- yield {
- "error_code": ImportCodeError.DATASET_NOT_ACTIVE,
- "column": uuid_field.name_field,
- "invalid_rows": df[inactive_dataset_mask],
- }
-
- # Warning: we check only permissions of first author, but currently there it only one author per import.
- authorized_datasets = {
- ds.unique_dataset_id.hex: ds
- for ds in db.session.execute(
- TDatasets.filter_by_creatable(
- user=imprt.authors[0], module_code=module_code, object_code=object_code
- )
- .where(TDatasets.unique_dataset_id.in_(uuid))
- .options(sa.orm.raiseload("*"))
- )
- .scalars()
- .all()
+
+ filtered_ds_mask = filtered_ds_mask & valid_ds_mask
+ uuid = df[filtered_ds_mask][uuid_col].unique().tolist()
+
+ # check dataset active status
+ active_ds = [uuid for uuid, ds in datasets.items() if ds.active]
+ active_ds_mask = df[uuid_col].isin(active_ds)
+ inactive_ds_mask = ~active_ds_mask & filtered_ds_mask
+
+ if inactive_ds_mask.any():
+ yield {
+ "error_code": ImportCodeError.DATASET_NOT_ACTIVE,
+ "column": uuid_field.name_field,
+ "invalid_rows": df[inactive_ds_mask],
}
- authorized_ds_mask = df[uuid_col].isin(authorized_datasets.keys())
- unauthorized_ds_mask = valid_ds_mask & ~authorized_ds_mask
- if unauthorized_ds_mask.any():
- yield {
- "error_code": ImportCodeError.DATASET_NOT_AUTHORIZED,
- "column": uuid_field.name_field,
- "invalid_rows": df[unauthorized_ds_mask],
- }
-
- if authorized_ds_mask.any():
- df.loc[authorized_ds_mask, id_col] = df[authorized_ds_mask][uuid_col].apply(
- lambda uuid: authorized_datasets[uuid].id_dataset
+ filtered_ds_mask = filtered_ds_mask & active_ds_mask
+ uuid = df[filtered_ds_mask][uuid_col].unique().tolist()
+
+ # check dataset authorized
+ # Warning: we check only permissions of first author, but currently there it only one author per import.
+ authorized_datasets = {
+ str(ds.unique_dataset_id): ds
+ for ds in db.session.execute(
+ TDatasets.filter_by_creatable(
+ user=imprt.authors[0], module_code=module_code, object_code=object_code
)
- updated_cols = {id_col}
-
- else:
- has_uuid_mask = pd.Series(False, index=df.index)
+ .where(TDatasets.unique_dataset_id.in_(uuid))
+ .options(sa.orm.raiseload("*"))
+ )
+ .scalars()
+ .all()
+ }
+ authorized_ds_mask = active_ds_mask & df[uuid_col].isin(authorized_datasets.keys())
+ unauthorized_ds_mask = ~authorized_ds_mask & filtered_ds_mask
+ if unauthorized_ds_mask.any():
+ yield {
+ "error_code": ImportCodeError.DATASET_NOT_AUTHORIZED,
+ "column": uuid_field.name_field,
+ "invalid_rows": df[unauthorized_ds_mask],
+ }
+ filtered_ds_mask = filtered_ds_mask & authorized_ds_mask
- if (~has_uuid_mask).any():
- # Set id_dataset from import for empty cells:
- df.loc[~has_uuid_mask, id_col] = imprt.id_dataset
+ # compute id_col based on uuid_col
+ if filtered_ds_mask.any():
+ id_col = id_field.dest_field
+ df.loc[filtered_ds_mask, id_col] = df[filtered_ds_mask][uuid_col].apply(
+ lambda uuid: authorized_datasets[uuid].id_dataset
+ )
updated_cols = {id_col}
return updated_cols
diff --git a/backend/geonature/core/imports/checks/sql/extra.py b/backend/geonature/core/imports/checks/sql/extra.py
index 80959e5332..750b8deb52 100644
--- a/backend/geonature/core/imports/checks/sql/extra.py
+++ b/backend/geonature/core/imports/checks/sql/extra.py
@@ -241,7 +241,7 @@ def check_existing_uuid(
imprt: TImports,
entity: Entity,
uuid_field: BibFields,
- whereclause: Any = sa.true(),
+ id_dataset_field: BibFields = None,
skip=False,
):
"""
@@ -254,25 +254,34 @@ def check_existing_uuid(
entity : Entity
The entity to check.
uuid_field : BibFields
- The field to check.
- whereclause : BooleanClause
- The WHERE clause to apply to the check.
+ The field to check
+ id_dataset_field : BibFields
+ if defnied, the uuid existence is checked for the given dataset. Otherwise, it is checked globally
+
skip: Boolean
Raise SKIP_EXISTING_UUID instead of EXISTING_UUID and set row validity to None (do not import)
"""
transient_table = imprt.destination.get_transient_table()
dest_table = entity.get_destination_table()
error_type = "SKIP_EXISTING_UUID" if skip else "EXISTING_UUID"
+
+ whereclause = sa.and_(
+ transient_table.c[uuid_field.dest_field] == dest_table.c[uuid_field.dest_field],
+ transient_table.c[entity.validity_column].is_(True),
+ )
+
+ if id_dataset_field:
+ whereclause = whereclause & (
+ transient_table.c[id_dataset_field.dest_field]
+ == dest_table.c[id_dataset_field.dest_field]
+ )
+
report_erroneous_rows(
imprt,
entity,
error_type=error_type,
error_column=uuid_field.name_field,
- whereclause=sa.and_(
- transient_table.c[uuid_field.dest_field] == dest_table.c[uuid_field.dest_field],
- transient_table.c[entity.validity_column].is_(True),
- whereclause,
- ),
+ whereclause=whereclause,
level_validity_mapping={"ERROR": False, "WARNING": None},
)
diff --git a/backend/geonature/core/imports/checks/sql/nomenclature.py b/backend/geonature/core/imports/checks/sql/nomenclature.py
index 83b2b8e32c..c8ffa5a6dc 100644
--- a/backend/geonature/core/imports/checks/sql/nomenclature.py
+++ b/backend/geonature/core/imports/checks/sql/nomenclature.py
@@ -176,9 +176,7 @@ def check_nomenclature_exist_proof(
)
-def check_nomenclature_blurring(
- imprt, entity, blurring_field, id_dataset_field, uuid_dataset_field
-):
+def check_nomenclature_blurring(imprt, entity, blurring_field, id_dataset_field):
"""
Raise an error if blurring not set.
Required if the dataset is private.
@@ -196,10 +194,7 @@ def check_nomenclature_blurring(
error_type=ImportCodeError.CONDITIONAL_MANDATORY_FIELD_ERROR,
error_column=blurring_field.name_field,
whereclause=sa.and_(
- sa.or_(
- transient_table.c[id_dataset_field.name_field] == TDatasets.id_dataset,
- transient_table.c[uuid_dataset_field.name_field] == TDatasets.unique_dataset_id,
- ),
+ transient_table.c[id_dataset_field.name_field] == TDatasets.id_dataset,
TDatasets.id_nomenclature_data_origin == id_nomenclature_private,
transient_table.c[blurring_field.dest_field] == None,
),
diff --git a/backend/geonature/core/imports/config_schema.py b/backend/geonature/core/imports/config_schema.py
index 2a77982e3f..5b5164b670 100644
--- a/backend/geonature/core/imports/config_schema.py
+++ b/backend/geonature/core/imports/config_schema.py
@@ -18,12 +18,6 @@
"show": True,
"filter": True,
},
- {
- "prop": "dataset.dataset_name",
- "name": "Jeu de données",
- "show": True,
- "filter": False,
- },
{
"prop": "statistics_rows",
"name": "Lignes importées",
diff --git a/backend/geonature/core/imports/models.py b/backend/geonature/core/imports/models.py
index 3e2b599141..8e71a03000 100644
--- a/backend/geonature/core/imports/models.py
+++ b/backend/geonature/core/imports/models.py
@@ -29,7 +29,6 @@
from geonature.utils.celery import celery_app
from geonature.core.gn_permissions.tools import get_scopes_by_action
from geonature.core.gn_commons.models import TModules
-from geonature.core.gn_meta.models import TDatasets
from pypnnomenclature.models import BibNomenclaturesTypes
from pypnusershub.db.models import User
@@ -319,8 +318,6 @@ def get_instance_permissions(self, scopes, user=None):
@serializable(
fields=[
"authors.nom_complet",
- "dataset.dataset_name",
- "dataset.active",
"destination.code",
"destination.label",
"destination.statistics_labels",
@@ -352,7 +349,6 @@ class TImports(InstancePermissionMixin, db.Model):
detected_encoding = db.Column(db.Unicode, nullable=True)
# import_table = db.Column(db.Unicode, nullable=True)
full_file_name = db.Column(db.Unicode, nullable=True)
- id_dataset = db.Column(db.Integer, ForeignKey("gn_meta.t_datasets.id_dataset"), nullable=True)
date_create_import = db.Column(db.DateTime, default=datetime.now)
date_update_import = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
date_end_import = db.Column(db.DateTime, nullable=True)
@@ -372,7 +368,6 @@ class TImports(InstancePermissionMixin, db.Model):
)
loaded = db.Column(db.Boolean, nullable=False, default=False)
processed = db.Column(db.Boolean, nullable=False, default=False)
- dataset = db.relationship(TDatasets, lazy="joined")
source_file = deferred(db.Column(db.LargeBinary))
columns = db.Column(ARRAY(db.Unicode))
# keys are target names, values are source names
diff --git a/backend/geonature/core/imports/routes/imports.py b/backend/geonature/core/imports/routes/imports.py
index 92b1dbb819..63840f373b 100644
--- a/backend/geonature/core/imports/routes/imports.py
+++ b/backend/geonature/core/imports/routes/imports.py
@@ -23,7 +23,6 @@
from geonature.core.gn_permissions import decorators as permissions
from geonature.core.gn_permissions.decorators import login_required
from geonature.core.gn_permissions.tools import get_scopes_by_action
-from geonature.core.gn_meta.models import TDatasets
from pypnnomenclature.models import TNomenclatures
@@ -85,11 +84,6 @@ def get_import_list(scope, destination=None):
filters = []
if search:
filters.append(TImports.full_file_name.ilike(f"%{search}%"))
- filters.append(
- TImports.dataset.has(
- func.lower(TDatasets.dataset_name).contains(func.lower(search)),
- )
- )
filters.append(
TImports.authors.any(
or_(
@@ -114,11 +108,9 @@ def get_import_list(scope, destination=None):
query = (
select(TImports)
.options(
- contains_eager(TImports.dataset),
contains_eager(TImports.authors),
contains_eager(TImports.destination).contains_eager(Destination.module),
)
- .join(TImports.dataset, isouter=True)
.join(TImports.authors, isouter=True)
.join(Destination)
.join(TModules)
@@ -165,13 +157,10 @@ def upload_file(scope, imprt, destination=None): # destination is set when impr
Add an import or update an existing import.
:form file: file to import
- :form int datasetId: dataset ID to which import data
"""
if imprt:
if not imprt.has_instance_permission(scope, action_code="C"):
raise Forbidden
- if not imprt.dataset.active:
- raise Forbidden("Le jeu de données est fermé.")
destination = imprt.destination
else:
assert destination
@@ -187,22 +176,7 @@ def upload_file(scope, imprt, destination=None): # destination is set when impr
if size == 0:
raise BadRequest(description="Impossible to upload empty files")
if imprt is None:
- try:
- dataset_id = int(request.form["datasetId"])
- except ValueError:
- raise BadRequest(description="'datasetId' must be an integer.")
- dataset = db.session.get(TDatasets, dataset_id)
- if dataset is None:
- raise BadRequest(description=f"Dataset '{dataset_id}' does not exist.")
- ds_scope = get_scopes_by_action(
- module_code=destination.module.module_code,
- object_code="ALL", # TODO object_code should be configurable by destination
- )["C"]
- if not dataset.has_instance_permission(ds_scope):
- raise Forbidden(description="Vous n’avez pas les permissions sur ce jeu de données.")
- if not dataset.active:
- raise Forbidden("Le jeu de données est fermé.")
- imprt = TImports(destination=destination, dataset=dataset)
+ imprt = TImports(destination=destination)
imprt.authors.append(author)
db.session.add(imprt)
else:
@@ -226,8 +200,6 @@ def upload_file(scope, imprt, destination=None): # destination is set when impr
def decode_file(scope, imprt):
if not imprt.has_instance_permission(scope, action_code="C"):
raise Forbidden
- if not imprt.dataset.active:
- raise Forbidden("Le jeu de données est fermé.")
if imprt.source_file is None:
raise BadRequest(description="A file must be first uploaded.")
if "encoding" not in request.json:
@@ -292,8 +264,6 @@ def decode_file(scope, imprt):
def set_import_field_mapping(scope, imprt):
if not imprt.has_instance_permission(scope, action_code="C"):
raise Forbidden
- if not imprt.dataset.active:
- raise Forbidden("Le jeu de données est fermé.")
try:
FieldMapping.validate_values(request.json)
except ValueError as e:
@@ -309,8 +279,6 @@ def set_import_field_mapping(scope, imprt):
def load_import(scope, imprt):
if not imprt.has_instance_permission(scope, action_code="C"):
raise Forbidden
- if not imprt.dataset.active:
- raise Forbidden("Le jeu de données est fermé.")
if imprt.source_file is None:
raise BadRequest(description="A file must be first uploaded.")
if imprt.fieldmapping is None:
@@ -404,8 +372,6 @@ def get_import_values(scope, imprt):
def set_import_content_mapping(scope, imprt):
if not imprt.has_instance_permission(scope, action_code="C"):
raise Forbidden
- if not imprt.dataset.active:
- raise Forbidden("Le jeu de données est fermé.")
try:
ContentMapping.validate_values(request.json)
except ValueError as e:
@@ -424,8 +390,6 @@ def prepare_import(scope, imprt):
"""
if not imprt.has_instance_permission(scope, action_code="C"):
raise Forbidden
- if not imprt.dataset.active:
- raise Forbidden("Le jeu de données est fermé.")
# Check preconditions to execute this action
if not imprt.loaded:
@@ -627,8 +591,6 @@ def import_valid_data(scope, imprt):
"""
if not imprt.has_instance_permission(scope, action_code="C"):
raise Forbidden
- if not imprt.dataset.active:
- raise Forbidden("Le jeu de données est fermé.")
if not imprt.processed:
raise Forbidden("L’import n’a pas été préalablement vérifié.")
transient_table = imprt.destination.get_transient_table()
@@ -662,8 +624,6 @@ def delete_import(scope, imprt):
"""
if not imprt.has_instance_permission(scope, action_code="C"):
raise Forbidden
- if not imprt.dataset.active:
- raise Forbidden("Le jeu de données est fermé.")
ImportUserError.query.filter_by(imprt=imprt).delete()
transient_table = imprt.destination.get_transient_table()
db.session.execute(
diff --git a/backend/geonature/core/imports/templates/import_template_pdf.html b/backend/geonature/core/imports/templates/import_template_pdf.html
index 467849f33b..093034fb4b 100644
--- a/backend/geonature/core/imports/templates/import_template_pdf.html
+++ b/backend/geonature/core/imports/templates/import_template_pdf.html
@@ -47,9 +47,6 @@
{% endfor %}
- {% if data.dataset: %}
- Jeu de données : {{ data.dataset.dataset_name }}
- {% endif %}
{% if data.keywords: %}
@@ -74,7 +71,7 @@
{% endif %}
-
+
{% if data.date_end_import is not none %}
-
+
{% endif %}
{% if data.processed %}
@@ -137,7 +134,7 @@
-
+
{% endif %}
diff --git a/backend/geonature/migrations/data/imports/sample_data.sql b/backend/geonature/migrations/data/imports/sample_data.sql
index bc81e25297..9bdd365401 100644
--- a/backend/geonature/migrations/data/imports/sample_data.sql
+++ b/backend/geonature/migrations/data/imports/sample_data.sql
@@ -20,6 +20,7 @@ FROM utilisateurs.bib_organismes
WHERE nom_organisme = 'Autre';
-- Step 2: Insert data
INSERT INTO utilisateurs.t_roles (
+ id_role,
groupe,
identifiant,
nom_role,
@@ -34,6 +35,7 @@ INSERT INTO utilisateurs.t_roles (
pass_plus
)
VALUES (
+ 9999,
false,
'admin-test-import',
'Administrateur-test-import',
@@ -49,6 +51,7 @@ VALUES (
'$2y$13$TMuRXgvIg6/aAez0lXLLFu0lyPk4m8N55NDhvLoUHh/Ar3rFzjFT.'
),
(
+ 9998,
false,
'agent-test-import',
'Agent-test-import',
@@ -894,7 +897,6 @@ VALUES (
-- #On peuple la liste d'import
INSERT INTO gn_imports.t_imports (
id_import,
- id_dataset,
id_destination,
format_source_file,
srid,
@@ -914,11 +916,6 @@ INSERT INTO gn_imports.t_imports (
)
VALUES (
1000,
- (
- SELECT id_dataset
- FROM gn_meta.t_datasets
- WHERE unique_dataset_id = '2f543d86-ec4e-4f1a-b4d9-123456789abc'
- ),
(
SELECT id_destination
FROM gn_imports.bib_destinations
@@ -942,11 +939,6 @@ VALUES (
),
(
1001,
- (
- SELECT id_dataset
- FROM gn_meta.t_datasets
- WHERE unique_dataset_id = '9f86d081-8292-466e-9e7b-16f3960d255f'
- ),
(
SELECT id_destination
FROM gn_imports.bib_destinations
@@ -970,11 +962,6 @@ VALUES (
),
(
1002,
- (
- SELECT id_dataset
- FROM gn_meta.t_datasets
- WHERE unique_dataset_id = 'a1b2c3d4-e5f6-4a3b-2c1d-e6f5a4b3c2d1'
- ),
(
SELECT id_destination
FROM gn_imports.bib_destinations
@@ -998,11 +985,6 @@ VALUES (
),
(
1003,
- (
- SELECT id_dataset
- FROM gn_meta.t_datasets
- WHERE unique_dataset_id = '5f45d560-1ce3-420c-b45c-3d589eedaee1'
- ),
(
SELECT id_destination
FROM gn_imports.bib_destinations
@@ -1024,17 +1006,26 @@ VALUES (
NULL,
'{5}'
);
--- On peuple les tables de correspondances - Ajout des roles lié aux imports
-CREATE TEMP TABLE temp_filtered_imports AS
-SELECT ti.id_import,
- ti.id_dataset
-FROM gn_imports.t_imports ti
- JOIN gn_meta.t_datasets td ON ti.id_dataset = td.id_dataset
-WHERE td.dataset_name ILIKE '%JDD-TEST-IMPORT%';
INSERT INTO gn_imports.cor_role_import (id_role, id_import)
-SELECT cda.id_role,
- tfi.id_import
-FROM temp_filtered_imports tfi
- JOIN gn_meta.cor_dataset_actor cda ON tfi.id_dataset = cda.id_dataset
-WHERE cda.id_role IS NOT NULL;
-DROP TABLE temp_filtered_imports;
+VALUES
+ (
+ 9999,
+ 1000
+ ),
+ (
+ 9998,
+ 1000
+ ),
+ (
+ 9999,
+ 1001
+ ),
+ (
+ 9999,
+ 1002
+ ),
+ (
+ 9999,
+ 1003
+ );
+
diff --git a/backend/geonature/migrations/versions/51ee1572f71f_import_monitorings_adjust_gn_imports_.py b/backend/geonature/migrations/versions/51ee1572f71f_import_monitorings_adjust_gn_imports_.py
new file mode 100644
index 0000000000..baa6564ee0
--- /dev/null
+++ b/backend/geonature/migrations/versions/51ee1572f71f_import_monitorings_adjust_gn_imports_.py
@@ -0,0 +1,122 @@
+"""[import.monitorings] Adjust gn.imports bib_fields id_dataset and unique_id_dataset values for synthese destination
+
+Revision ID: 51ee1572f71f
+Revises: df277299fdda
+Create Date: 2025-01-24 16:38:46.007151
+
+"""
+
+from alembic import op
+import sqlalchemy as sa
+
+from geonature.core.imports.models import BibFields, Destination
+from sqlalchemy.dialects.postgresql import UUID
+
+# revision identifiers, used by Alembic.
+revision = "51ee1572f71f"
+down_revision = "df277299fdda"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ op.drop_column(
+ schema="gn_imports", table_name="t_imports_synthese", column_name="unique_dataset_id"
+ )
+
+ op.execute(
+ sa.update(BibFields)
+ .where(
+ BibFields.name_field == "unique_dataset_id",
+ BibFields.id_destination == Destination.id_destination,
+ Destination.code == "synthese",
+ )
+ .values(
+ dict(
+ display=True,
+ mandatory=True,
+ type_field="dataset",
+ type_field_params=dict(bind_value="unique_dataset_id"),
+ source_field="src_unique_dataset_id",
+ dest_field=None,
+ )
+ )
+ )
+
+ op.execute(
+ sa.update(BibFields)
+ .where(
+ BibFields.name_field == "id_dataset",
+ BibFields.id_destination == Destination.id_destination,
+ Destination.code == "synthese",
+ )
+ .values(
+ dict(
+ display=False,
+ type_field="textarea",
+ mandatory=False,
+ dest_field="id_dataset",
+ source_field=None,
+ )
+ )
+ )
+
+ op.execute(
+ """
+ DO $$
+ BEGIN
+ -- Vérifier si la colonne existe dans la table
+ IF EXISTS (SELECT 1
+ FROM information_schema.columns
+ WHERE
+ table_name = 't_imports'
+ AND column_name = 'id_dataset') THEN
+ -- Supprimer la colonne si elle existe
+ ALTER TABLE gn_imports.t_imports DROP COLUMN id_dataset;
+ END IF;
+ END $$;
+ """
+ )
+
+
+def downgrade():
+ op.execute(
+ sa.update(BibFields)
+ .where(
+ BibFields.name_field == "unique_dataset_id",
+ BibFields.id_destination == Destination.id_destination,
+ Destination.code == "synthese",
+ )
+ .values(
+ dict(
+ display=False,
+ mandatory=False,
+ optional_conditions=None,
+ type_field="text",
+ type_field_params=None,
+ dest_field="unique_dataset_id",
+ )
+ )
+ )
+
+ op.execute(
+ sa.update(BibFields)
+ .where(
+ BibFields.name_field == "id_dataset",
+ BibFields.id_destination == Destination.id_destination,
+ Destination.code == "synthese",
+ )
+ .values(dict(dest_field=None))
+ )
+
+ op.add_column(
+ schema="gn_imports",
+ table_name="t_imports",
+ column=sa.Column("id_dataset", sa.INTEGER),
+ )
+
+ op.add_column(
+ schema="gn_imports",
+ table_name="t_imports_synthese",
+ column=sa.Column("unique_dataset_id", UUID(as_uuid=True)),
+ )
diff --git a/backend/geonature/migrations/versions/imports/a81f74d0a518_insert_import_sample_data.py b/backend/geonature/migrations/versions/imports/a81f74d0a518_insert_import_sample_data.py
index 386116d6fa..50c6ac4999 100644
--- a/backend/geonature/migrations/versions/imports/a81f74d0a518_insert_import_sample_data.py
+++ b/backend/geonature/migrations/versions/imports/a81f74d0a518_insert_import_sample_data.py
@@ -31,11 +31,8 @@ def downgrade():
op.execute(
"""
DELETE FROM gn_imports.t_imports
- WHERE id_dataset IN (
- (SELECT id_dataset FROM gn_meta.t_datasets WHERE unique_dataset_id = 'a1b2c3d4-e5f6-4a3b-2c1d-e6f5a4b3c2d1'),
- (SELECT id_dataset FROM gn_meta.t_datasets WHERE unique_dataset_id = '9f86d081-8292-466e-9e7b-16f3960d255f'),
- (SELECT id_dataset FROM gn_meta.t_datasets WHERE unique_dataset_id = '2f543d86-ec4e-4f1a-b4d9-123456789abc'),
- (SELECT id_dataset FROM gn_meta.t_datasets WHERE unique_dataset_id = '5f45d560-1ce3-420c-b45c-3d589eedaee1')
+ WHERE id_import IN (
+ 1000,1001,1002,1003
);
"""
)
@@ -128,29 +125,14 @@ def downgrade():
"""
)
- # Step 1: Create a temporary table to hold the filtered imports
- op.execute(
- """
- CREATE TEMP TABLE temp_filtered_imports AS
- SELECT ti.id_import
- FROM gn_imports.t_imports ti
- JOIN gn_meta.t_datasets td ON ti.id_dataset = td.id_dataset
- WHERE td.dataset_name ILIKE '%JDD-TEST-IMPORT%';
- """
- )
-
- # Step 2: Delete the relevant records from cor_role_import
+ # Delete the relevant records from cor_role_import
op.execute(
"""
DELETE FROM gn_imports.cor_role_import cri
- USING temp_filtered_imports tfi
- WHERE cri.id_import in (tfi.id_import);
+ WHERE cri.id_import in (1000, 1001, 1002, 1003);
"""
)
- # Clean up temporary table
- op.execute("DROP TABLE temp_filtered_imports;")
-
## Clean users test
# Delete permissions for admin-test-import
op.execute(
@@ -164,7 +146,7 @@ def downgrade():
op.execute(
"""
DELETE FROM gn_permissions.t_permissions
- WHERE id_role = (SELECT id_role FROM utilisateurs.t_roles WHERE identifiant = 'agent-test-import');
+ WHERE id_role = (SELECT id_role FROM utilisateurs.t_roles WHERE identifiant = 'agent-test-import');
"""
)
@@ -184,6 +166,23 @@ def downgrade():
"""
)
+ ## Clean Rol Provider
+ # admin-test-import
+ op.execute(
+ """
+ DELETE FROM utilisateurs.cor_role_provider
+ WHERE id_role = (SELECT id_role FROM utilisateurs.t_roles WHERE identifiant = 'admin-test-import');
+ """
+ )
+
+ # agent-test-import
+ op.execute(
+ """
+ DELETE FROM utilisateurs.cor_role_provider
+ WHERE id_role = (SELECT id_role FROM utilisateurs.t_roles WHERE identifiant = 'agent-test-import');
+ """
+ )
+
# Delete the roles
op.execute(
"""
diff --git a/backend/geonature/tests/imports/files/occhab/no_default_uuid.csv b/backend/geonature/tests/imports/files/occhab/no_default_uuid.csv
index 56b632dddb..ccd396e050 100644
--- a/backend/geonature/tests/imports/files/occhab/no_default_uuid.csv
+++ b/backend/geonature/tests/imports/files/occhab/no_default_uuid.csv
@@ -1,9 +1,9 @@
Objectif du test;Erreur station;Erreur habitat;id_station_source;unique_id_sinp_station;unique_dataset_id;date_min;date_max;observers;id_nomenclature_area_surface_calculation;WKT;id_nomenclature_geographic_object;unique_id_sinp_habitat;nom_cite;cd_hab;technical_precision
-Station + habitat sur la même ligne;OK !;OK !;Station 8;afa81c29-c75d-408d-bf48-53cce02d5561;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;4ee53579-b09b-408f-aa1f-d62495a66667;prairie;24;
-Station uniquement;OK !;Pas d’habitat;;9d3fb1bd-6148-45c4-aa13-ff9212155afe;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;;;
-Habitat uniquement dans une station existante en base.;Pas de station;OK !;;EXISTING_STATION_UUID;;;;Toto;;;;05f0163a-ab14-4045-84b9-b513188092ae;prairie;24;
-Habitat uniquement dans une station existante en base, mais l’habitat n’a pas d’UUID alors qu’il n’est pas généré.;Pas de station;MISSING_VALUE(unique_id_sinp_habitat);;EXISTING_STATION_UUID;;;;Toto;;;;;prairie;24;
-Habitat uniquement dans une station existante en base, mais l’UUID est invalide.;Pas de station;INVALID_UUID(unique_id_sinp_habitat);;EXISTING_STATION_UUID;;;;Toto;;;;erroneous;prairie;24;
+Station + habitat sur la même ligne;OK !;OK !;Station 8;afa81c29-c75d-408d-bf48-53cce02d5561;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;4ee53579-b09b-408f-aa1f-d62495a66667;prairie;24;
+Station uniquement;OK !;Pas d’habitat;;9d3fb1bd-6148-45c4-aa13-ff9212155afe;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;;;
+Habitat uniquement dans une station existante en base.;Pas de station;OK !;;@EXISTING_STATION_UUID@;;;;Toto;;;;05f0163a-ab14-4045-84b9-b513188092ae;prairie;24;
+Habitat uniquement dans une station existante en base, mais l’habitat n’a pas d’UUID alors qu’il n’est pas généré.;Pas de station;MISSING_VALUE(unique_id_sinp_habitat);;@EXISTING_STATION_UUID@;;;;Toto;;;;;prairie;24;
+Habitat uniquement dans une station existante en base, mais l’UUID est invalide.;Pas de station;INVALID_UUID(unique_id_sinp_habitat);;@EXISTING_STATION_UUID@;;;;Toto;;;;erroneous;prairie;24;
;;;;;;;;Toto;;;;;;;
;;;;;;;;Toto;;;;;;;
;;;;;;;;Toto;;;;;;;
@@ -11,30 +11,30 @@ Habitat mais pas de station référencée;Pas de station;MISSING_VALUE(unique_id
Uniquement un uuid station, mais on ne sait pas s’il appartient à une station ou s’il sert à indiquer le parent d’un habitat;ORPHAN_ROW(unique_id_sinp_station);ORPHAN_ROW(unique_id_sinp_station);;258a2478-8a0e-4321-83df-c2313ad3040e;;;;Toto;;;;;;;
Uniquement un id station source, mais on ne sait pas s’il appartient à une station ou s’il sert à indiquer le parent d’un habitat;ORPHAN_ROW(id_station_source);ORPHAN_ROW(id_station_source);Station -1;;;;;Toto;;;;;;;
Uniquement UUID station + id station source, mais on ne sait pas s’ils appartiennent à une station ou s’ils servent à indiquer le parent d’un habitat;ORPHAN_ROW(unique_id_sinp_station, id_station_source);ORPHAN_ROW(unique_id_sinp_station,id_station_source);Station -2;54e54935-982b-4da3-9aaf-e87e49a1fdf1;;;;Toto;;;;;;;
-On importe 2 habitats dans une même nouvelle station dont les données sont répétées. Les lignes contenant la station sont rapproché par UUID.;OK !;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;e5e7a184-3e92-4adb-a721-5bd004b3397f;forêt;24;
-;OK !;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;8f52f122-b9ae-45b3-b947-2c9f7934b823;prairie;24;
-On importe 2 habitats dans une même nouvelle station dont les données sont répétées MAIS AVEC DES DIFFÉRENCES (date). Les lignes contenant la station sont rapproché par UUID.;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;17/11/2023;;Toto;;COORD_STATION;St;d91496e9-d904-45a8-9e18-cb8acbbb6ea6;prairie;24;
-;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;18/11/2023;;Toto;;COORD_STATION;St;8b25ede6-b65a-4a85-98d6-0c813bcae3bf;prairie;24;
-On importe 2 habitats dans une même nouvelle station dont les données sont répétées mais avec des différences (date INVALIDE). Les lignes contenant la station sont rapproché par UUID. On vérifie qu’on a pas d’erreur sur la date car les contrôles ne doivent pas être lancé si les données sont incohérentes. En revanche, les contrôles des habitats doivent bien être lancés.;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;17/11/2023;;Toto;;COORD_STATION;St;8235a358-3bc0-4ade-8f60-eb5d9e8ac453;prairie;24;
-NO_PARENT_ENTITY(id_station) non levé sur l’habitat en raison de l’implémentation du check qui ignore les lignes erronées. À voir s’il faut le faire évoluer.;INCOHERENT_DATA(unique_id_sinp_station);INVALID_INTEGER(cd_hab);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;date invalide;;Toto;;COORD_STATION;St;0a53de31-be5a-4ad9-a8f8-511e85d50ace;prairie;invalide;
-On importe 2 habitats dans une même nouvelle station dont les données sont répétées. Les lignes contenant la station sont rapproché par id origine. Mais les UUID ne sont pas spécifier alors au’ils ne sont pas générés.;MISSING_VALUE(unique_id_sinp_station);MISSING_VALUE(unique_id_sinp_station),ERRONEOUS_PARENT_ENTITY;Station 1;;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;d6050c44-88c0-45c6-bb2c-02f7e72f57aa;prairie;24;
-;La station étant dupliqué, elle est ignorée;MISSING_VALUE(unique_id_sinp_station),ERRONEOUS_PARENT_ENTITY;Station 1;;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;f2678b4c-5092-4f6f-902a-b5d21f0d7a88;prairie;24;
-On importe 2 habitats dans une même nouvelle station dont les données sont répétées MAIS AVEC DES DIFFÉRENCES (date). Les lignes contenant la station sont rapproché par id origine.;INCOHERENT_DATA(id_station_source);MISSING_VALUE(unique_id_sinp_station);Station 2;;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;2eba7b82-e987-4ea8-bca8-a34de063db87;prairie;24;
-;INCOHERENT_DATA(id_station_source);MISSING_VALUE(unique_id_sinp_station);Station 2;;;invalide;17/11/2023;Toto;;COORD_STATION;St;c68163bd-b45d-436b-87ce-389ad7f18572;prairie;24;
-Un UUID station invalide lève une erreur sur la station ET sur l’habitat;INVALID_UUID(unique_id_sinp_station);INVALID_UUID(unique_id_sinp_station),ERRONEOUS_PARENT_ENTITY;;Erroneous 1;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;6c02ef80-2e78-4c2c-b8b5-1c75e2349fc2;prairie;24;
-Un UUID station invalide lève une erreur sur la station uniquement si pas d’habitat;INVALID_UUID(unique_id_sinp_station),MISSING_VALUE(date_min);Pas d’habitat;;Erroneous 2;;;17/11/2024;Toto;;COORD_STATION;;;;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées. Les lignes contenant la station sont rapproché par UUID.;OK !;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;e5e7a184-3e92-4adb-a721-5bd004b3397f;forêt;24;
+;OK !;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;8f52f122-b9ae-45b3-b947-2c9f7934b823;prairie;24;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées MAIS AVEC DES DIFFÉRENCES (date). Les lignes contenant la station sont rapproché par UUID.;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;@VALID_DATASET_UUID@;17/11/2023;;Toto;;@COORD_STATION@;St;d91496e9-d904-45a8-9e18-cb8acbbb6ea6;prairie;24;
+;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;@VALID_DATASET_UUID@;18/11/2023;;Toto;;@COORD_STATION@;St;8b25ede6-b65a-4a85-98d6-0c813bcae3bf;prairie;24;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées mais avec des différences (date INVALIDE). Les lignes contenant la station sont rapproché par UUID. On vérifie qu’on a pas d’erreur sur la date car les contrôles ne doivent pas être lancé si les données sont incohérentes. En revanche, les contrôles des habitats doivent bien être lancés.;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;@VALID_DATASET_UUID@;17/11/2023;;Toto;;@COORD_STATION@;St;8235a358-3bc0-4ade-8f60-eb5d9e8ac453;prairie;24;
+NO_PARENT_ENTITY(id_station) non levé sur l’habitat en raison de l’implémentation du check qui ignore les lignes erronées. À voir s’il faut le faire évoluer.;INCOHERENT_DATA(unique_id_sinp_station);INVALID_INTEGER(cd_hab);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;@VALID_DATASET_UUID@;date invalide;;Toto;;@COORD_STATION@;St;0a53de31-be5a-4ad9-a8f8-511e85d50ace;prairie;invalide;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées. Les lignes contenant la station sont rapproché par id origine. Mais les UUID ne sont pas spécifier alors au’ils ne sont pas générés.;MISSING_VALUE(unique_id_sinp_station);MISSING_VALUE(unique_id_sinp_station),ERRONEOUS_PARENT_ENTITY;Station 1;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;d6050c44-88c0-45c6-bb2c-02f7e72f57aa;prairie;24;
+;La station étant dupliqué, elle est ignorée;MISSING_VALUE(unique_id_sinp_station),ERRONEOUS_PARENT_ENTITY;Station 1;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;f2678b4c-5092-4f6f-902a-b5d21f0d7a88;prairie;24;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées MAIS AVEC DES DIFFÉRENCES (date). Les lignes contenant la station sont rapproché par id origine.;INCOHERENT_DATA(id_station_source);MISSING_VALUE(unique_id_sinp_station);Station 2;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;2eba7b82-e987-4ea8-bca8-a34de063db87;prairie;24;
+;INCOHERENT_DATA(id_station_source);MISSING_VALUE(unique_id_sinp_station);Station 2;;@VALID_DATASET_UUID@;invalide;17/11/2023;Toto;;@COORD_STATION@;St;c68163bd-b45d-436b-87ce-389ad7f18572;prairie;24;
+Un UUID station invalide lève une erreur sur la station ET sur l’habitat;INVALID_UUID(unique_id_sinp_station);INVALID_UUID(unique_id_sinp_station),ERRONEOUS_PARENT_ENTITY;;Erroneous 1;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;6c02ef80-2e78-4c2c-b8b5-1c75e2349fc2;prairie;24;
+Un UUID station invalide lève une erreur sur la station uniquement si pas d’habitat;INVALID_UUID(unique_id_sinp_station),MISSING_VALUE(date_min);Pas d’habitat;;Erroneous 2;@VALID_DATASET_UUID@;;17/11/2024;Toto;;@COORD_STATION@;;;;;
Un UUID station invalide lève une erreur sur l’habitat uniquement si pas de station. Comme pour un précédent test d’incohérence,, NO PARENT_ENTITY n’est pas levé en raison d’un choix d’implémentation qui peut être modifié.;Pas de station;INVALID_UUID(unique_id_sinp_station);;Erroneous 3;;;;Toto;;;;0f8b2ae0-df5f-4d66-9c0b-5ccbb0baa7f2;prairie;24;
-Les UUID ≠ mais les id origine sont identique !;INCOHERENT_DATA [UUID ≠];NO_PARENT_ENTITY(id_station);Station 3;dd0d12fc-bb85-4029-9c72-14fd8583f9bb;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;791438ee-aeae-4983-9d23-1ae86208128e;prairie;24;
-;INCOHERENT_DATA [UUID ≠];NO_PARENT_ENTITY(id_station);Station 3;330bb0f5-dc1c-431a-af1a-d70138b8c99d;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;745743a3-d5e2-4f43-a791-cd4bcf9a06d5;prairie;24;
-Les UUID sont égaux mais les id origine ≠ !;INCOHERENT_DATA [id_station_source ≠];NO_PARENT_ENTITY(id_station);Station 4;a5c37acb-c966-4024-bea6-71ec125b51c8;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;fc6b3757-7c6e-4619-a509-8d964135596b;prairie;24;
-;INCOHERENT_DATA [id_station_source ≠];NO_PARENT_ENTITY(id_station);Station 5;a5c37acb-c966-4024-bea6-71ec125b51c8;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;de898fc8-8ef7-47ff-8cc0-5a463022fda4;prairie;24;
-Les id origine sont identique, mais les UUID ne sont pas toujours renseignés.;INCOHERENT_DATA [UUID ≠];NO_PARENT_ENTITY(id_station);Station 6;7ed90696-4e74-4ed5-98a4-518eea009a7f;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;e63b9d13-73bf-4a2a-9539-d26eb74633ec;prairie;24;
-;INCOHERENT_DATA [UUID ≠];MISSING_VALUE(unique_id_sinp_station);Station 6;;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;d8268ad3-cc6a-47a9-80b8-460a98ff3bab;prairie;24;
-Les UUID sont égaux mais les id origine ne sont pas toujours renseignés.;INCOHERENT_DATA [id_station_source ≠];NO_PARENT_ENTITY(id_station);Station 7;c4262f95-0b19-422a-848b-8f83c292d27a;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;51ef110f-5f38-414e-8820-6bee9930e46d;prairie;24;
-;INCOHERENT_DATA [id_station_source ≠];NO_PARENT_ENTITY(id_station);;c4262f95-0b19-422a-848b-8f83c292d27a;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;e5c4fcb2-2bd1-44e9-a2d1-87888d3da246;prairie;24;
-Il y a ni UUID, ni id_origine, or les UUID ne sont pas générés.;MISSING_VALUE(unique_id_sinp_station);MISSING_VALUE(unique_id_sinp_station);;;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;7aa27e0b-680e-466e-940a-97dd7fd7715a;prairie;24;
+Les UUID ≠ mais les id origine sont identique !;INCOHERENT_DATA [UUID ≠];NO_PARENT_ENTITY(id_station);Station 3;dd0d12fc-bb85-4029-9c72-14fd8583f9bb;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;791438ee-aeae-4983-9d23-1ae86208128e;prairie;24;
+;INCOHERENT_DATA [UUID ≠];NO_PARENT_ENTITY(id_station);Station 3;330bb0f5-dc1c-431a-af1a-d70138b8c99d;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;745743a3-d5e2-4f43-a791-cd4bcf9a06d5;prairie;24;
+Les UUID sont égaux mais les id origine ≠ !;INCOHERENT_DATA [id_station_source ≠];NO_PARENT_ENTITY(id_station);Station 4;a5c37acb-c966-4024-bea6-71ec125b51c8;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;fc6b3757-7c6e-4619-a509-8d964135596b;prairie;24;
+;INCOHERENT_DATA [id_station_source ≠];NO_PARENT_ENTITY(id_station);Station 5;a5c37acb-c966-4024-bea6-71ec125b51c8;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;de898fc8-8ef7-47ff-8cc0-5a463022fda4;prairie;24;
+Les id origine sont identique, mais les UUID ne sont pas toujours renseignés.;INCOHERENT_DATA [UUID ≠];NO_PARENT_ENTITY(id_station);Station 6;7ed90696-4e74-4ed5-98a4-518eea009a7f;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;e63b9d13-73bf-4a2a-9539-d26eb74633ec;prairie;24;
+;INCOHERENT_DATA [UUID ≠];MISSING_VALUE(unique_id_sinp_station);Station 6;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;d8268ad3-cc6a-47a9-80b8-460a98ff3bab;prairie;24;
+Les UUID sont égaux mais les id origine ne sont pas toujours renseignés.;INCOHERENT_DATA [id_station_source ≠];NO_PARENT_ENTITY(id_station);Station 7;c4262f95-0b19-422a-848b-8f83c292d27a;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;51ef110f-5f38-414e-8820-6bee9930e46d;prairie;24;
+;INCOHERENT_DATA [id_station_source ≠];NO_PARENT_ENTITY(id_station);;c4262f95-0b19-422a-848b-8f83c292d27a;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;e5c4fcb2-2bd1-44e9-a2d1-87888d3da246;prairie;24;
+Il y a ni UUID, ni id_origine, or les UUID ne sont pas générés.;MISSING_VALUE(unique_id_sinp_station);MISSING_VALUE(unique_id_sinp_station);;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;7aa27e0b-680e-466e-940a-97dd7fd7715a;prairie;24;
Import d’un habitat dans une station existante ailleurs dans le fichier, référencé par UUID.;Pas de station;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;;;;Toto;;;;3adb0b26-97ba-436e-923e-8a1b4f4d41ea;prairie;24;
Import d’un habitat dans une station existante ailleurs dans le fichier, référencé par id origine.;Pas de station;MISSING_VALUE(unique_id_sinp_station);Station 8;;;;;Toto;;;;4bed57d7-2569-4e49-9b82-14b6b847d5f7;prairie;24;
-On importe une station qui existe déjà en base : elle est ignorée;SKIP_EXISTING_UUID;Pas d’habitat;;EXISTING_STATION_UUID;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;;;
-On importe une station qui existe déjà en base et un nouvel habitat, seul l’habitat est importé;SKIP_EXISTING_UUID;OK !;;EXISTING_STATION_UUID;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;33153ba5-8773-4ffc-8e69-7be3e008208a;prairie;24;
-On importe une station et un habitat existant déjà en base;SKIP_EXISTING_UUID;SKIP_EXISTING_UUID;;EXISTING_STATION_UUID;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;EXISTING_HABITAT_UUID;prairie;24;
+On importe une station qui existe déjà en base : elle est ignorée;SKIP_EXISTING_UUID;Pas d’habitat;;@EXISTING_STATION_UUID@;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;;;
+On importe une station qui existe déjà en base et un nouvel habitat, seul l’habitat est importé;SKIP_EXISTING_UUID;OK !;;@EXISTING_STATION_UUID@;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;33153ba5-8773-4ffc-8e69-7be3e008208a;prairie;24;
+On importe une station et un habitat existant déjà en base;SKIP_EXISTING_UUID;SKIP_EXISTING_UUID;;@EXISTING_STATION_UUID@;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;@EXISTING_HABITAT_UUID@;prairie;24;
diff --git a/backend/geonature/tests/imports/files/occhab/valid_file.csv b/backend/geonature/tests/imports/files/occhab/valid_file.csv
index 543730d7ea..173f233a2e 100644
--- a/backend/geonature/tests/imports/files/occhab/valid_file.csv
+++ b/backend/geonature/tests/imports/files/occhab/valid_file.csv
@@ -1,44 +1,44 @@
Objectif du test;Erreur station;Erreur habitat;id_station_source;unique_id_sinp_station;unique_dataset_id;date_min;date_max;observers;id_nomenclature_area_surface_calculation;WKT;id_nomenclature_geographic_object;unique_id_sinp_habitat;nom_cite;cd_hab;technical_precision;id_nomenclature_collection_technique
-Station + habitat sur la même ligne;OK !;OK !;;afa81c29-c75d-408d-bf48-53cce02d5561;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;4ee53579-b09b-408f-aa1f-d62495a66667;prairie;24;;
-Station uniquement;OK !;Pas d’habitat;;9d3fb1bd-6148-45c4-aa13-ff9212155afe;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;;;;
-Habitat uniquement dans une station existante en base.;Pas de station;OK !;;EXISTING_STATION_UUID;;;;Toto;;;;05f0163a-ab14-4045-84b9-b513188092ae;prairie;24;;
-Dataset innexistant, habitat valide mais pas le parent;DATASET_NOT_FOUND(unique_dataset_id), INCOHERENT_DATA;ERRONEOUS_PARENT_ENTITY;;bdc3346d-0fc3-40fa-b787-be927e4dd82e;050d613c-543f-47fd-800a-13931b2721c7;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;2ff4867d-6943-45d8-873d-187fbc6d67a7;prairie;24;;
-Dataset interdit, habitat valide mais pas le parent;DATASET_NOT_AUTHORIZED(unique_dataset_id);ERRONEOUS_PARENT_ENTITY;;f5f031a3-cf1b-419c-9817-69c39f51aef4;FORBIDDEN_DATASET_UUID;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;5dfb9930-4795-4e6f-baae-3dd86abb3b70;prairie;24;;
-Dataset UUID invalide;INVALID_UUID(unique_dataset_id);Pas d’habitat;;;erroneous;17/11/2023;17/11/2023;Toto;;COORD_STATION;;;;;;
-Champs géométrique manquant;NO-GEOM(Champs géométriques);Pas d’habitat;;;;17/11/2023;17/11/2023;Toto;;;;;;;;
-Champs requis manquant;MISSING_VALUE(date_min);ERRONEOUS_PARENT_ENTITY;;4ee7728d-387d-49c5-b9a3-4162b0987fa5;;;;Toto;;COORD_STATION;St;aeb10ac4-6d69-4fa6-8df6-14d9304911df;prairie;24;;
+Station + habitat sur la même ligne;OK !;OK !;;afa81c29-c75d-408d-bf48-53cce02d5561;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;4ee53579-b09b-408f-aa1f-d62495a66667;prairie;24;;
+Station uniquement;OK !;Pas d’habitat;;9d3fb1bd-6148-45c4-aa13-ff9212155afe;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;;;;
+Habitat uniquement dans une station existante en base.;Pas de station;OK !;;@EXISTING_STATION_UUID@;;;;Toto;;;;05f0163a-ab14-4045-84b9-b513188092ae;prairie;24;;
+Dataset innexistant, habitat valide mais pas le parent;DATASET_NOT_FOUND(unique_dataset_id), INCOHERENT_DATA;ERRONEOUS_PARENT_ENTITY;;bdc3346d-0fc3-40fa-b787-be927e4dd82e;@DATASET_NOT_FOUND@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;2ff4867d-6943-45d8-873d-187fbc6d67a7;prairie;24;;
+Dataset interdit, habitat valide mais pas le parent;DATASET_NOT_AUTHORIZED(unique_dataset_id);ERRONEOUS_PARENT_ENTITY;;f5f031a3-cf1b-419c-9817-69c39f51aef4;@FORBIDDEN_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;5dfb9930-4795-4e6f-baae-3dd86abb3b70;prairie;24;;
+Dataset UUID invalide;INVALID_UUID(unique_dataset_id);Pas d’habitat;;;erroneous;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;;;;;;
+Champs géométrique manquant;NO-GEOM(Champs géométriques);Pas d’habitat;;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;;;;;;;
+Champs requis manquant;MISSING_VALUE(date_min);ERRONEOUS_PARENT_ENTITY;;4ee7728d-387d-49c5-b9a3-4162b0987fa5;@VALID_DATASET_UUID@;;;Toto;;@COORD_STATION@;St;aeb10ac4-6d69-4fa6-8df6-14d9304911df;prairie;24;;
Habitat mais pas de station référencée;Pas de station;NO_PARENT_ENTITY(id_station);;;;;;Toto;;;;;prairie;24;;
Uniquement un uuid station, mais on ne sait pas s’il appartient à une station ou s’il sert à indiquer le parent d’un habitat;ORPHAN_ROW(unique_id_sinp_station);ORPHAN_ROW(unique_id_sinp_station);;258a2478-8a0e-4321-83df-c2313ad3040e;;;;Toto;;;;;;;;
Uniquement un id station source, mais on ne sait pas s’il appartient à une station ou s’il sert à indiquer le parent d’un habitat;ORPHAN_ROW(id_station_source);ORPHAN_ROW(id_station_source);Station -1;;;;;Toto;;;;;;;;
Uniquement UUID station + id station source, mais on ne sait pas s’ils appartiennent à une station ou s’ils servent à indiquer le parent d’un habitat;ORPHAN_ROW(unique_id_sinp_station, id_station_source);ORPHAN_ROW(unique_id_sinp_station,id_station_source);Station -2;54e54935-982b-4da3-9aaf-e87e49a1fdf1;;;;Toto;;;;;;;;
-On importe 2 habitats dans une même nouvelle station dont les données sont répétées. Les lignes contenant la station sont rapproché par UUID.;OK !;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;e5e7a184-3e92-4adb-a721-5bd004b3397f;forêt;24;;
-;OK !;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;8f52f122-b9ae-45b3-b947-2c9f7934b823;prairie;24;;
-On importe 2 habitats dans une même nouvelle station dont les données sont répétées MAIS AVEC DES DIFFÉRENCES (date). Les lignes contenant la station sont rapproché par UUID.;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;17/11/2023;;Toto;;COORD_STATION;St;d91496e9-d904-45a8-9e18-cb8acbbb6ea6;prairie;24;;
-;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;18/11/2023;;Toto;;COORD_STATION;St;;prairie;24;;
-On importe 2 habitats dans une même nouvelle station dont les données sont répétées mais avec des différences (date INVALIDE). Les lignes contenant la station sont rapproché par UUID. On vérifie qu’on a pas d’erreur sur la date car les contrôles ne doivent pas être lancé si les données sont incohérentes. En revanche, les contrôles des habitats doivent bien être lancés.;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;17/11/2023;;Toto;;COORD_STATION;St;;prairie;24;;
-NO_PARENT_ENTITY(id_station) non levé sur l’habitat en raison de l’implémentation du check qui ignore les lignes erronées. À voir s’il faut le faire évoluer.;INCOHERENT_DATA(unique_id_sinp_station);INVALID_INTEGER(cd_hab);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;date invalide;;Toto;;COORD_STATION;St;;prairie;invalide;;
-On importe 2 habitats dans une même nouvelle station dont les données sont répétées. Les lignes contenant la station sont rapproché par id origine.;OK !;OK !;Station 1;;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-;OK !;OK !;Station 1;;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-On importe 2 habitats dans une même nouvelle station dont les données sont répétées MAIS AVEC DES DIFFÉRENCES (date). Les lignes contenant la station sont rapproché par id origine.;INCOHERENT_DATA(id_station_source);NO_PARENT_ENTITY(id_station);Station 2;;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-;INCOHERENT_DATA(id_station_source);NO_PARENT_ENTITY(id_station);Station 2;;;invalide;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-Un UUID station invalide lève une erreur sur la station ET sur l’habitat;INVALID_UUID(unique_id_sinp_station);INVALID_UUID(unique_id_sinp_station),ERRONEOUS_PARENT_ENTITY;;Erroneous 1;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;6c02ef80-2e78-4c2c-b8b5-1c75e2349fc2;prairie;24;;
-Un UUID station invalide lève une erreur sur la station uniquement si pas d’habitat;INVALID_UUID(unique_id_sinp_station),MISSING_VALUE(date_min);Pas d’habitat;;Erroneous 2;;;17/11/2024;Toto;;COORD_STATION;;;;;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées. Les lignes contenant la station sont rapproché par UUID.;OK !;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;e5e7a184-3e92-4adb-a721-5bd004b3397f;forêt;24;;
+;OK !;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;8f52f122-b9ae-45b3-b947-2c9f7934b823;prairie;24;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées MAIS AVEC DES DIFFÉRENCES (date). Les lignes contenant la station sont rapproché par UUID.;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;@VALID_DATASET_UUID@;17/11/2023;;Toto;;@COORD_STATION@;St;d91496e9-d904-45a8-9e18-cb8acbbb6ea6;prairie;24;;
+;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;@VALID_DATASET_UUID@;18/11/2023;;Toto;;@COORD_STATION@;St;;prairie;24;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées mais avec des différences (date INVALIDE). Les lignes contenant la station sont rapproché par UUID. On vérifie qu’on a pas d’erreur sur la date car les contrôles ne doivent pas être lancé si les données sont incohérentes. En revanche, les contrôles des habitats doivent bien être lancés.;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;17/11/2023;;Toto;;@COORD_STATION@;St;;prairie;24;;
+NO_PARENT_ENTITY(id_station) non levé sur l’habitat en raison de l’implémentation du check qui ignore les lignes erronées. À voir s’il faut le faire évoluer.;INCOHERENT_DATA(unique_id_sinp_station);INVALID_INTEGER(cd_hab);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;@VALID_DATASET_UUID@;date invalide;;Toto;;@COORD_STATION@;St;;prairie;invalide;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées. Les lignes contenant la station sont rapproché par id origine.;OK !;OK !;Station 1;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+;OK !;OK !;Station 1;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées MAIS AVEC DES DIFFÉRENCES (date). Les lignes contenant la station sont rapproché par id origine.;INCOHERENT_DATA(id_station_source);NO_PARENT_ENTITY(id_station);Station 2;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+;INCOHERENT_DATA(id_station_source);NO_PARENT_ENTITY(id_station);Station 2;;@VALID_DATASET_UUID@;invalide;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+Un UUID station invalide lève une erreur sur la station ET sur l’habitat;INVALID_UUID(unique_id_sinp_station);INVALID_UUID(unique_id_sinp_station),ERRONEOUS_PARENT_ENTITY;;Erroneous 1;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;6c02ef80-2e78-4c2c-b8b5-1c75e2349fc2;prairie;24;;
+Un UUID station invalide lève une erreur sur la station uniquement si pas d’habitat;INVALID_UUID(unique_id_sinp_station),MISSING_VALUE(date_min);Pas d’habitat;;Erroneous 2;@VALID_DATASET_UUID@;;17/11/2024;Toto;;@COORD_STATION@;;;;;;
Un UUID station invalide lève une erreur sur l’habitat uniquement si pas de station. Comme pour un précédent test d’incohérence,, NO PARENT_ENTITY n’est pas levé en raison d’un choix d’implémentation qui peut être modifié.;Pas de station;INVALID_UUID(unique_id_sinp_station);;Erroneous 3;;;;Toto;;;;;prairie;24;;
-Les UUID ≠ mais les id origine sont identique !;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 3;dd0d12fc-bb85-4029-9c72-14fd8583f9bb;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 3;330bb0f5-dc1c-431a-af1a-d70138b8c99d;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-Les UUID sont égaux mais les id origine ≠ !;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;Station 4;a5c37acb-c966-4024-bea6-71ec125b51c8;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;Station 5;a5c37acb-c966-4024-bea6-71ec125b51c8;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-Les id origine sont identique, mais les UUID ne sont pas toujours renseignés.;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 6;7ed90696-4e74-4ed5-98a4-518eea009a7f;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 6;;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-Les UUID sont égaux mais les id origine ne sont pas toujours renseignés.;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;Station 7;c4262f95-0b19-422a-848b-8f83c292d27a;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;;c4262f95-0b19-422a-848b-8f83c292d27a;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-Il y a ni UUID, ni id_origine : l’UUID sera généré.;OK !;OK !;;;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
+Les UUID ≠ mais les id origine sont identique !;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 3;dd0d12fc-bb85-4029-9c72-14fd8583f9bb;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 3;330bb0f5-dc1c-431a-af1a-d70138b8c99d;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+Les UUID sont égaux mais les id origine ≠ !;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;Station 4;a5c37acb-c966-4024-bea6-71ec125b51c8;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;Station 5;a5c37acb-c966-4024-bea6-71ec125b51c8;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+Les id origine sont identique, mais les UUID ne sont pas toujours renseignés.;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 6;7ed90696-4e74-4ed5-98a4-518eea009a7f;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 6;;;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+Les UUID sont égaux mais les id origine ne sont pas toujours renseignés.;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;Station 7;c4262f95-0b19-422a-848b-8f83c292d27a;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;;c4262f95-0b19-422a-848b-8f83c292d27a;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+Il y a ni UUID, ni id_origine : l’UUID sera généré.;OK !;OK !;;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
Import d’un habitat dans une station existante ailleurs dans le fichier, référencé par UUID.;Pas de station;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;;;;Toto;;;;;prairie;24;;
Import d’un habitat dans une station existante ailleurs dans le fichier, référencé par id origine.;Pas de station;OK !;Station 1;;;;;Toto;;;;;prairie;24;;
-On importe une station qui existe déjà en base : elle est ignorée;SKIP_EXISTING_UUID;Pas d’habitat;;EXISTING_STATION_UUID;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;;;;
-On importe une station qui existe déjà en base et un nouvel habitat, seul l’habitat est importé;SKIP_EXISTING_UUID;OK !;;EXISTING_STATION_UUID;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;
-On importe une station et un habitat existant déjà en base;SKIP_EXISTING_UUID;SKIP_EXISTING_UUID;;EXISTING_STATION_UUID;;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;EXISTING_HABITAT_UUID;prairie;24;;
-technique collect vaut « autre » mais pas de précision fournise;OK !;CONDITIONAL_MANDATORY_FIELD_ERROR;;;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;;10
-technique collect vaut « autre » et une précision est bien fournies;OK !;OK !;;;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;moyen précis;10
-L’habitat est crée dans une station que existe en base mais sur laquelle nous n’avons pas les droits;DATASET_NOT_AUTHORIZED(unique_dataset_id);OK ! ;;STRANGER_STATION_UUID;;;;;;;;;prairie;24;moyen précis;10
-jeu de données pas actif;DATASET_NOT_ACTIVE;ERRONEOUS_PARENT_ENTITY;;;INACTIVE_DATASET_UUID;17/11/2023;17/11/2023;Toto;;COORD_STATION;St;;prairie;24;moyen précis;10
+On importe une station qui existe déjà en base : elle est ignorée;SKIP_EXISTING_UUID;Pas d’habitat;;@EXISTING_STATION_UUID@;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;;;;
+On importe une station qui existe déjà en base et un nouvel habitat, seul l’habitat est importé;SKIP_EXISTING_UUID;OK !;;@EXISTING_STATION_UUID@;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;
+On importe une station et un habitat existant déjà en base;SKIP_EXISTING_UUID;SKIP_EXISTING_UUID;;@EXISTING_STATION_UUID@;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;@EXISTING_HABITAT_UUID@;prairie;24;;
+technique collect vaut « autre » mais pas de précision fournise;OK !;CONDITIONAL_MANDATORY_FIELD_ERROR;;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;;10
+technique collect vaut « autre » et une précision est bien fournies;OK !;OK !;;;@VALID_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;moyen précis;10
+L’habitat est crée dans une station que existe en base mais sur laquelle nous n’avons pas les droits;DATASET_NOT_AUTHORIZED(unique_dataset_id);OK !;;@STRANGER_STATION_UUID@;;;;;;;;;prairie;24;moyen précis;10
+jeu de données pas actif;DATASET_NOT_ACTIVE;ERRONEOUS_PARENT_ENTITY;;;@INACTIVE_DATASET_UUID@;17/11/2023;17/11/2023;Toto;;@COORD_STATION@;St;;prairie;24;moyen précis;10
diff --git a/backend/geonature/tests/imports/files/occhab/valid_file_importable.csv b/backend/geonature/tests/imports/files/occhab/valid_file_importable.csv
new file mode 100644
index 0000000000..c3336df62c
--- /dev/null
+++ b/backend/geonature/tests/imports/files/occhab/valid_file_importable.csv
@@ -0,0 +1,44 @@
+Objectif du test;Erreur station;Erreur habitat;id_station_source;unique_id_sinp_station;unique_dataset_id;date_min;date_max;observers;id_nomenclature_area_surface_calculation;WKT;id_nomenclature_geographic_object;unique_id_sinp_habitat;nom_cite;cd_hab;technical_precision;id_nomenclature_collection_technique
+Station + habitat sur la même ligne;OK !;OK !;;afa81c29-c75d-408d-bf48-53cce02d5561;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;4ee53579-b09b-408f-aa1f-d62495a66667;prairie;24;;
+Station uniquement;OK !;Pas d’habitat;;9d3fb1bd-6148-45c4-aa13-ff9212155afe;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;;;;
+Habitat uniquement dans une station existante en base.;Pas de station;OK !;;EXISTING_STATION_UUID;;;;Toto;;;;05f0163a-ab14-4045-84b9-b513188092ae;prairie;24;;
+Dataset innexistant, habitat valide mais pas le parent;DATASET_NOT_FOUND(unique_dataset_id), INCOHERENT_DATA;ERRONEOUS_PARENT_ENTITY;;bdc3346d-0fc3-40fa-b787-be927e4dd82e;050d613c-543f-47fd-800a-13931b2721c7;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;2ff4867d-6943-45d8-873d-187fbc6d67a7;prairie;24;;
+Dataset interdit, habitat valide mais pas le parent;DATASET_NOT_AUTHORIZED(unique_dataset_id);ERRONEOUS_PARENT_ENTITY;;f5f031a3-cf1b-419c-9817-69c39f51aef4;FORBIDDEN_DATASET_UUID;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;5dfb9930-4795-4e6f-baae-3dd86abb3b70;prairie;24;;
+Dataset UUID invalide;INVALID_UUID(unique_dataset_id);Pas d’habitat;;;erroneous;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);;;;;;
+Champs géométrique manquant;NO-GEOM(Champs géométriques);Pas d’habitat;;;;17/11/2023;17/11/2023;Toto;;;;;;;;
+Champs requis manquant;MISSING_VALUE(date_min);ERRONEOUS_PARENT_ENTITY;;4ee7728d-387d-49c5-b9a3-4162b0987fa5;;;;Toto;;POINT(6.6 44.85);St;aeb10ac4-6d69-4fa6-8df6-14d9304911df;prairie;24;;
+Habitat mais pas de station référencée;Pas de station;NO_PARENT_ENTITY(id_station);;;;;;Toto;;;;;prairie;24;;
+Uniquement un uuid station, mais on ne sait pas s’il appartient à une station ou s’il sert à indiquer le parent d’un habitat;ORPHAN_ROW(unique_id_sinp_station);ORPHAN_ROW(unique_id_sinp_station);;258a2478-8a0e-4321-83df-c2313ad3040e;;;;Toto;;;;;;;;
+Uniquement un id station source, mais on ne sait pas s’il appartient à une station ou s’il sert à indiquer le parent d’un habitat;ORPHAN_ROW(id_station_source);ORPHAN_ROW(id_station_source);Station -1;;;;;Toto;;;;;;;;
+Uniquement UUID station + id station source, mais on ne sait pas s’ils appartiennent à une station ou s’ils servent à indiquer le parent d’un habitat;ORPHAN_ROW(unique_id_sinp_station, id_station_source);ORPHAN_ROW(unique_id_sinp_station,id_station_source);Station -2;54e54935-982b-4da3-9aaf-e87e49a1fdf1;;;;Toto;;;;;;;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées. Les lignes contenant la station sont rapproché par UUID.;OK !;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;e5e7a184-3e92-4adb-a721-5bd004b3397f;forêt;24;;
+;OK !;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;8f52f122-b9ae-45b3-b947-2c9f7934b823;prairie;24;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées MAIS AVEC DES DIFFÉRENCES (date). Les lignes contenant la station sont rapproché par UUID.;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;17/11/2023;;Toto;;POINT(6.6 44.85);St;d91496e9-d904-45a8-9e18-cb8acbbb6ea6;prairie;24;;
+;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;18/11/2023;;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées mais avec des différences (date INVALIDE). Les lignes contenant la station sont rapproché par UUID. On vérifie qu’on a pas d’erreur sur la date car les contrôles ne doivent pas être lancé si les données sont incohérentes. En revanche, les contrôles des habitats doivent bien être lancés.;INCOHERENT_DATA(unique_id_sinp_station);NO_PARENT_ENTITY(id_station);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;17/11/2023;;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+NO_PARENT_ENTITY(id_station) non levé sur l’habitat en raison de l’implémentation du check qui ignore les lignes erronées. À voir s’il faut le faire évoluer.;INCOHERENT_DATA(unique_id_sinp_station);INVALID_INTEGER(cd_hab);;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;date invalide;;Toto;;POINT(6.6 44.85);St;;prairie;invalide;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées. Les lignes contenant la station sont rapproché par id origine.;OK !;OK !;Station 1;;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+;OK !;OK !;Station 1;;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+On importe 2 habitats dans une même nouvelle station dont les données sont répétées MAIS AVEC DES DIFFÉRENCES (date). Les lignes contenant la station sont rapproché par id origine.;INCOHERENT_DATA(id_station_source);NO_PARENT_ENTITY(id_station);Station 2;;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+;INCOHERENT_DATA(id_station_source);NO_PARENT_ENTITY(id_station);Station 2;;;invalide;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+Un UUID station invalide lève une erreur sur la station ET sur l’habitat;INVALID_UUID(unique_id_sinp_station);INVALID_UUID(unique_id_sinp_station),ERRONEOUS_PARENT_ENTITY;;Erroneous 1;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;6c02ef80-2e78-4c2c-b8b5-1c75e2349fc2;prairie;24;;
+Un UUID station invalide lève une erreur sur la station uniquement si pas d’habitat;INVALID_UUID(unique_id_sinp_station),MISSING_VALUE(date_min);Pas d’habitat;;Erroneous 2;;;17/11/2024;Toto;;POINT(6.6 44.85);;;;;;
+Un UUID station invalide lève une erreur sur l’habitat uniquement si pas de station. Comme pour un précédent test d’incohérence,, NO PARENT_ENTITY n’est pas levé en raison d’un choix d’implémentation qui peut être modifié.;Pas de station;INVALID_UUID(unique_id_sinp_station);;Erroneous 3;;;;Toto;;;;;prairie;24;;
+Les UUID ≠ mais les id origine sont identique !;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 3;dd0d12fc-bb85-4029-9c72-14fd8583f9bb;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 3;330bb0f5-dc1c-431a-af1a-d70138b8c99d;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+Les UUID sont égaux mais les id origine ≠ !;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;Station 4;a5c37acb-c966-4024-bea6-71ec125b51c8;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;Station 5;a5c37acb-c966-4024-bea6-71ec125b51c8;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+Les id origine sont identique, mais les UUID ne sont pas toujours renseignés.;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 6;7ed90696-4e74-4ed5-98a4-518eea009a7f;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+;INCOHERENT_DATA [UUID ≠];ERRONEOUS_PARENT_ENTITY;Station 6;;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+Les UUID sont égaux mais les id origine ne sont pas toujours renseignés.;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;Station 7;c4262f95-0b19-422a-848b-8f83c292d27a;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+;INCOHERENT_DATA [id_station_source ≠];ERRONEOUS_PARENT_ENTITY;;c4262f95-0b19-422a-848b-8f83c292d27a;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+Il y a ni UUID, ni id_origine : l’UUID sera généré.;OK !;OK !;;;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+Import d’un habitat dans une station existante ailleurs dans le fichier, référencé par UUID.;Pas de station;OK !;;462d385f-489a-436b-babb-8cca5fc62e1d;;;;Toto;;;;;prairie;24;;
+Import d’un habitat dans une station existante ailleurs dans le fichier, référencé par id origine.;Pas de station;OK !;Station 1;;;;;Toto;;;;;prairie;24;;
+On importe une station qui existe déjà en base : elle est ignorée;SKIP_EXISTING_UUID;Pas d’habitat;;EXISTING_STATION_UUID;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;;;;
+On importe une station qui existe déjà en base et un nouvel habitat, seul l’habitat est importé;SKIP_EXISTING_UUID;OK !;;EXISTING_STATION_UUID;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;
+On importe une station et un habitat existant déjà en base;SKIP_EXISTING_UUID;SKIP_EXISTING_UUID;;EXISTING_STATION_UUID;;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;EXISTING_HABITAT_UUID;prairie;24;;
+technique collect vaut « autre » mais pas de précision fournise;OK !;CONDITIONAL_MANDATORY_FIELD_ERROR;;;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;;10
+technique collect vaut « autre » et une précision est bien fournies;OK !;OK !;;;VALID_DATASET_UUID;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;moyen précis;10
+L’habitat est crée dans une station que existe en base mais sur laquelle nous n’avons pas les droits;DATASET_NOT_AUTHORIZED(unique_dataset_id);OK ! ;;STRANGER_STATION_UUID;;;;;;;;;prairie;24;moyen précis;10
+jeu de données pas actif;DATASET_NOT_ACTIVE;ERRONEOUS_PARENT_ENTITY;;;INACTIVE_DATASET_UUID;17/11/2023;17/11/2023;Toto;;POINT(6.6 44.85);St;;prairie;24;moyen précis;10
diff --git a/backend/geonature/tests/imports/files/synthese/jdd_to_import_file.csv b/backend/geonature/tests/imports/files/synthese/jdd_to_import_file.csv
index 396ee835e9..eecbae1f90 100644
--- a/backend/geonature/tests/imports/files/synthese/jdd_to_import_file.csv
+++ b/backend/geonature/tests/imports/files/synthese/jdd_to_import_file.csv
@@ -1,6 +1,8 @@
error;id_synthese;id_origine;comment_releve;comment_occurrence;date_debut;date_fin;heure_debut;heure_fin;cd_nom;cd_ref;nom_valide;nom_vernaculaire;nom_cite;regne;group1_inpn;group2_inpn;classe;ordre;famille;rang_taxo;nombre_min;nombre_max;alti_min;alti_max;prof_min;prof_max;observateurs;determinateur;communes;geometrie_wkt_4326;x_centroid_4326;y_centroid_4326;nom_lieu;validateur;niveau_validation;date_validation;comment_validation;preuve_numerique_url;preuve_non_numerique;jdd_nom;jdd_uuid;jdd_id;ca_nom;ca_uuid;ca_id;cd_habref;cd_habitat;nom_habitat;precision_geographique;nature_objet_geo;type_regroupement;methode_regroupement;technique_observation;biologique_statut;etat_biologique;biogeographique_statut;naturalite;preuve_existante;niveau_precision_diffusion;stade_vie;sexe;objet_denombrement;type_denombrement;niveau_sensibilite;statut_observation;statut_source;type_info_geo;methode_determination;comportement;reference_biblio;uuid_perm_sinp;uuid_perm_grp_sinp;date_creation;date_modification;unique_dataset_id
-valid;1;1;Relevé n°1;Occurrence n°1;2017-01-01;2017-01-01;12:05:02;12:05:02;60612;60612;Lynx lynx (Linnaeus, 1758);;Lynx Boréal;Animalia;Chordés;Mammifères;Mammalia;Carnivora;Felidae;ES;5;5;1500;1565;;;Administrateur test;Gil;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poil;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Adulte;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;b4f85a2e-dd88-4cdd-aa86-f1c7370faf3f;5b427c76-bd8c-4103-a33c-884c7037aa2b;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;VALID_DATASET_UUID
-valid;2;2;Relevé n°2;Occurrence n°2;2017-01-01;2017-01-02;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1500;1565;;;Administrateur test;Théo;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Immature;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;830c93c7-288e-40f0-a17f-15fbb50e643a;5b427c76-bd8c-4103-a33c-884c7037aa2b;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;
-DATASET_NOT_AUTHORIZED(unique_dataset_id);3;3;Relevé n°3;Occurrence n°3;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e3;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;FORBIDDEN_DATASET_UUID
-INVALID_UUID(unique_dataset_id);6;6;Relevé n°6;Occurrence n°6;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;f5515e2a-b30d-11eb-8cc8-af8c2d0867b4;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;050d613c-543f-47fd-800a-13931b2721c7
-CONDITIONAL_MANDATORY_FIELD_ERROR(id_nomenclature_blurring);7;7;Relevé n°7;Occurrence n°7;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;;;;;;;;;;;;;;;;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;;;;;;050d613c-543f-47fd-800a-13931b2721c7;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;PRIVATE_DATASET_UUID
+valid;1;1;Relevé n°1;Occurrence n°1;2017-01-01;2017-01-01;12:05:02;12:05:02;60612;60612;Lynx lynx (Linnaeus, 1758);;Lynx Boréal;Animalia;Chordés;Mammifères;Mammalia;Carnivora;Felidae;ES;5;5;1500;1565;;;Administrateur test;Gil;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poil;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Adulte;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;@USER_DATASET_UUID@
+valid;2;2;Relevé n°2;Occurrence n°2;2017-01-01;2017-01-02;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1500;1565;;;Administrateur test;Théo;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Immature;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;
+INVALID_UUID(unique_dataset_id);3;3;Relevé n°3;Occurrence n°3;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;this-is-not-a-valid-uuid
+DATASET_NOT_FOUND(unique_dataset_id;4;4;Relevé n°4;Occurrence n°4;2017-01-01;2017-01-02;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1500;1565;;;Administrateur test;Théo;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Immature;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;@DATASET_NOT_FOUND@
+DATASET_INACTIVE(unique_dataset_id);5;5;Relevé n°3;Occurrence n°3;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;@DATASET_INACTIVE@
+DATASET_NOT_AUTHORIZED(unique_dataset_id);6;6;Relevé n°5;Occurrence n°5;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;@DATASET_NOT_AUTHORIZED@
+DATASET_PRIVATE(unique_dataset_id);7;7;Relevé n°7;Occurrence n°7;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497;@PRIVATE_DATASET_UUID@
diff --git a/backend/geonature/tests/imports/files/synthese/valid_file.csv b/backend/geonature/tests/imports/files/synthese/valid_file.csv
index 1c12d057f1..c5354abbac 100644
--- a/backend/geonature/tests/imports/files/synthese/valid_file.csv
+++ b/backend/geonature/tests/imports/files/synthese/valid_file.csv
@@ -1,7 +1,7 @@
error;id_synthese;id_origine;comment_releve;comment_occurrence;date_debut;date_fin;heure_debut;heure_fin;cd_nom;cd_ref;nom_valide;nom_vernaculaire;nom_cite;regne;group1_inpn;group2_inpn;classe;ordre;famille;rang_taxo;nombre_min;nombre_max;alti_min;alti_max;prof_min;prof_max;observateurs;determinateur;communes;geometrie_wkt_4326;x_centroid_4326;y_centroid_4326;nom_lieu;validateur;niveau_validation;date_validation;comment_validation;preuve_numerique_url;preuve_non_numerique;jdd_nom;jdd_uuid;jdd_id;ca_nom;ca_uuid;ca_id;cd_habref;cd_habitat;nom_habitat;precision_geographique;nature_objet_geo;type_regroupement;methode_regroupement;technique_observation;biologique_statut;etat_biologique;biogeographique_statut;naturalite;preuve_existante;niveau_precision_diffusion;stade_vie;sexe;objet_denombrement;type_denombrement;niveau_sensibilite;statut_observation;floutage_dee;statut_source;type_info_geo;methode_determination;comportement;reference_biblio;uuid_perm_sinp;uuid_perm_grp_sinp;date_creation;date_modification
-valid;1;1;Relevé n°1;Occurrence n°1;2017-01-01;2017-01-01;12:05:02;12:05:02;60612;60612;Lynx lynx (Linnaeus, 1758);;Lynx Boréal;Animalia;Chordés;Mammifères;Mammalia;Carnivora;Felidae;ES;5;5;1500;1565;;;Administrateur test;Gil;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poil;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Adulte;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;b4f85a2e-dd88-4cdd-aa86-f1c7370faf3f;5b427c76-bd8c-4103-a33c-884c7037aa2b;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-valid;2;2;Relevé n°2;Occurrence n°2;2017-01-01;2017-01-02;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1500;1565;;;Administrateur test;Théo;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Immature;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;830c93c7-288e-40f0-a17f-15fbb50e643a;5b427c76-bd8c-4103-a33c-884c7037aa2b;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-duplicate id;3;3;Relevé n°3;Occurrence n°3;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e3;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-duplicate id;3;4;Relevé n°4;Occurrence n°4;2017-01-08;2017-01-08;20:00:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e4;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-count min > count max;5;5;Relevé n°5;Occurrence n°5;2017-01-08;2017/01/08;20:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;20;5;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e5;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-valid;6;6;Relevé n°6;Occurrence n°6;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;f5515e2a-b30d-11eb-8cc8-af8c2d0867b4;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+valid;1;1;Relevé n°1;Occurrence n°1;2017-01-01;2017-01-01;12:05:02;12:05:02;60612;60612;Lynx lynx (Linnaeus, 1758);;Lynx Boréal;Animalia;Chordés;Mammifères;Mammalia;Carnivora;Felidae;ES;5;5;1500;1565;;;Administrateur test;Gil;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poil;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Adulte;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+valid;2;2;Relevé n°2;Occurrence n°2;2017-01-01;2017-01-02;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1500;1565;;;Administrateur test;Théo;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Immature;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+duplicate id;3;3;Relevé n°3;Occurrence n°3;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+duplicate id;3;4;Relevé n°4;Occurrence n°4;2017-01-08;2017-01-08;20:00:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+count min > count max;5;5;Relevé n°5;Occurrence n°5;2017-01-08;2017/01/08;20:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;20;5;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+valid;6;6;Relevé n°6;Occurrence n°6;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
diff --git a/backend/geonature/tests/imports/files/synthese/valid_file_etienne.csv b/backend/geonature/tests/imports/files/synthese/valid_file_etienne.csv
deleted file mode 100644
index 66063b8c6e..0000000000
--- a/backend/geonature/tests/imports/files/synthese/valid_file_etienne.csv
+++ /dev/null
@@ -1,7 +0,0 @@
-error ;id_synthese ;id_origine ;comment_releve ;comment_occurrence ;date_debut ;date_fin ;heure_debut ;heure_fin ;cd_nom ;cd_ref ;nom_valide ;nom_vernaculaire ;nom_cite ;regne ;group1_inpn ;group2_inpn ;classe ;ordre ;famille ;rang_taxo ;nombre_min ;nombre_max ;alti_min ;alti_max ;prof_min ;prof_max ;observateurs ;determinateur ;communes ;geometrie_wkt_4326 ;x_centroid_4326 ;y_centroid_4326 ;nom_lieu ;validateur ;niveau_validation ;date_validation ;comment_validation ;preuve_numerique_url ;preuve_non_numerique ;jdd_nom ;jdd_uuid ;jdd_id ;ca_nom ;ca_uuid ;ca_id ;cd_habref ;cd_habitat ;nom_habitat ;precision_geographique ;nature_objet_geo ;type_regroupement ;methode_regroupement ;technique_observation ;biologique_statut ;etat_biologique ;biogeographique_statut ;naturalite ;preuve_existante ;niveau_precision_diffusion ;stade_vie ;sexe ;objet_denombrement ;type_denombrement ;niveau_sensibilite ;statut_observation ;floutage_dee ;statut_source ;type_info_geo ;methode_determination ;comportement ;reference_biblio ;uuid_perm_sinp ;uuid_perm_grp_sinp ;date_creation ;date_modification
-valid ; 10 ; 10 ;Relevé n°1 ;Occurrence n°1 ;2017-01-01 ;2017-01-01 ;12:05:02 ;12:05:02 ; 60612 ; 60612 ;Lynx lynx (Linnaeus, 1758) ; ;Lynx Boréal ;Animalia ;Chordés ;Mammifères ;Mammalia ;Carnivora ;Felidae ;ES ; 5 ; 5 ; 1500 ; 1565 ; ; ;Administrateur test ;Gil ;Vallouise-Pelvoux ;POINT(6.6 44.85) ; 6.5 ; 44.85 ; ; ;En attente de validation ; ; ; ;Poil ;Contact aléatoire tous règnes confondus ;4d331cae-65e4-4948-b0b2-a11bc5bb46c2 ; 1 ;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins ;57b7d0f2-4183-4b7b-8f08-6e105d476dc5 ; 1 ; ; ; ; 10 ;Inventoriel ;OBS ; ;Galerie/terrier ;Non renseigné ;Non renseigné ;Non renseigné ;Sauvage ;Oui ;Précise ;Adulte ;Femelle ;Individu ;Compté ;Non sensible - Diffusion précise ;Présent ;Non ;Terrain ;Géoréférencement ;Autre méthode de détermination ;Non renseigné ; ;b4f85a2e-dd88-4cdd-aa86-f1c7370faf3f ;5b427c76-bd8c-4103-a33c-884c7037aa2b ;2021-01-11 14:20:46.492497 ;2021-01-11 14:20:46.492497
-valid ; 20 ; 20 ;Relevé n°2 ;Occurrence n°2 ;2017-01-01 ;2017-01-02 ;12:05:02 ;12:05:02 ; 351 ; 351 ;Rana temporaria Linnaeus, 1758 ;Grenouille rousse (La) ;Grenouille rousse ;Animalia ;Chordés ;Amphibiens ;Amphibia ;Anura ;Ranidae ;ES ; 1 ; 1 ; 1500 ; 1565 ; ; ;Administrateur test ;Théo ;Vallouise-Pelvoux ;POINT(6.6 44.85) ; 6.5 ; 44.85 ; ; ;En attente de validation ; ; ; ;Poils de plumes ;Contact aléatoire tous règnes confondus ;4d331cae-65e4-4948-b0b2-a11bc5bb46c2 ; 1 ;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins ;57b7d0f2-4183-4b7b-8f08-6e105d476dc5 ; 1 ; ; ; ; 10 ;Inventoriel ;OBS ; ;Galerie/terrier ;Non renseigné ;Non renseigné ;Non renseigné ;Sauvage ;Oui ;Précise ;Immature ;Femelle ;Individu ;Compté ;Non sensible - Diffusion précise ;Présent ;Non ;Terrain ;Géoréférencement ;Autre méthode de détermination ;Non renseigné ; ;830c93c7-288e-40f0-a17f-15fbb50e643a ;5b427c76-bd8c-4103-a33c-884c7037aa2b ;2021-01-11 14:20:46.492497 ;2021-01-11 14:20:46.492497
-duplicate id ; 30 ; 30 ;Relevé n°3 ;Occurrence n°3 ;2017-01-08 ; ; ; ; 67111 ; 67111 ;Alburnus alburnus (Linnaeus, 1758) ;Ablette ;Ablette ;Animalia ;Chordés ;Poissons ;Actinopterygii ;Cypriniformes ;Leuciscidae ;ES ; 1 ; 1 ; 1600 ; 1600 ; ; ;Administrateur test ;Donovan ;Vallouise-Pelvoux ;POINT(6.5 44.85) ; 6.5 ; 44.85 ; ; ;En attente de validation ; ; ; ;Poils de plumes ;Contact aléatoire tous règnes confondus ;4d331cae-65e4-4948-b0b2-a11bc5bb46c2 ; 1 ;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins ;57b7d0f2-4183-4b7b-8f08-6e105d476dc5 ; 1 ; ; ; ; 100 ;Inventoriel ;OBS ; ;Galerie/terrier ;Non renseigné ;Non renseigné ;Non renseigné ;Sauvage ;Oui ;Précise ;Juvénile ;Femelle ;Individu ;Compté ;Non sensible - Diffusion précise ;Présent ;Non ;Terrain ;Géoréférencement ;Autre méthode de détermination ;Non renseigné ; ;2f92f91a-64a2-4684-90e4-140466bb34e3 ;5937d0f2-c96d-424b-bea4-9e3fdac894ed ;2021-01-11 14:20:46.492497 ;2021-01-11 14:20:46.492497
-duplicate id ; 30 ; 40 ;Relevé n°4 ;Occurrence n°4 ;2017-01-08 ;2017-01-08 ;20:00:00 ;23:00:00 ; 67111 ; 67111 ;Alburnus alburnus (Linnaeus, 1758) ;Ablette ;Ablette ;Animalia ;Chordés ;Poissons ;Actinopterygii ;Cypriniformes ;Leuciscidae ;ES ; 1 ; 1 ; 1600 ; 1600 ; ; ;Administrateur test ;Donovan ;Vallouise-Pelvoux ;POINT(6.5 44.85) ; 6.5 ; 44.85 ; ; ;En attente de validation ; ; ; ;Poils de plumes ;Contact aléatoire tous règnes confondus ;4d331cae-65e4-4948-b0b2-a11bc5bb46c2 ; 1 ;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins ;57b7d0f2-4183-4b7b-8f08-6e105d476dc5 ; 1 ; ; ; ; 100 ;Inventoriel ;OBS ; ;Galerie/terrier ;Non renseigné ;Non renseigné ;Non renseigné ;Sauvage ;Oui ;Précise ;Juvénile ;Femelle ;Individu ;Compté ;Non sensible - Diffusion précise ;Présent ;Non ;Terrain ;Géoréférencement ;Autre méthode de détermination ;Non renseigné ; ;2f92f91a-64a2-4684-90e4-140466bb34e4 ;5937d0f2-c96d-424b-bea4-9e3fdac894ed ;2021-01-11 14:20:46.492497 ;2021-01-11 14:20:46.492497
-count min > count max ; 50 ; 50 ;Relevé n°5 ;Occurrence n°5 ;2017-01-08 ;2017/01/08 ;20:00 ;23:00:00 ; 67111 ; 67111 ;Alburnus alburnus (Linnaeus, 1758) ;Ablette ;Ablette ;Animalia ;Chordés ;Poissons ;Actinopterygii ;Cypriniformes ;Leuciscidae ;ES ; 20 ; 5 ; 1600 ; 1600 ; ; ;Administrateur test ;Donovan ;Vallouise-Pelvoux ;POINT(6.5 44.85) ; 6.5 ; 44.85 ; ; ;En attente de validation ; ; ; ;Poils de plumes ;Contact aléatoire tous règnes confondus ;4d331cae-65e4-4948-b0b2-a11bc5bb46c2 ; 1 ;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins ;57b7d0f2-4183-4b7b-8f08-6e105d476dc5 ; 1 ; ; ; ; 100 ;Inventoriel ;OBS ; ;Galerie/terrier ;Non renseigné ;Non renseigné ;Non renseigné ;Sauvage ;Oui ;Précise ;Juvénile ;Femelle ;Individu ;Compté ;Non sensible - Diffusion précise ;Présent ;Non ;Terrain ;Géoréférencement ;Autre méthode de détermination ;Non renseigné ; ;2f92f91a-64a2-4684-90e4-140466bb34e5 ;5937d0f2-c96d-424b-bea4-9e3fdac894ed ;2021-01-11 14:20:46.492497 ;2021-01-11 14:20:46.492497
-valid ; 60 ; 60 ;Relevé n°6 ;Occurrence n°6 ;2017-01-01 ;2017-01-01 ;12:05:02 ;12:05:02 ; 351 ; 351 ;Rana temporaria Linnaeus, 1758 ;Grenouille rousse (La) ;Grenouille rousse ;Animalia ;Chordés ;Amphibiens ;Amphibia ;Anura ;Ranidae ;ES ; 1 ; 1 ; 1600 ; 1600 ; ; ;Administrateur test ;Donovan ;Vallouise-Pelvoux ;POINT(6.5 44.75) ; 6.5 ; 44.85 ; ; ;En attente de validation ; ; ; ;Poils de plumes ;Contact aléatoire tous règnes confondus ;4d331cae-65e4-4948-b0b2-a11bc5bb46c2 ; 1 ;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins ;57b7d0f2-4183-4b7b-8f08-6e105d476dc5 ; 1 ; ; ; ; 100 ;Inventoriel ;OBS ; ;Galerie/terrier ;Non renseigné ;Non renseigné ;Non renseigné ;Sauvage ;Oui ;Précise ;Juvénile ;Femelle ;Individu ;Compté ;Non sensible - Diffusion précise ;Présent ;Non ;Terrain ;Géoréférencement ;Autre méthode de détermination ;Non renseigné ; ;f5515e2a-b30d-11eb-8cc8-af8c2d0867b4 ;5937d0f2-c96d-424b-bea4-9e3fdac894ed ;2021-01-11 14:20:46.492497 ;2021-01-11 14:20:46.492497
diff --git a/backend/geonature/tests/imports/files/synthese/valid_file_importable.csv b/backend/geonature/tests/imports/files/synthese/valid_file_importable.csv
new file mode 100644
index 0000000000..d5d1739108
--- /dev/null
+++ b/backend/geonature/tests/imports/files/synthese/valid_file_importable.csv
@@ -0,0 +1,7 @@
+error;id_synthese;id_origine;comment_releve;comment_occurrence;date_debut;date_fin;heure_debut;heure_fin;cd_nom;cd_ref;nom_valide;nom_vernaculaire;nom_cite;regne;group1_inpn;group2_inpn;classe;ordre;famille;rang_taxo;nombre_min;nombre_max;alti_min;alti_max;prof_min;prof_max;observateurs;determinateur;communes;geometrie_wkt_4326;x_centroid_4326;y_centroid_4326;nom_lieu;validateur;niveau_validation;date_validation;comment_validation;preuve_numerique_url;preuve_non_numerique;jdd_nom;jdd_uuid;jdd_id;ca_nom;ca_uuid;ca_id;cd_habref;cd_habitat;nom_habitat;precision_geographique;nature_objet_geo;type_regroupement;methode_regroupement;technique_observation;biologique_statut;etat_biologique;biogeographique_statut;naturalite;preuve_existante;niveau_precision_diffusion;stade_vie;sexe;objet_denombrement;type_denombrement;niveau_sensibilite;statut_observation;floutage_dee;statut_source;type_info_geo;methode_determination;comportement;reference_biblio;uuid_perm_sinp;uuid_perm_grp_sinp;date_creation;date_modification
+valid;10;10;Relevé n°1;Occurrence n°1;2017-01-01;2017-01-01;12:05:02;12:05:02;60612;60612;Lynx lynx (Linnaeus, 1758);;Lynx Boréal;Animalia;Chordés;Mammifères;Mammalia;Carnivora;Felidae;ES;5;5;1500;1565;;;Administrateur test;Gil;Vallouise-Pelvoux;POINT(6.6 44.85);6.5;44.85;;;En attente de validation;;;;Poil;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Adulte;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;b4f85a2e-dd88-4cdd-aa86-f1c7370faf3f;5b427c76-bd8c-4103-a33c-884c7037aa2b;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+valid;20;20;Relevé n°2;Occurrence n°2;2017-01-01;2017-01-02;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1500;1565;;;Administrateur test;Théo;Vallouise-Pelvoux;POINT(6.6 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Immature;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;830c93c7-288e-40f0-a17f-15fbb50e643a;5b427c76-bd8c-4103-a33c-884c7037aa2b;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+duplicate id;30;30;Relevé n°3;Occurrence n°3;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e3;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+duplicate id;30;40;Relevé n°4;Occurrence n°4;2017-01-08;2017-01-08;20:00:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e4;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+count min > count max;50;50;Relevé n°5;Occurrence n°5;2017-01-08;2017/01/08;20:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;20;5;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e5;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+valid;60;60;Relevé n°6;Occurrence n°6;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.75);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;f5515e2a-b30d-11eb-8cc8-af8c2d0867b4;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
diff --git a/backend/geonature/tests/imports/fixtures.py b/backend/geonature/tests/imports/fixtures.py
index a28ebe84d5..3e3d7f6f22 100644
--- a/backend/geonature/tests/imports/fixtures.py
+++ b/backend/geonature/tests/imports/fixtures.py
@@ -1,11 +1,28 @@
import pytest
from flask import g
import sqlalchemy as sa
+from pathlib import Path
from geonature.core.gn_commons.models import TModules
from geonature.utils.env import db
-from geonature.core.imports.models import BibFields, Destination
+from geonature.core.imports.models import BibFields, Destination, FieldMapping
+
+tests_path = Path(__file__).parent
+
+# ######################################################################################
+# Fixtures -- destination
+# ######################################################################################
+
+
+@pytest.fixture(scope="class")
+def module_code(): # provide with a default value - should bve overriden
+ return "SYNTHESE"
+
+
+@pytest.fixture(scope="class")
+def testfiles_folder(): # provide with a default value - should bve overriden
+ return "synthese"
@pytest.fixture(scope="session")
@@ -24,16 +41,16 @@ def set_default_destination(endpoint, values):
values["destination"] = g.default_destination.code
-@pytest.fixture(scope="session")
-def synthese_destination():
+@pytest.fixture(scope="class")
+def import_destination(module_code):
return Destination.query.filter(
- Destination.module.has(TModules.module_code == "SYNTHESE")
+ Destination.module.has(TModules.module_code == module_code)
).one()
@pytest.fixture(scope="class")
-def default_synthese_destination(app, default_destination, synthese_destination):
- g.default_destination = synthese_destination
+def default_import_destination(app, default_destination, import_destination):
+ g.default_destination = import_destination
yield
del g.default_destination
@@ -65,13 +82,431 @@ def all_modules_destination(list_all_module_dest_code):
return dict_modules_dest
+# ######################################################################################
+# Fixtures -- datasets
+# ######################################################################################
+
+from geonature.tests.utils import set_logged_user, unset_logged_user
+from flask import g, url_for
+from geonature.core.gn_meta.models import TDatasets, TAcquisitionFramework
+from pypnnomenclature.models import TNomenclatures, BibNomenclaturesTypes
+from geonature.core.imports.models import (
+ TImports,
+ BibFields,
+)
+
+
+@pytest.fixture()
+def import_file_name():
+ return "valid_file.csv"
+
+
+@pytest.fixture()
+def import_dataset(import_datasets):
+ return import_datasets["user"]
+
+
+def create_dataset(client, module_code, user, active=True, private=False):
+ """ """
+ set_logged_user(client, user)
+
+ # Generate acquisition framework
+ r_af = client.post(
+ url_for("gn_meta.create_acquisition_framework"),
+ json={
+ "acquisition_framework_name": "import_AF",
+ "acquisition_framework_desc": "import_AF description",
+ },
+ )
+ assert r_af.status_code == 200, r_af.data
+ new_acquisition_framework = db.session.get(
+ TAcquisitionFramework, r_af.get_json()["id_acquisition_framework"]
+ )
+
+ # Get module
+ r_module = client.get(url_for("gn_commons.get_module", module_code=module_code))
+ assert r_module.status_code == 200
+
+ modules = [
+ r_module.get_json(),
+ ]
+
+ # Get principal actor
+ id_principal_actor_role = db.session.execute(
+ sa.select(TNomenclatures.id_nomenclature)
+ .join(BibNomenclaturesTypes, BibNomenclaturesTypes.mnemonique == "ROLE_ACTEUR")
+ .where(
+ TNomenclatures.mnemonique == "Contact principal",
+ )
+ ).scalar_one()
+ cor_dataset_actor = [
+ {
+ "id_nomenclature_actor_role": id_principal_actor_role,
+ "id_role": user.id_role,
+ }
+ ]
+
+ # Get default data origin
+ id_nomenclature_data_origin = None
+ if private:
+ id_nomenclature_data_origin = db.session.execute(
+ sa.select(TNomenclatures.id_nomenclature).where(
+ TNomenclatures.nomenclature_type.has(
+ BibNomenclaturesTypes.mnemonique == "DS_PUBLIQUE"
+ ),
+ TNomenclatures.mnemonique == "Privée",
+ )
+ ).scalar_one()
+
+ # Get territory metropole
+ territory_metropole = db.session.execute(
+ sa.select(TNomenclatures).where(
+ TNomenclatures.nomenclature_type.has(BibNomenclaturesTypes.mnemonique == "TERRITOIRE"),
+ TNomenclatures.cd_nomenclature == "METROP",
+ )
+ ).scalar_one()
+
+ json = {
+ "id_acquisition_framework": new_acquisition_framework.id_acquisition_framework,
+ "dataset_name": "import_dataset",
+ "dataset_shortname": "import_dataset",
+ "dataset_desc": "import_dataset description",
+ "keywords": None,
+ "terrestrial_domain": True,
+ "marine_domain": False,
+ "id_nomenclature_data_origin": id_nomenclature_data_origin,
+ "validable": True,
+ "active": active,
+ "id_taxa_list": None,
+ "modules": modules,
+ "cor_territories": [territory_metropole.as_dict()],
+ "cor_dataset_actor": cor_dataset_actor,
+ }
+
+ response = client.post(
+ url_for("gn_meta.create_dataset"),
+ json=json,
+ )
+
+ return db.session.get(TDatasets, response.get_json()["id_dataset"])
+
+
+@pytest.fixture()
+def import_datasets(client, module_code, users):
+ datasets = {
+ "user": create_dataset(client, module_code, users["user"]),
+ "user--private": create_dataset(client, module_code, users["user"], private=True),
+ "user--inactive": create_dataset(client, module_code, users["user"], active=False),
+ "admin": create_dataset(client, module_code, users["admin_user"]),
+ }
+ return datasets
+
+
+# ######################################################################################
+# Fixtures -- fieldmapping
+# ######################################################################################
+
+
@pytest.fixture()
-def display_unique_dataset_id():
+def fieldmapping_unique_dataset_id(import_dataset):
+ None
+
+
+@pytest.fixture(scope="class")
+def fieldmapping_preset_name():
+ return "Synthese GeoNature"
+
+
+@pytest.fixture()
+def fieldmapping(
+ import_file_name,
+ autogenerate,
+ import_dataset,
+ fieldmapping_unique_dataset_id,
+ fieldmapping_preset_name,
+):
+ fieldmapping = {}
+ if fieldmapping_preset_name:
+ fieldmapping = (
+ db.session.execute(
+ sa.select(FieldMapping).filter_by(
+ label=fieldmapping_preset_name,
+ )
+ )
+ .unique()
+ .scalar_one()
+ .values
+ )
+ else:
+ bib_fields = db.session.scalars(sa.select(BibFields).filter_by(display=True)).unique().all()
+ fieldmapping = {
+ field.name_field: {
+ "column_src": (
+ autogenerate
+ if field.autogenerated
+ else (
+ [field.name_field, "additional_data2"] if field.multi else field.name_field
+ )
+ )
+ }
+ for field in bib_fields
+ }
+
+ if fieldmapping_unique_dataset_id:
+ fieldmapping["unique_dataset_id"] = fieldmapping_unique_dataset_id
+
+ return fieldmapping
+
+
+# ######################################################################################
+# Fixtures -- contentmapping
+# ######################################################################################
+from sqlalchemy.orm import joinedload
+
+
+@pytest.fixture(scope="class")
+def contentmapping_preset_name():
+ return "Nomenclatures SINP (labels)"
+
+
+@pytest.fixture(scope="function")
+def add_in_contentmapping():
+ return {"STADE_VIE": {"": "17"}} # Alevin
+
+
+@pytest.fixture(scope="function")
+def contentmapping(add_in_contentmapping, import_destination, contentmapping_preset_name):
+ contentmapping = {}
+ if contentmapping_preset_name is not None:
+ contentmapping = (
+ db.session.scalars(
+ sa.select(ContentMapping).filter_by(label=contentmapping_preset_name)
+ )
+ .unique()
+ .one()
+ .values
+ )
+ else:
+ fields = (
+ db.session.scalars(
+ sa.select(BibFields)
+ .filter_by(destination=import_destination, display=True)
+ .filter(BibFields.nomenclature_type != None)
+ .options(
+ joinedload(BibFields.nomenclature_type).joinedload(
+ BibNomenclaturesTypes.nomenclatures
+ ),
+ )
+ )
+ .unique()
+ .all()
+ )
+ contentmapping = {
+ field.nomenclature_type.mnemonique: {
+ **{
+ nomenclature.mnemonique: nomenclature.cd_nomenclature
+ for nomenclature in field.nomenclature_type.nomenclatures
+ },
+ **{
+ nomenclature.cd_nomenclature: nomenclature.cd_nomenclature
+ for nomenclature in field.nomenclature_type.nomenclatures
+ },
+ }
+ for field in fields
+ }
+
+ for entry, value in add_in_contentmapping.items():
+ if contentmapping[entry]:
+ contentmapping[entry].update(value)
+
+ return contentmapping
+
+
+# ######################################################################################
+# Fixtures -- override config value
+# ######################################################################################
+from apptax.taxonomie.models import BibListes, Taxref
+
+
+@pytest.fixture()
+def small_batch(monkeypatch):
+ monkeypatch.setitem(current_app.config["IMPORT"], "DATAFRAME_BATCH_SIZE", 10)
+
+
+@pytest.fixture
+def check_private_jdd(monkeypatch):
+ monkeypatch.setitem(current_app.config["IMPORT"], "CHECK_PRIVATE_JDD_BLURING", True)
+
+
+@pytest.fixture()
+def no_default_nomenclatures(monkeypatch):
+ monkeypatch.setitem(
+ current_app.config["IMPORT"], "FILL_MISSING_NOMENCLATURE_WITH_DEFAULT_VALUE", False
+ )
+
+
+@pytest.fixture()
+def area_restriction(monkeypatch, sample_area):
+ monkeypatch.setitem(current_app.config["IMPORT"], "ID_AREA_RESTRICTION", sample_area.id_area)
+
+
+@pytest.fixture(scope="function")
+def g_permissions():
"""
- This fixture is temporary and must be removed when the UUID of a JDD can be mapped in the
- fieldmapping step !
+ Fixture to initialize flask g variable
+ Mandatory if we want to run this test file standalone
"""
- query = (
- sa.update(BibFields).where(BibFields.name_field == "unique_dataset_id").values(display=True)
+ g._permissions_by_user = {}
+ g._permissions = {}
+
+
+@pytest.fixture()
+def sample_taxhub_list():
+ nom = Taxref.query.filter_by(cd_nom=67111).one()
+ with db.session.begin_nested():
+ taxa_list = BibListes(nom_liste="test", code_liste="test", noms=[nom])
+ db.session.add(taxa_list)
+ return taxa_list
+
+
+@pytest.fixture()
+def change_id_list_conf(monkeypatch, sample_taxhub_list):
+ monkeypatch.setitem(
+ current_app.config["IMPORT"], "ID_LIST_TAXA_RESTRICTION", sample_taxhub_list.id_liste
)
- db.session.execute(query)
+
+
+# ######################################################################################
+# Fixtures -- immport
+# ######################################################################################
+
+
+from flask import g, url_for, current_app
+from werkzeug.datastructures import Headers
+from geonature.core.imports.utils import insert_import_data_in_transient_table
+from geonature.core.imports.models import (
+ TImports,
+ FieldMapping,
+ ContentMapping,
+ BibFields,
+)
+from ref_geo.models import LAreas
+
+
+@pytest.fixture()
+def sample_area():
+ return LAreas.query.filter(LAreas.area_name == "Bouches-du-Rhône").one()
+
+
+@pytest.fixture()
+def autogenerate():
+ return True
+
+
+@pytest.fixture(scope="function")
+def override_in_importfile():
+ return {}
+
+
+@pytest.fixture(scope="class")
+def imports(import_destination, users):
+ def create_import(authors=[]):
+ with db.session.begin_nested():
+ imprt = TImports(destination=import_destination, authors=authors)
+ db.session.add(imprt)
+ return imprt
+
+ return {
+ "own_import": create_import(authors=[users["user"]]),
+ "associate_import": create_import(authors=[users["associate_user"]]),
+ "stranger_import": create_import(authors=[users["stranger_user"]]),
+ "orphan_import": create_import(),
+ }
+
+
+@pytest.fixture()
+def uploaded_import(client, import_file_name, override_in_importfile, users, testfiles_folder):
+ set_logged_user(client, users["user"])
+
+ with open(tests_path / "files" / testfiles_folder / import_file_name, "rb") as f:
+ f.seek(0)
+ data = {"file": (f, import_file_name)}
+ r = client.post(
+ url_for("import.upload_file"),
+ data=data,
+ headers=Headers({"Content-Type": "multipart/form-data"}),
+ )
+ assert r.status_code == 200, r.data
+ imprt = db.session.get(TImports, r.get_json()["id_import"])
+
+ for before, after in override_in_importfile.items():
+ imprt.source_file = imprt.source_file.replace(
+ before.encode("ascii"),
+ after.encode("ascii"),
+ )
+ return imprt
+
+
+@pytest.fixture()
+def decoded_import(client, uploaded_import):
+ set_logged_user(client, uploaded_import.authors[0])
+ r = client.post(
+ url_for(
+ "import.decode_file",
+ import_id=uploaded_import.id_import,
+ ),
+ data={
+ "encoding": "utf-8",
+ "format": "csv",
+ "srid": 4326,
+ "separator": ";",
+ },
+ )
+ assert r.status_code == 200, r.data
+ unset_logged_user(client)
+ db.session.refresh(uploaded_import)
+ return uploaded_import
+
+
+@pytest.fixture()
+def field_mapped_import(client, decoded_import, fieldmapping):
+ with db.session.begin_nested():
+ decoded_import.fieldmapping = fieldmapping
+ return decoded_import
+
+
+@pytest.fixture()
+def loaded_import(client, field_mapped_import):
+ with db.session.begin_nested():
+ field_mapped_import.source_count = insert_import_data_in_transient_table(
+ field_mapped_import
+ )
+ field_mapped_import.loaded = True
+ return field_mapped_import
+
+
+@pytest.fixture()
+def content_mapped_import(loaded_import, contentmapping):
+ loaded_import.contentmapping = contentmapping
+ db.session.flush()
+ return loaded_import
+
+
+@pytest.fixture()
+def prepared_import(client, content_mapped_import, small_batch, check_private_jdd):
+ set_logged_user(client, content_mapped_import.authors[0])
+ r = client.post(url_for("import.prepare_import", import_id=content_mapped_import.id_import))
+ assert r.status_code == 200, r.data
+ unset_logged_user(client)
+ db.session.refresh(content_mapped_import)
+ return content_mapped_import
+
+
+@pytest.fixture()
+def imported_import(client, g_permissions, prepared_import):
+ set_logged_user(client, prepared_import.authors[0])
+ r = client.post(url_for("import.import_valid_data", import_id=prepared_import.id_import))
+ assert r.status_code == 200, r.data
+ unset_logged_user(client)
+ db.session.refresh(prepared_import)
+ return prepared_import
diff --git a/backend/geonature/tests/imports/jsonschema_definitions.py b/backend/geonature/tests/imports/jsonschema_definitions.py
index edf268dff0..e453525bff 100644
--- a/backend/geonature/tests/imports/jsonschema_definitions.py
+++ b/backend/geonature/tests/imports/jsonschema_definitions.py
@@ -209,7 +209,6 @@
"detected_encoding": {"type": ["string", "null"]},
# "import_table": {"type": ["string", "null"]},
"full_file_name": {"type": ["string", "null"]},
- "id_dataset": {"type": ["integer", "null"]},
"date_create_import": {"type": "string"},
"date_update_import": {"type": "string"},
"source_count": {"type": ["integer", "null"]},
@@ -245,7 +244,6 @@
"detected_encoding",
# "import_table",
"full_file_name",
- "id_dataset",
"date_create_import",
"date_update_import",
"source_count",
diff --git a/backend/geonature/tests/imports/test_fields.py b/backend/geonature/tests/imports/test_fields.py
index 76ae983dc5..4096d17b1a 100644
--- a/backend/geonature/tests/imports/test_fields.py
+++ b/backend/geonature/tests/imports/test_fields.py
@@ -14,14 +14,14 @@
from .jsonschema_definitions import jsonschema_definitions
-@pytest.fixture()
-def dest():
- return Destination.query.filter(
- Destination.module.has(TModules.module_code == "SYNTHESE")
- ).one()
+@pytest.fixture(scope="class")
+def module_code():
+ return "SYNTHESE"
-@pytest.mark.usefixtures("client_class", "temporary_transaction", "default_synthese_destination")
+@pytest.mark.usefixtures(
+ "client_class", "temporary_transaction", "default_import_destination", "module_code"
+)
class TestFields:
def test_fields(self, users):
assert self.client.get(url_for("import.get_fields")).status_code == Unauthorized.code
diff --git a/backend/geonature/tests/imports/test_imports_occhab.py b/backend/geonature/tests/imports/test_imports_occhab.py
index 4865cde719..16c08db7fb 100644
--- a/backend/geonature/tests/imports/test_imports_occhab.py
+++ b/backend/geonature/tests/imports/test_imports_occhab.py
@@ -26,6 +26,7 @@
from geonature.core.imports.models import Destination, TImports, BibFields
from geonature.tests.imports.utils import assert_import_errors
+from geonature.tests.utils import set_logged_user, unset_logged_user
occhab = pytest.importorskip("gn_module_occhab")
@@ -33,199 +34,69 @@
from gn_module_occhab.models import Station, OccurenceHabitat
-test_files_path = Path(__file__).parent / "files" / "occhab"
+# ######################################################################################
+# Fixtures -- override default values
+# ######################################################################################
-@pytest.fixture(scope="session")
-def occhab_destination():
- return Destination.query.filter(Destination.module.has(TModules.module_code == "OCCHAB")).one()
+@pytest.fixture(scope="class")
+def testfiles_folder(): # provide with a default value - should bve overriden
+ return "occhab"
@pytest.fixture(scope="class")
-def default_occhab_destination(app, default_destination, occhab_destination):
- """
- This fixture set "occhab" as default destination when not specified in call to url_for.
- """
- g.default_destination = occhab_destination
- yield
- del g.default_destination
+def module_code():
+ return "OCCHAB"
-@pytest.fixture()
-def fieldmapping(occhab_destination):
- fields = (
- db.session.scalars(
- sa.select(BibFields).filter_by(destination=occhab_destination, display=True)
- )
- .unique()
- .all()
- )
- return {field.name_field: {"column_src": field.name_field} for field in fields}
+@pytest.fixture(scope="class")
+def fieldmapping_preset_name():
+ return ""
@pytest.fixture()
-def contentmapping(occhab_destination):
- """
- This content mapping matches cd_nomenclature AND mnemonique.
- """
- fields = (
- db.session.scalars(
- sa.select(BibFields)
- .filter_by(destination=occhab_destination, display=True)
- .filter(BibFields.nomenclature_type != None)
- .options(
- joinedload(BibFields.nomenclature_type).joinedload(
- BibNomenclaturesTypes.nomenclatures
- ),
- )
- )
- .unique()
- .all()
- )
- return {
- field.nomenclature_type.mnemonique: {
- **{
- nomenclature.mnemonique: nomenclature.cd_nomenclature
- for nomenclature in field.nomenclature_type.nomenclatures
- },
- **{
- nomenclature.cd_nomenclature: nomenclature.cd_nomenclature
- for nomenclature in field.nomenclature_type.nomenclatures
- },
- }
- for field in fields
- }
+def autogenerate():
+ return False
-@pytest.fixture()
-def uploaded_import(
- client,
- users,
- datasets,
+@pytest.fixture(scope="function")
+def override_in_importfile(
+ import_datasets,
station,
station_stranger_dataset,
- habitat,
- import_file_name,
- display_unique_dataset_id,
coord_station_test_file,
+ habitat,
):
- with open(test_files_path / import_file_name, "rb") as f:
- test_file_line_count = sum(1 for line in f) - 1 # remove headers
- f.seek(0)
- content = f.read()
- content = content.replace(
- b"EXISTING_STATION_UUID",
- station.unique_id_sinp_station.hex.encode("ascii"),
- )
- content = content.replace(
- b"STRANGER_STATION_UUID",
- station_stranger_dataset.unique_id_sinp_station.hex.encode("ascii"),
- )
- content = content.replace(
- b"EXISTING_HABITAT_UUID",
- habitat.unique_id_sinp_hab.hex.encode("ascii"),
- )
- content = content.replace(
- b"VALID_DATASET_UUID",
- datasets["own_dataset"].unique_dataset_id.hex.encode("ascii"),
- )
- content = content.replace(
- b"FORBIDDEN_DATASET_UUID",
- datasets["orphan_dataset"].unique_dataset_id.hex.encode("ascii"),
- )
- content = content.replace(
- b"INACTIVE_DATASET_UUID",
- datasets["own_dataset_not_activated"].unique_dataset_id.hex.encode("ascii"),
- )
- content = content.replace(
- b"COORD_STATION",
- to_wkt(coord_station_test_file[0]).encode("ascii"),
- )
-
- f = BytesIO(content)
- data = {
- "file": (f, import_file_name),
- "datasetId": datasets["own_dataset"].id_dataset,
- }
- with logged_user(client, users["user"]):
- r = client.post(
- url_for("import.upload_file"),
- data=data,
- headers=Headers({"Content-Type": "multipart/form-data"}),
- )
- assert r.status_code == 200, r.data
- return TImports.query.get(r.json["id_import"])
-
-
-@pytest.fixture()
-def decoded_import(client, uploaded_import):
- imprt = uploaded_import
- with logged_user(client, imprt.authors[0]):
- r = client.post(
- url_for("import.decode_file", import_id=imprt.id_import),
- data={"encoding": "utf-8", "format": "csv", "srid": 4326, "separator": ";"},
- )
- assert r.status_code == 200, r.data
- db.session.refresh(imprt)
- return imprt
-
-
-@pytest.fixture()
-def field_mapped_import(client, decoded_import, fieldmapping):
- imprt = decoded_import
- with logged_user(client, imprt.authors[0]):
- r = client.post(
- url_for("import.set_import_field_mapping", import_id=imprt.id_import),
- data=fieldmapping,
- )
- assert r.status_code == 200, r.data
- db.session.refresh(imprt)
- return imprt
+ return {
+ "@EXISTING_STATION_UUID@": str(station.unique_id_sinp_station),
+ "@STRANGER_STATION_UUID@": str(station_stranger_dataset.unique_id_sinp_station),
+ "@EXISTING_HABITAT_UUID@": str(habitat.unique_id_sinp_hab),
+ "@VALID_DATASET_UUID@": str(import_datasets["user"].unique_dataset_id),
+ "@FORBIDDEN_DATASET_UUID@": str(import_datasets["admin"].unique_dataset_id),
+ "@INACTIVE_DATASET_UUID@": str(import_datasets["user--inactive"].unique_dataset_id),
+ "@DATASET_NOT_FOUND@": "03905a03-c7fa-4642-b143-5005fa805377",
+ "@COORD_STATION@": to_wkt(coord_station_test_file[0]),
+ }
-@pytest.fixture()
-def loaded_import(client, field_mapped_import, fieldmapping):
- imprt = field_mapped_import
- with logged_user(client, imprt.authors[0]):
- r = client.post(url_for("import.load_import", import_id=imprt.id_import))
- assert r.status_code == 200, r.data
- db.session.refresh(imprt)
- return imprt
+@pytest.fixture(scope="class")
+def contentmapping_preset_name():
+ return None
-@pytest.fixture()
-def content_mapped_import(client, loaded_import, contentmapping):
- imprt = loaded_import
- with logged_user(client, imprt.authors[0]):
- r = client.post(
- url_for("import.set_import_content_mapping", import_id=imprt.id_import),
- data=contentmapping,
- )
- assert r.status_code == 200, r.data
- db.session.refresh(imprt)
- return imprt
+@pytest.fixture(scope="function")
+def add_in_contentmapping():
+ return {}
@pytest.fixture()
-def prepared_import(client, content_mapped_import):
- imprt = content_mapped_import
- with logged_user(client, imprt.authors[0]):
- r = client.post(url_for("import.prepare_import", import_id=imprt.id_import))
- assert r.status_code == 200, r.data
- db.session.refresh(imprt)
- assert imprt.processed is True
- return imprt
+def no_default_uuid(monkeypatch):
+ monkeypatch.setitem(current_app.config["IMPORT"], "DEFAULT_GENERATE_MISSING_UUID", False)
-@pytest.fixture()
-def imported_import(client, prepared_import):
- imprt = prepared_import
-
- with logged_user(client, imprt.authors[0]):
- r = client.post(url_for("import.import_valid_data", import_id=imprt.id_import))
- assert r.status_code == 200, r.data
- db.session.refresh(imprt)
- return imprt
+# ######################################################################################
+# Fixtures -- station
+# ######################################################################################
@pytest.fixture(scope="function")
@@ -239,9 +110,9 @@ def coord_station():
@pytest.fixture(scope="function")
-def station(datasets, coord_station):
+def station(import_datasets, coord_station):
station = Station(
- id_dataset=datasets["own_dataset"].id_dataset,
+ id_dataset=import_datasets["user"].id_dataset,
date_min=datetime.strptime("17/11/2023", "%d/%m/%Y"),
geom_4326=from_shape(*coord_station),
)
@@ -251,9 +122,9 @@ def station(datasets, coord_station):
@pytest.fixture(scope="function")
-def station_stranger_dataset(datasets, coord_station):
+def station_stranger_dataset(import_datasets, coord_station):
station = Station(
- id_dataset=datasets["stranger_dataset"].id_dataset,
+ id_dataset=import_datasets["admin"].id_dataset,
date_min=datetime.strptime("17/11/2023", "%d/%m/%Y"),
geom_4326=from_shape(*coord_station),
)
@@ -262,6 +133,11 @@ def station_stranger_dataset(datasets, coord_station):
return station
+# ######################################################################################
+# Fixtures -- habitat
+# ######################################################################################
+
+
@pytest.fixture(scope="function")
def habitat(station):
habitat = OccurenceHabitat(
@@ -277,21 +153,25 @@ def habitat(station):
return habitat
-@pytest.fixture()
-def no_default_uuid(monkeypatch):
- monkeypatch.setitem(current_app.config["IMPORT"], "DEFAULT_GENERATE_MISSING_UUID", False)
+# ######################################################################################
+# TestImportsOcchab
+# ######################################################################################
@pytest.mark.usefixtures(
"client_class",
"temporary_transaction",
"celery_eager",
- "default_occhab_destination",
+ "import_destination",
+ "default_import_destination",
+ "module_code",
+ "fieldmapping_preset_name",
+ "testfiles_folder",
+ "contentmapping_preset_name",
)
class TestImportsOcchab:
- @pytest.mark.parametrize("import_file_name", ["valid_file.csv"])
- def test_import_valid_file(self, imported_import):
+ def test_import_valid_file(self, datasets, imported_import):
assert_import_errors(
imported_import,
{
@@ -562,7 +442,6 @@ def test_import_without_default_uuid(self, no_default_uuid, imported_import):
== imported_import.statistics["habitat_count"]
)
- @pytest.mark.parametrize("import_file_name", ["valid_file.csv"])
def test_remove_import_with_manual_children(self, client, users, imported_import):
"""
This test verifies that it is not possible to remove an import if an imported entity
@@ -586,7 +465,6 @@ def test_remove_import_with_manual_children(self, client, users, imported_import
assert str(station.id_station) in r.json["description"]
assert str(habitat.id_habitat) in r.json["description"]
- @pytest.mark.parametrize("import_file_name", ["valid_file.csv"])
def test_bbox_computation(
self,
imported_import,
@@ -610,7 +488,6 @@ def test_bbox_computation(
],
}
- @pytest.mark.parametrize("import_file_name", ["valid_file.csv"])
def test_bbox_computation_transient(
self,
prepared_import,
diff --git a/backend/geonature/tests/imports/test_imports_synthese.py b/backend/geonature/tests/imports/test_imports_synthese.py
index b7308bd313..f8cac9b1a2 100644
--- a/backend/geonature/tests/imports/test_imports_synthese.py
+++ b/backend/geonature/tests/imports/test_imports_synthese.py
@@ -23,7 +23,7 @@
)
from geonature.core.gn_permissions.models import PermAction, Permission, PermObject
from geonature.core.gn_commons.models import TModules
-from geonature.core.gn_meta.models import TDatasets
+from geonature.core.gn_meta.models import TDatasets, TAcquisitionFramework
from geonature.core.gn_synthese.models import Synthese
from geonature.tests.fixtures import synthese_data, celery_eager
@@ -34,16 +34,12 @@
from geonature.core.imports.models import (
TImports,
- FieldMapping,
ContentMapping,
- BibFields,
)
-from geonature.core.imports.utils import insert_import_data_in_transient_table
from .jsonschema_definitions import jsonschema_definitions
from .utils import assert_import_errors as _assert_import_errors
-
tests_path = Path(__file__).parent
valid_file_expected_errors = {
@@ -60,249 +56,73 @@ def assert_import_errors(imprt, expected_errors):
return _assert_import_errors(imprt, expected_errors, entity_code="observation")
-@pytest.fixture(scope="class")
-def g_permissions():
- """
- Fixture to initialize flask g variable
- Mandatory if we want to run this test file standalone
- """
- g._permissions_by_user = {}
- g._permissions = {}
-
-
-@pytest.fixture()
-def sample_area():
- return LAreas.query.filter(LAreas.area_name == "Bouches-du-Rhône").one()
-
-
-@pytest.fixture(scope="function")
-def imports(synthese_destination, users):
- def create_import(authors=[]):
- with db.session.begin_nested():
- imprt = TImports(destination=synthese_destination, authors=authors)
- db.session.add(imprt)
- return imprt
-
- return {
- "own_import": create_import(authors=[users["user"]]),
- "associate_import": create_import(authors=[users["associate_user"]]),
- "stranger_import": create_import(authors=[users["stranger_user"]]),
- "orphan_import": create_import(),
- }
-
-
-@pytest.fixture()
-def small_batch(monkeypatch):
- monkeypatch.setitem(current_app.config["IMPORT"], "DATAFRAME_BATCH_SIZE", 3)
-
-
-@pytest.fixture
-def check_private_jdd(monkeypatch):
- monkeypatch.setitem(current_app.config["IMPORT"], "CHECK_PRIVATE_JDD_BLURING", True)
-
-
-@pytest.fixture()
-def no_default_nomenclatures(monkeypatch):
- monkeypatch.setitem(
- current_app.config["IMPORT"], "FILL_MISSING_NOMENCLATURE_WITH_DEFAULT_VALUE", False
- )
-
-
-@pytest.fixture()
-def area_restriction(monkeypatch, sample_area):
- monkeypatch.setitem(current_app.config["IMPORT"], "ID_AREA_RESTRICTION", sample_area.id_area)
-
-
-@pytest.fixture()
-def import_file_name():
- return "valid_file.csv"
-
-
-@pytest.fixture()
-def autogenerate():
- return True
-
-
-@pytest.fixture()
-def import_dataset(datasets, import_file_name):
- ds = datasets["own_dataset"]
- if import_file_name == "nomenclatures_file.csv":
- previous_data_origin = ds.nomenclature_data_origin
- ds.nomenclature_data_origin = TNomenclatures.query.filter(
- TNomenclatures.nomenclature_type.has(BibNomenclaturesTypes.mnemonique == "DS_PUBLIQUE"),
- TNomenclatures.mnemonique == "Privée",
- ).one()
- yield ds
- if import_file_name == "nomenclatures_file.csv":
- ds.nomenclature_data_origin = previous_data_origin
-
-
-@pytest.fixture()
-def new_import(synthese_destination, users, import_dataset):
- with db.session.begin_nested():
- imprt = TImports(
- destination=synthese_destination,
- authors=[users["user"]],
- id_dataset=import_dataset.id_dataset,
- )
- db.session.add(imprt)
- return imprt
-
-
-@pytest.fixture()
-def uploaded_import(new_import, datasets, import_file_name):
- with db.session.begin_nested():
- with open(tests_path / "files" / "synthese" / import_file_name, "rb") as f:
- f.seek(0)
- content = f.read()
- if import_file_name == "jdd_to_import_file.csv":
- content = content.replace(
- b"VALID_DATASET_UUID",
- datasets["own_dataset"].unique_dataset_id.hex.encode("ascii"),
- )
- content = content.replace(
- b"FORBIDDEN_DATASET_UUID",
- datasets["orphan_dataset"].unique_dataset_id.hex.encode("ascii"),
- )
- content = content.replace(
- b"PRIVATE_DATASET_UUID",
- datasets["private"].unique_dataset_id.hex.encode("ascii"),
- )
- new_import.full_file_name = "jdd_to_import_file.csv"
- else:
- new_import.full_file_name = "valid_file.csv"
- new_import.source_file = content
- return new_import
-
-
-@pytest.fixture()
-def decoded_import(client, uploaded_import):
- set_logged_user(client, uploaded_import.authors[0])
- r = client.post(
- url_for(
- "import.decode_file",
- import_id=uploaded_import.id_import,
- ),
- data={
- "encoding": "utf-8",
- "format": "csv",
- "srid": 4326,
- "separator": ";",
- },
- )
- assert r.status_code == 200, r.data
- unset_logged_user(client)
- db.session.refresh(uploaded_import)
- return uploaded_import
+# ######################################################################################
+# Fixtures -- default values to be overriden
+# ######################################################################################
-@pytest.fixture()
-def fieldmapping(import_file_name, autogenerate):
- if import_file_name in ["valid_file.csv", "jdd_to_import_file.csv"]:
- return (
- db.session.execute(sa.select(FieldMapping).filter_by(label="Synthese GeoNature"))
- .unique()
- .scalar_one()
- .values
- )
- else:
- bib_fields = db.session.scalars(sa.select(BibFields).filter_by(display=True)).unique().all()
- return {
- field.name_field: {
- "column_src": (
- autogenerate
- if field.autogenerated
- else (
- [field.name_field, "additional_data2"] if field.multi else field.name_field
- )
- )
- }
- for field in bib_fields
- }
+@pytest.fixture(scope="class")
+def fieldmapping_preset_name():
+ return "Synthese GeoNature"
-@pytest.fixture()
-def field_mapped_import(client, decoded_import, fieldmapping):
- with db.session.begin_nested():
- decoded_import.fieldmapping = fieldmapping
- return decoded_import
+@pytest.fixture(scope="class")
+def contentmapping_preset_name():
+ return "Nomenclatures SINP (labels)"
-@pytest.fixture()
-def loaded_import(client, field_mapped_import):
- with db.session.begin_nested():
- field_mapped_import.source_count = insert_import_data_in_transient_table(
- field_mapped_import
- )
- field_mapped_import.loaded = True
- return field_mapped_import
+@pytest.fixture(scope="class")
+def module_code():
+ return "SYNTHESE"
-@pytest.fixture()
-def content_mapped_import(client, import_file_name, loaded_import):
- with db.session.begin_nested():
- loaded_import.contentmapping = (
- db.session.scalars(
- sa.select(ContentMapping).filter_by(label="Nomenclatures SINP (labels)")
- )
- .unique()
- .one()
- .values
- )
- if import_file_name == "empty_nomenclatures_file.csv":
- loaded_import.contentmapping["STADE_VIE"].update(
- {
- "": "17", # Alevin
- }
- )
- return loaded_import
+@pytest.fixture(scope="class")
+def testfiles_folder(): # provide with a default value - should bve overriden
+ return "synthese"
-@pytest.fixture()
-def prepared_import(client, content_mapped_import, small_batch, check_private_jdd):
- set_logged_user(client, content_mapped_import.authors[0])
- r = client.post(url_for("import.prepare_import", import_id=content_mapped_import.id_import))
- assert r.status_code == 200, r.data
- unset_logged_user(client)
- db.session.refresh(content_mapped_import)
- return content_mapped_import
+@pytest.fixture(scope="function")
+def fieldmapping_unique_dataset_id(import_dataset):
+ return {
+ "default_value": str(import_dataset.unique_dataset_id),
+ "column_src": "unique_dataset_id",
+ }
-@pytest.fixture()
-def imported_import(client, prepared_import):
- set_logged_user(client, prepared_import.authors[0])
- r = client.post(url_for("import.import_valid_data", import_id=prepared_import.id_import))
- assert r.status_code == 200, r.data
- unset_logged_user(client)
- db.session.refresh(prepared_import)
- return prepared_import
+@pytest.fixture(scope="function")
+def override_in_importfile(import_datasets):
+ return {
+ "@USER_DATASET_UUID@": str(import_datasets["user"].unique_dataset_id),
+ "@DATASET_NOT_FOUND@": "03905a03-c7fa-4642-b143-5005fa805377",
+ "@DATASET_NOT_AUTHORIZED@": str(import_datasets["admin"].unique_dataset_id),
+ "@DATASET_INACTIVE@": str(import_datasets["user--inactive"].unique_dataset_id),
+ "@PRIVATE_DATASET_UUID@": str(import_datasets["user--private"].unique_dataset_id),
+ }
@pytest.fixture()
-def sample_taxhub_list():
- nom = Taxref.query.filter_by(cd_nom=67111).one()
- with db.session.begin_nested():
- taxa_list = BibListes(nom_liste="test", code_liste="test", noms=[nom])
- db.session.add(taxa_list)
- return taxa_list
+def per_dataset_uuid_check(monkeypatch):
+ monkeypatch.setitem(current_app.config["IMPORT"], "PER_DATASET_UUID_CHECK", True)
-@pytest.fixture()
-def change_id_list_conf(monkeypatch, sample_taxhub_list):
- monkeypatch.setitem(
- current_app.config["IMPORT"], "ID_LIST_TAXA_RESTRICTION", sample_taxhub_list.id_liste
- )
+# ######################################################################################
+# Tests -- imports
+# ######################################################################################
@pytest.mark.usefixtures(
"client_class",
"temporary_transaction",
"celery_eager",
- "default_synthese_destination",
- "display_unique_dataset_id",
+ "import_destination",
+ "default_import_destination",
+ "module_code",
+ "fieldmapping_preset_name",
+ "testfiles_folder",
+ "contentmapping_preset_name",
)
class TestImportsSynthese:
- def test_import_permissions(self, g_permissions, synthese_destination):
+ def test_import_permissions(self, g_permissions, import_destination):
with db.session.begin_nested():
organisme = Organisme(nom_organisme="test_import")
db.session.add(organisme)
@@ -319,7 +139,7 @@ def test_import_permissions(self, g_permissions, synthese_destination):
user.groups.append(group)
- imprt = TImports(destination=synthese_destination)
+ imprt = TImports(destination=import_destination)
db.session.add(imprt)
get_scopes_by_action = partial(
@@ -416,7 +236,7 @@ def test_import_permissions(self, g_permissions, synthese_destination):
assert scope == 3
assert imprt.has_instance_permission(scope, user=user, action_code="U") is True
- # Should be always true
+ # Should be always True
assert imprt.has_instance_permission(scope, user=user, action_code="R") is True
def test_list_imports(self, imports, users):
@@ -460,16 +280,6 @@ def test_order_import(self, users, imports, uploaded_import):
import_ids_asc = [imprt["id_import"] for imprt in r_asc.get_json()["imports"]]
assert import_ids_des == import_ids_asc[-1::-1]
- def test_order_import_foreign(self, users, imports, uploaded_import):
- set_logged_user(self.client, users["user"])
- response = self.client.get(url_for("import.get_import_list") + "?sort=dataset.dataset_name")
- assert response.status_code == 200, response.data
- imports = response.get_json()["imports"]
- for a, b in zip(imports[:1], imports[1:]):
- assert (a["dataset"] is None) or (
- a["dataset"]["dataset_name"] <= b["dataset"]["dataset_name"]
- )
-
def test_get_import(self, users, imports):
def get(import_name):
return self.client.get(
@@ -511,11 +321,11 @@ def test_delete_import(self, users, imported_import):
)
assert transient_rows_count == 0
- def test_import_upload(self, users, datasets):
+ def test_import_upload(self, users):
+
with open(tests_path / "files" / "synthese" / "simple_file.csv", "rb") as f:
data = {
"file": (f, "simple_file.csv"),
- "datasetId": datasets["own_dataset"].id_dataset,
}
r = self.client.post(
url_for("import.upload_file"),
@@ -528,7 +338,6 @@ def test_import_upload(self, users, datasets):
with open(tests_path / "files" / "synthese" / "simple_file.csv", "rb") as f:
data = {
"file": (f, "simple_file.csv"),
- "datasetId": datasets["own_dataset"].id_dataset,
}
r = self.client.post(
url_for("import.upload_file"),
@@ -539,39 +348,8 @@ def test_import_upload(self, users, datasets):
assert "has no permissions to C in IMPORT" in r.json["description"]
set_logged_user(self.client, users["user"])
-
- unexisting_id = db.session.query(func.max(TDatasets.id_dataset)).scalar() + 1
with open(tests_path / "files" / "synthese" / "simple_file.csv", "rb") as f:
- data = {
- "file": (f, "simple_file.csv"),
- "datasetId": unexisting_id,
- }
- r = self.client.post(
- url_for("import.upload_file"),
- data=data,
- headers=Headers({"Content-Type": "multipart/form-data"}),
- )
- assert r.status_code == BadRequest.code, r.data
- assert r.json["description"] == f"Dataset '{unexisting_id}' does not exist."
-
- with open(tests_path / "files" / "synthese" / "simple_file.csv", "rb") as f:
- data = {
- "file": (f, "simple_file.csv"),
- "datasetId": datasets["stranger_dataset"].id_dataset,
- }
- r = self.client.post(
- url_for("import.upload_file"),
- data=data,
- headers=Headers({"Content-Type": "multipart/form-data"}),
- )
- assert r.status_code == Forbidden.code, r.data
- assert "jeu de données" in r.json["description"] # this is a DS issue
-
- with open(tests_path / "files" / "synthese" / "simple_file.csv", "rb") as f:
- data = {
- "file": (f, "simple_file.csv"),
- "datasetId": datasets["own_dataset"].id_dataset,
- }
+ data = {"file": (f, "simple_file.csv")}
r = self.client.post(
url_for("import.upload_file"),
data=data,
@@ -583,13 +361,10 @@ def test_import_upload(self, users, datasets):
assert imprt.source_file is not None
assert imprt.full_file_name == "simple_file.csv"
- def test_import_error(self, users, datasets):
+ def test_import_error(self, users, import_datasets):
set_logged_user(self.client, users["user"])
with open(tests_path / "files" / "synthese" / "empty.csv", "rb") as f:
- data = {
- "file": (f, "empty.csv"),
- "datasetId": datasets["own_dataset"].id_dataset,
- }
+ data = {"file": (f, "empty.csv")}
r = self.client.post(
url_for("import.upload_file"),
data=data,
@@ -597,11 +372,9 @@ def test_import_error(self, users, datasets):
)
assert r.status_code == 400, r.data
assert r.json["description"] == "Impossible to upload empty files"
+
with open(tests_path / "files" / "synthese" / "starts_with_empty_line.csv", "rb") as f:
- data = {
- "file": (f, "starts_with_empty_line.csv"),
- "datasetId": datasets["own_dataset"].id_dataset,
- }
+ data = {"file": (f, "starts_with_empty_line.csv")}
r = self.client.post(
url_for("import.upload_file"),
data=data,
@@ -618,7 +391,6 @@ def test_import_upload_after_preparation(self, prepared_import):
with open(tests_path / "files" / "synthese" / "utf8_file.csv", "rb") as f:
data = {
"file": (f, "utf8_file.csv"),
- "datasetId": imprt.id_dataset,
}
r = self.client.put(
url_for("import.upload_file", import_id=imprt.id_import),
@@ -635,8 +407,9 @@ def test_import_upload_after_preparation(self, prepared_import):
assert imprt.columns == None
assert len(imprt.errors) == 0
- def test_import_decode(self, users, new_import):
- imprt = new_import
+ def test_import_decode(self, users, uploaded_import):
+
+ imprt = uploaded_import
data = {
"encoding": "utf-16",
"format": "csv",
@@ -644,6 +417,8 @@ def test_import_decode(self, users, new_import):
"separator": ";",
}
+ unset_logged_user(self.client)
+ db.session.flush()
r = self.client.post(url_for("import.decode_file", import_id=imprt.id_import), data=data)
assert r.status_code == Unauthorized.code, r.data
@@ -651,10 +426,13 @@ def test_import_decode(self, users, new_import):
r = self.client.post(url_for("import.decode_file", import_id=imprt.id_import), data=data)
assert r.status_code == Forbidden.code, r.data
- set_logged_user(self.client, users["user"])
+ set_logged_user(self.client, imprt.authors[0])
r = self.client.post(url_for("import.decode_file", import_id=imprt.id_import), data=data)
assert r.status_code == BadRequest.code, r.data
- assert "first upload" in r.json["description"]
+ assert (
+ "Erreur d’encodage lors de la lecture du fichier source. Avez-vous sélectionné le bon encodage de votre fichier ?"
+ == r.json["description"]
+ )
imprt.full_file_name = "import.csv"
imprt.detected_encoding = "utf-8"
@@ -692,6 +470,7 @@ def test_import_decode(self, users, new_import):
with open(tests_path / "files" / "synthese" / "utf8_file.csv", "rb") as f:
imprt.source_file = f.read()
+ db.session.flush()
r = self.client.post(url_for("import.decode_file", import_id=imprt.id_import), data=data)
assert r.status_code == 200, r.data
@@ -868,17 +647,15 @@ def test_import_errors(self, users, prepared_import):
)
assert len(r.json) == len(valid_file_expected_errors)
- def test_import_valid_file(self, users, datasets):
+ def test_import_valid_file(self, users, fieldmapping, import_file_name):
set_logged_user(self.client, users["user"])
# Upload step
- test_file_name = "valid_file.csv"
- with open(tests_path / "files" / "synthese" / test_file_name, "rb") as f:
+ with open(tests_path / "files" / "synthese" / import_file_name, "rb") as f:
test_file_line_count = sum(1 for line in f) - 1 # remove headers
f.seek(0)
data = {
- "file": (f, test_file_name),
- "datasetId": datasets["own_dataset"].id_dataset,
+ "file": (f, import_file_name),
}
r = self.client.post(
url_for("import.upload_file"),
@@ -894,8 +671,7 @@ def test_import_valid_file(self, users, datasets):
assert imprt_json["detected_encoding"] == "utf-8"
assert imprt_json["detected_format"] == "csv"
assert imprt_json["detected_separator"] == ";"
- assert imprt_json["full_file_name"] == test_file_name
- assert imprt_json["id_dataset"] == datasets["own_dataset"].id_dataset
+ assert imprt_json["full_file_name"] == import_file_name
# Decode step
data = {
@@ -926,12 +702,7 @@ def test_import_valid_file(self, users, datasets):
assert transient_rows_count == 0
# Field mapping step
- fieldmapping = (
- db.session.execute(sa.select(FieldMapping).filter_by(label="Synthese GeoNature"))
- .unique()
- .scalar_one()
- )
- fieldmapping_values = fieldmapping.values.copy()
+ fieldmapping_values = fieldmapping.copy()
fieldmapping_values.update(
{"count_max": fieldmapping_values.get("count_max", {}) | {"default_value": 5}}
)
@@ -1036,8 +807,9 @@ def test_import_valid_file(self, users, datasets):
r = self.client.delete(url_for("import.delete_import", import_id=imprt.id_import))
assert r.status_code == 200, r.data
- @pytest.mark.parametrize("import_file_name", ["geom_file.csv"])
- @pytest.mark.parametrize("autogenerate", [False])
+ @pytest.mark.parametrize(
+ "autogenerate, import_file_name,fieldmapping_preset_name", [(False, "geom_file.csv", None)]
+ )
def test_import_geometry_file(self, area_restriction, prepared_import):
assert_import_errors(
prepared_import,
@@ -1059,7 +831,7 @@ def test_import_geometry_file(self, area_restriction, prepared_import):
},
)
- @pytest.mark.parametrize("import_file_name", ["cd_file.csv"])
+ @pytest.mark.parametrize("import_file_name,fieldmapping_preset_name", [("cd_file.csv", None)])
def test_import_cd_file(self, change_id_list_conf, prepared_import):
assert_import_errors(
prepared_import,
@@ -1072,7 +844,9 @@ def test_import_cd_file(self, change_id_list_conf, prepared_import):
},
)
- @pytest.mark.parametrize("import_file_name", ["source_pk_file.csv"])
+ @pytest.mark.parametrize(
+ "import_file_name,fieldmapping_preset_name", [("source_pk_file.csv", None)]
+ )
def test_import_source_pk_file(self, prepared_import):
assert_import_errors(
prepared_import,
@@ -1085,7 +859,9 @@ def test_import_source_pk_file(self, prepared_import):
},
)
- @pytest.mark.parametrize("import_file_name", ["altitude_file.csv"])
+ @pytest.mark.parametrize(
+ "import_file_name,fieldmapping_preset_name", [("altitude_file.csv", None)]
+ )
def test_import_altitude_file(self, prepared_import):
french_dem = has_french_dem()
if french_dem:
@@ -1122,8 +898,27 @@ def test_import_altitude_file(self, prepared_import):
]
assert altitudes == expected_altitudes
- @pytest.mark.parametrize("import_file_name", ["uuid_file.csv"])
- def test_import_uuid_file(self, synthese_data, prepared_import):
+ @pytest.mark.parametrize("import_file_name,fieldmapping_preset_name", [("uuid_file.csv", None)])
+ def test_import_uuid_file_per_dataset_uuid(
+ self, per_dataset_uuid_check, import_datasets, synthese_data, prepared_import
+ ):
+ assert_import_errors(
+ prepared_import,
+ {
+ (ImportCodeError.DUPLICATE_UUID, "unique_id_sinp", frozenset([3, 4])),
+ (ImportCodeError.INVALID_UUID, "unique_id_sinp", frozenset([6])),
+ },
+ )
+ transient_table = prepared_import.destination.get_transient_table()
+ unique_id_sinp = db.session.execute(
+ select([transient_table.c.unique_id_sinp])
+ .where(transient_table.c.id_import == prepared_import.id_import)
+ .where(transient_table.c.line_no == 7)
+ ).scalar()
+ assert unique_id_sinp != None
+
+ @pytest.mark.parametrize("import_file_name,fieldmapping_preset_name", [("uuid_file.csv", None)])
+ def test_import_uuid_file(self, import_datasets, synthese_data, prepared_import):
assert_import_errors(
prepared_import,
{
@@ -1140,7 +935,7 @@ def test_import_uuid_file(self, synthese_data, prepared_import):
).scalar()
assert unique_id_sinp != None
- @pytest.mark.parametrize("import_file_name", ["dates.csv"])
+ @pytest.mark.parametrize("import_file_name,fieldmapping_preset_name", [("dates.csv", None)])
def test_import_dates_file(self, prepared_import):
assert_import_errors(
prepared_import,
@@ -1156,7 +951,9 @@ def test_import_dates_file(self, prepared_import):
},
)
- @pytest.mark.parametrize("import_file_name", ["digital_proof.csv"])
+ @pytest.mark.parametrize(
+ "import_file_name,fieldmapping_preset_name", [("digital_proof.csv", None)]
+ )
def test_import_digital_proofs_file(self, prepared_import):
assert_import_errors(
prepared_import,
@@ -1170,7 +967,7 @@ def test_import_digital_proofs_file(self, prepared_import):
},
)
- @pytest.mark.parametrize("import_file_name", ["depth.csv"])
+ @pytest.mark.parametrize("import_file_name,fieldmapping_preset_name", [("depth.csv", None)])
def test_import_depth_file(self, prepared_import):
assert_import_errors(
prepared_import,
@@ -1179,7 +976,9 @@ def test_import_depth_file(self, prepared_import):
},
)
- @pytest.mark.parametrize("import_file_name", ["nomenclatures_file.csv"])
+ @pytest.mark.parametrize(
+ "import_file_name,fieldmapping_preset_name", [("nomenclatures_file.csv", None)]
+ )
def test_import_nomenclatures_file(self, prepared_import):
assert_import_errors(
prepared_import,
@@ -1202,7 +1001,9 @@ def test_import_nomenclatures_file(self, prepared_import):
},
)
- @pytest.mark.parametrize("import_file_name", ["additional_data.csv"])
+ @pytest.mark.parametrize(
+ "import_file_name,fieldmapping_preset_name", [("additional_data.csv", None)]
+ )
def test_import_additional_data(self, imported_import):
assert_import_errors(
imported_import,
@@ -1228,7 +1029,9 @@ def test_import_additional_data(self, imported_import):
{"a": "A", "additional_data2": ""},
]
- @pytest.mark.parametrize("import_file_name", ["empty_nomenclatures_file.csv"])
+ @pytest.mark.parametrize(
+ "import_file_name,fieldmapping_preset_name", [("empty_nomenclatures_file.csv", None)]
+ )
def test_import_empty_nomenclatures_file(self, imported_import):
assert_import_errors(
imported_import,
@@ -1252,7 +1055,9 @@ def test_import_empty_nomenclatures_file(self, imported_import):
# et ne pas l’écraser avec la valeur par défaut
assert obs3.nomenclature_life_stage.label_default == "Alevin"
- @pytest.mark.parametrize("import_file_name", ["empty_nomenclatures_file.csv"])
+ @pytest.mark.parametrize(
+ "import_file_name,fieldmapping_preset_name", [("empty_nomenclatures_file.csv", None)]
+ )
def test_import_empty_nomenclatures_file_no_default(
self, no_default_nomenclatures, imported_import
):
@@ -1279,7 +1084,9 @@ def test_import_empty_nomenclatures_file_no_default(
# et ne pas l’écraser avec la valeur par défaut
assert obs3.nomenclature_life_stage.label_default == "Alevin"
- @pytest.mark.parametrize("import_file_name", ["multiline_comment_file.csv"])
+ @pytest.mark.parametrize(
+ "import_file_name,fieldmapping_preset_name", [("multiline_comment_file.csv", None)]
+ )
def test_import_multiline_comment_file(self, users, imported_import):
assert_import_errors(
imported_import,
@@ -1327,6 +1134,9 @@ def test_export_pdf_forbidden(self, users, imports):
def test_get_import_source_file(self, users, uploaded_import):
url = url_for("import.get_import_source_file", import_id=uploaded_import.id_import)
+ unset_logged_user(self.client)
+ db.session.flush()
+
resp = self.client.get(url)
assert resp.status_code == Unauthorized.code
@@ -1334,7 +1144,7 @@ def test_get_import_source_file(self, users, uploaded_import):
resp = self.client.get(url)
assert resp.status_code == Forbidden.code
- set_logged_user(self.client, users["user"])
+ set_logged_user(self.client, uploaded_import.authors[0])
resp = self.client.get(url)
assert resp.status_code == 200
assert resp.content_length > 0
@@ -1351,7 +1161,9 @@ def test_get_nomenclatures(self):
for nomenclature in resp.json.values()
)
- @pytest.mark.parametrize("import_file_name", ["multiline_comment_file.csv"])
+ @pytest.mark.parametrize(
+ "import_file_name,fieldmapping_preset_name", [("multiline_comment_file.csv", None)]
+ )
def test_import_compare_error_line_with_csv(self, users, imported_import, import_file_name):
"""
This test verify generated errors csv file contains right rows from source file.
@@ -1383,19 +1195,22 @@ def test_import_compare_error_line_with_csv(self, users, imported_import, import
# and this is the test purpose assert:
assert error_row == source_row
- @pytest.mark.parametrize("import_file_name", ["jdd_to_import_file.csv"])
+ @pytest.mark.parametrize(
+ "import_file_name",
+ [("jdd_to_import_file.csv")],
+ )
def test_import_jdd_file(self, imported_import, users):
assert_import_errors(
imported_import,
{
- # id_dataset errors
- # The line 2 should not be error (should be the one selected jdd default)
- (ImportCodeError.DATASET_NOT_AUTHORIZED, "unique_dataset_id", frozenset({2, 4, 6})),
+ (ImportCodeError.INVALID_UUID, "unique_dataset_id", frozenset({4})),
(ImportCodeError.DATASET_NOT_FOUND, "unique_dataset_id", frozenset({5})),
+ (ImportCodeError.DATASET_NOT_ACTIVE, "unique_dataset_id", frozenset({6})),
+ (ImportCodeError.DATASET_NOT_AUTHORIZED, "unique_dataset_id", frozenset({7})),
(
ImportCodeError.CONDITIONAL_MANDATORY_FIELD_ERROR,
"floutage_dee",
- frozenset({6}),
+ frozenset({8}),
),
},
)
diff --git a/backend/geonature/tests/imports/test_mappings.py b/backend/geonature/tests/imports/test_mappings.py
index 38dbab98d7..dd1171ff5d 100644
--- a/backend/geonature/tests/imports/test_mappings.py
+++ b/backend/geonature/tests/imports/test_mappings.py
@@ -25,12 +25,12 @@
@pytest.fixture()
-def mappings(synthese_destination, users):
+def mappings(import_destination, users):
mappings = {}
bib_fields = (
db.session.execute(
sa.select(BibFields.name_field, BibFields.autogenerated, BibFields.multi).filter_by(
- destination=synthese_destination, display=True
+ destination=import_destination, display=True
)
)
.unique()
@@ -50,9 +50,7 @@ def mappings(synthese_destination, users):
nomenc_bib_fields = (
db.session.scalars(
sa.select(BibFields)
- .where(
- BibFields.destination == synthese_destination, BibFields.nomenclature_type != None
- )
+ .where(BibFields.destination == import_destination, BibFields.nomenclature_type != None)
.options(
joinedload(BibFields.nomenclature_type).joinedload(
BibNomenclaturesTypes.nomenclatures
@@ -72,47 +70,47 @@ def mappings(synthese_destination, users):
}
with db.session.begin_nested():
mappings["content_public"] = ContentMapping(
- destination=synthese_destination,
+ destination=import_destination,
label="Content Mapping",
active=True,
public=True,
values=contentmapping_values,
)
mappings["field_public"] = FieldMapping(
- destination=synthese_destination,
+ destination=import_destination,
label="Public Field Mapping",
active=True,
public=True,
values=fieldmapping_values,
)
mappings["field"] = FieldMapping(
- destination=synthese_destination,
+ destination=import_destination,
label="Private Field Mapping",
active=True,
public=False,
)
mappings["field_public_disabled"] = FieldMapping(
- destination=synthese_destination,
+ destination=import_destination,
label="Disabled Public Field Mapping",
active=False,
public=True,
)
mappings["self"] = FieldMapping(
- destination=synthese_destination,
+ destination=import_destination,
label="Self’s Mapping",
active=True,
public=False,
owners=[users["self_user"]],
)
mappings["stranger"] = FieldMapping(
- destination=synthese_destination,
+ destination=import_destination,
label="Stranger’s Mapping",
active=True,
public=False,
owners=[users["stranger_user"]],
)
mappings["associate"] = FieldMapping(
- destination=synthese_destination,
+ destination=import_destination,
label="Associate’s Mapping",
active=True,
public=False,
@@ -122,7 +120,9 @@ def mappings(synthese_destination, users):
return mappings
-@pytest.mark.usefixtures("client_class", "temporary_transaction", "default_synthese_destination")
+@pytest.mark.usefixtures(
+ "client_class", "temporary_transaction", "default_import_destination", "module_code"
+)
class TestMappings:
def test_list_mappings(self, users, mappings):
set_logged_user(self.client, users["noright_user"])
@@ -302,11 +302,12 @@ def test_add_field_mapping(self, users, mappings):
assert r.status_code == BadRequest.code
r = self.client.post(url, data=fieldmapping)
- assert r.status_code == BadRequest.code # missing date_min
+ assert r.status_code == BadRequest.code # missing date_min and unique_dataset_id
fieldmapping.update(
{
"date_min": {"column_src": "date_debut"},
+ "unique_dataset_id": {"column_src": "jdd_uuid"},
}
)
r = self.client.post(url, data=fieldmapping)
diff --git a/backend/geonature/tests/test_gn_meta.py b/backend/geonature/tests/test_gn_meta.py
index a32f83cc12..6e8a499747 100644
--- a/backend/geonature/tests/test_gn_meta.py
+++ b/backend/geonature/tests/test_gn_meta.py
@@ -612,6 +612,10 @@ def test_datasets_permissions(self, app, datasets, users):
)
assert set(sc(dsc.filter_by_scope(2, query=qs)).unique().all()) == set(
[
+ # The code is attempting to access a dataset named "own_dataset" from a dictionary or list
+ # named "datasets" in Python. However, the code snippet provided is incomplete and lacks
+ # context, so it is difficult to determine the exact functionality or purpose of this code
+ # without additional information.
datasets["own_dataset"],
datasets["own_dataset_not_activated"],
datasets["associate_dataset"],
diff --git a/contrib/gn_module_occhab/backend/gn_module_occhab/imports/actions.py b/contrib/gn_module_occhab/backend/gn_module_occhab/imports/actions.py
index a0fd94a8a0..8331bf7904 100644
--- a/contrib/gn_module_occhab/backend/gn_module_occhab/imports/actions.py
+++ b/contrib/gn_module_occhab/backend/gn_module_occhab/imports/actions.py
@@ -325,7 +325,8 @@ def check_station_sql(imprt):
geom_4326_field=fields["geom_4326"],
geom_local_field=fields["geom_local"],
)
- if imprt.fieldmapping.get("altitudes_generate", False):
+ autogenerate_field = imprt.fieldmapping.get("altitudes_generate", False)
+ if autogenerate_field and autogenerate_field["column_src"]:
# TODO@TestImportsOcchab.test_import_valid_file: add testcase
generate_altitudes(
imprt,
@@ -490,8 +491,6 @@ def import_data_to_destination(imprt: TImports) -> None:
):
insert_fields |= {field}
if entity.code == "station":
- # unique_dataset_id is replaced with id_dataset
- insert_fields -= {fields["unique_dataset_id"]}
insert_fields |= {fields["id_dataset"]}
insert_fields |= {fields["geom_4326"], fields["geom_local"]}
# TODO@TestImportsOcchab.test_import_valid_file: add testcase
diff --git a/contrib/gn_module_occhab/backend/gn_module_occhab/migrations/65f77e9d4c6f_adjust_occhab_to_datasate_management_.py b/contrib/gn_module_occhab/backend/gn_module_occhab/migrations/65f77e9d4c6f_adjust_occhab_to_datasate_management_.py
new file mode 100644
index 0000000000..dfce135c57
--- /dev/null
+++ b/contrib/gn_module_occhab/backend/gn_module_occhab/migrations/65f77e9d4c6f_adjust_occhab_to_datasate_management_.py
@@ -0,0 +1,99 @@
+"""Adjust occhab to datasate management modification in import
+
+Revision ID: 65f77e9d4c6f
+Revises: e43f039b5ff1
+Create Date: 2025-01-28 11:28:51.311696
+
+"""
+
+from alembic import op
+import sqlalchemy as sa
+
+from geonature.core.imports.models import BibFields, Destination
+from sqlalchemy.dialects.postgresql import UUID
+
+# revision identifiers, used by Alembic.
+revision = "65f77e9d4c6f"
+down_revision = "e43f039b5ff1"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ op.drop_column(
+ schema="gn_imports", table_name="t_imports_occhab", column_name="unique_dataset_id"
+ )
+
+ op.execute(
+ sa.update(BibFields)
+ .where(
+ BibFields.name_field == "unique_dataset_id",
+ BibFields.id_destination == Destination.id_destination,
+ Destination.code == "occhab",
+ )
+ .values(
+ dict(
+ display=True,
+ mandatory=True,
+ type_field="dataset",
+ type_field_params=dict(bind_value="unique_dataset_id"),
+ source_field="src_unique_dataset_id",
+ dest_field=None,
+ )
+ )
+ )
+
+ op.execute(
+ sa.update(BibFields)
+ .where(
+ BibFields.name_field == "id_dataset",
+ BibFields.id_destination == Destination.id_destination,
+ Destination.code == "occhab",
+ )
+ .values(
+ dict(
+ display=False,
+ type_field="textarea",
+ mandatory=False,
+ dest_field="id_dataset",
+ source_field=None,
+ )
+ )
+ )
+
+
+def downgrade():
+ op.execute(
+ sa.update(BibFields)
+ .where(
+ BibFields.name_field == "unique_dataset_id",
+ BibFields.id_destination == Destination.id_destination,
+ Destination.code == "occhab",
+ )
+ .values(
+ dict(
+ display=False,
+ mandatory=False,
+ optional_conditions=None,
+ type_field="text",
+ type_field_params=None,
+ dest_field="unique_dataset_id",
+ )
+ )
+ )
+
+ op.execute(
+ sa.update(BibFields)
+ .where(
+ BibFields.name_field == "id_dataset",
+ BibFields.id_destination == Destination.id_destination,
+ Destination.code == "occhab",
+ )
+ .values(dict(dest_field=None))
+ )
+
+ op.add_column(
+ schema="gn_imports",
+ table_name="t_imports_occhab",
+ column=sa.Column("unique_dataset_id", UUID(as_uuid=True)),
+ )
diff --git a/frontend/cypress/e2e/import/constants/fieldsContent.js b/frontend/cypress/e2e/import/constants/fieldsContent.js
index f37b212512..e6ff931b1b 100644
--- a/frontend/cypress/e2e/import/constants/fieldsContent.js
+++ b/frontend/cypress/e2e/import/constants/fieldsContent.js
@@ -1,9 +1,4 @@
export const FIELDS_CONTENT_STEP_UPLOAD = {
- datasetField: {
- defaultValue: 'JDD-TEST-IMPORT-ADMIN',
- newValue: 'JDD-TEST-IMPORT-2',
- selector: 'ng-select',
- },
fileUploadField: {
defaultValue: 'import/synthese/valid_file_test_link_list_import_synthese.csv',
newValue: 'import/synthese/valid_file_import_synthese_test_changed.csv',
diff --git a/frontend/cypress/e2e/import/constants/filters.js b/frontend/cypress/e2e/import/constants/filters.js
index a3a6f48c41..f827566a15 100644
--- a/frontend/cypress/e2e/import/constants/filters.js
+++ b/frontend/cypress/e2e/import/constants/filters.js
@@ -1,9 +1,4 @@
export const FILTERS_TABLE = [
- {
- columnName: 'Jeu de données',
- searchTerm: ['JDD-TEST', 'JDD-TEST-IMPORT-ADMIN', 'JDD-INVALID'],
- expectedRowsCount: [4, 1, 0],
- },
{
columnName: 'Fichier',
searchTerm: ['valid_file_test_import', 'invalid_file.csv'],
diff --git a/frontend/cypress/e2e/import/constants/selectors.js b/frontend/cypress/e2e/import/constants/selectors.js
index 2993fb258a..0839c916f6 100644
--- a/frontend/cypress/e2e/import/constants/selectors.js
+++ b/frontend/cypress/e2e/import/constants/selectors.js
@@ -48,13 +48,19 @@ export const getSelectorsForStep = (stepName) => {
export const SELECTOR_IMPORT_MODAL_DELETE = '[data-qa=import-modal-delete]';
export const SELECTOR_IMPORT_MODAL_DELETE_VALIDATE = '[data-qa=modal-delete-validate]';
+
export const SELECTOR_IMPORT_MODAL_DESTINATION_START = '[data-qa=import-modal-destination-start]';
export const SELECTOR_IMPORT_FIELDMAPPING_DATE_MIN = '[data-qa=import-fieldmapping-theme-date_min]';
export const SELECTOR_IMPORT_FIELDMAPPING_OBSERVERS =
'[data-qa=import-fieldmapping-theme-observers]';
export const SELECTOR_IMPORT_FIELDMAPPING_NOM_CITE = '[data-qa=import-fieldmapping-theme-nom_cite]';
export const SELECTOR_IMPORT_FIELDMAPPING_WKT = '[data-qa=import-fieldmapping-theme-WKT]';
+export const SELECTOR_IMPORT_FIELDMAPPING_CD_HAB = '[data-qa=import-fieldmapping-theme-cd_hab]';
export const SELECTOR_IMPORT_FIELDMAPPING_CD_NOM = '[data-qa=import-fieldmapping-theme-cd_nom]';
+export const SELECTOR_IMPORT_FIELDMAPPING_DATASET =
+ '[data-qa=import-fieldmapping-theme-unique_dataset_id]';
+export const SELECTOR_IMPORT_FIELDMAPPING_DEFAULT_DATASET =
+ '[data-qa=import-fieldmapping-theme-default-unique_dataset_id] ng-select';
export const SELECTOR_IMPORT_FIELDMAPPING_VALIDATE =
'[data-qa=import-new-fieldmapping-model-validate]';
export const SELECTOR_IMPORT_FIELDMAPPING_BUTTON_DELETE =
@@ -70,6 +76,8 @@ export const SELECTOR_IMPORT_FIELDMAPPING_SELECTION_RENAME_OK =
export const SELECTOR_IMPORT_FIELDMAPPING_SELECTION_RENAME_TEXT =
'[data-qa=import-fieldmapping-selection-rename-text]';
export const SELECTOR_IMPORT_FIELDMAPPING_MODAL = '[data-qa=import-fieldmapping-saving-modal]';
+export const SELECTOR_IMPORT_FIELDMAPPING_MODAL_CANCEL =
+ '[data-qa=import-fieldmapping-saving-modal-cancel]';
export const SELECTOR_IMPORT_FIELDMAPPING_MODAL_CLOSE =
'[data-qa=import-fieldmapping-saving-modal-close]';
export const SELECTOR_IMPORT_FIELDMAPPING_MODAL_OK =
@@ -88,7 +96,6 @@ export const SELECTOR_IMPORT_LIST_TOOLBAR_DESTINATIONS =
export const SELECTOR_IMPORT_LIST_TOOLBAR_SEARCH = '[data-qa=import-list-toolbar-search]';
export const SELECTOR_DESTINATIONS = '[data-qa=destinations]';
export const SELECTOR_IMPORT = '[data-qa=gn-sidenav-link-IMPORT]';
-export const SELECTOR_IMPORT_UPLOAD_DATASET = '[data-qa=import-new-upload-datasets]';
export const SELECTOR_IMPORT_UPLOAD_FILE = '[data-qa=import-new-upload-file]';
export const SELECTOR_IMPORT_UPLOAD_VALIDATE = '[data-qa=import-new-upload-validate]';
export const SELECTOR_IMPORT_CONTENTMAPPING_STEP_BUTTON =
diff --git a/frontend/cypress/e2e/import/list-table-jdd-modify-delete-spec.js b/frontend/cypress/e2e/import/list-table-jdd-modify-delete-spec.js
index 4c26312171..56b362a2ae 100644
--- a/frontend/cypress/e2e/import/list-table-jdd-modify-delete-spec.js
+++ b/frontend/cypress/e2e/import/list-table-jdd-modify-delete-spec.js
@@ -44,7 +44,7 @@ describe('Tests actions on active/inactive list JDD ', () => {
});
JDD_LIST.forEach((jdd_item) => {
- it(`should verify actions for ${jdd_item.jdd_name} (${
+ it.skip(`should verify actions for ${jdd_item.jdd_name} (${
jdd_item.jdd_is_active ? 'active' : 'inactive'
})`, () => {
cy.getRowIndexByCellValue(
@@ -58,19 +58,18 @@ describe('Tests actions on active/inactive list JDD ', () => {
});
});
- it('Should be able to modify a finished import, but still active JDD', () => {
+ it.skip('Should be able to modify a finished import, but still active JDD', () => {
cy.startImport();
cy.pickDestination();
- cy.pickDataset(user.dataset);
cy.loadImportFile(FILES.synthese.valid.fixture);
cy.configureImportFile();
- cy.configureImportFieldMapping();
+ cy.configureImportFieldMapping(user.dataset);
cy.configureImportContentMapping();
cy.verifyImport();
cy.executeImport();
cy.backToImportList();
- cy.get(getSelectorImportListTableRowEdit(0))
+ cy.get(getSelectorImportListTableRowEdit.skip(0))
.should('exist')
.should('be.visible')
.should('not.be.disabled');
@@ -80,7 +79,7 @@ describe('Tests actions on active/inactive list JDD ', () => {
});
cy.reload();
- cy.get(getSelectorImportListTableRowEdit(0))
+ cy.get(getSelectorImportListTableRowEdit.skip(0))
.should('exist')
.should('be.visible')
.should('be.disabled');
@@ -90,7 +89,7 @@ describe('Tests actions on active/inactive list JDD ', () => {
});
cy.reload();
- cy.get(getSelectorImportListTableRowEdit(0))
+ cy.get(getSelectorImportListTableRowEdit.skip(0))
.should('exist')
.should('be.visible')
.should('not.be.disabled');
@@ -104,7 +103,7 @@ describe('Tests actions on active/inactive list JDD ', () => {
function verifyEditAction(rowIndex, jdd_item) {
const actionStatus = jdd_item.jdd_is_active ? 'not.be.disabled' : 'be.disabled';
- cy.get(getSelectorImportListTableRowEdit(rowIndex))
+ cy.get(getSelectorImportListTableRowEdit.skip(rowIndex))
.should('exist')
.should('be.visible')
.should(actionStatus)
diff --git a/frontend/cypress/e2e/import/list-table-refer-to-jdd-spec.js b/frontend/cypress/e2e/import/list-table-refer-to-jdd-spec.js
deleted file mode 100644
index f087441105..0000000000
--- a/frontend/cypress/e2e/import/list-table-refer-to-jdd-spec.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import { USERS } from './constants/users';
-import { TIMEOUT_WAIT, VIEWPORTS } from './constants/common';
-import { SELECTOR_IMPORT_LIST_TABLE } from './constants/selectors';
-
-const COLUMN_NAME = 'Jeu de données';
-const JDD_LIST = ['JDD-TEST-IMPORT-ADMIN', 'JDD-TEST-IMPORT-2', 'JDD-TEST-IMPORT-3'];
-
-// ////////////////////////////////////////////////////////////////////////////
-//
-// ////////////////////////////////////////////////////////////////////////////
-
-describe('Test List import - Refer to JDD page', () => {
- VIEWPORTS.forEach((viewport) => {
- context(`viewport: ${viewport.width}x${viewport.height}`, () => {
- const user = USERS[0];
- context(`user: ${user.login.username}`, () => {
- beforeEach(() => {
- cy.viewport(viewport.width, viewport.height);
- cy.geonatureLogin(user.login.username, user.login.password);
- cy.visitImport();
- });
-
- JDD_LIST.forEach((cellValue) =>
- it('Should be redirected to page Metada dataset with dataset name: ' + cellValue, () => {
- cy.getCellValueByColumnName(SELECTOR_IMPORT_LIST_TABLE, COLUMN_NAME, cellValue).then(
- () => {
- cy.get('@targetLink').click();
- cy.wait(TIMEOUT_WAIT);
- }
- );
- cy.location().then((loc) => {
- cy.log('Current URL: ' + loc.href);
- expect(loc.href).to.include('metadata/dataset_detail/');
- });
- })
- );
- });
- });
- });
-});
diff --git a/frontend/cypress/e2e/import/navigation-check-back-each-steps-spec.js b/frontend/cypress/e2e/import/navigation-check-back-each-steps-spec.js
index 880fcfd40f..581fd22a77 100644
--- a/frontend/cypress/e2e/import/navigation-check-back-each-steps-spec.js
+++ b/frontend/cypress/e2e/import/navigation-check-back-each-steps-spec.js
@@ -69,7 +69,6 @@ describe('Import Process Navigation', () => {
cy.pickDestination(DESTINATION);
// STEP 1 - UPLOAD
- cy.pickDataset(FIELDS_CONTENT_STEP_UPLOAD.datasetField.defaultValue);
cy.loadImportFile(FIELDS_CONTENT_STEP_UPLOAD.fileUploadField.defaultValue);
cy.wait(TIMEOUT_WAIT);
cy.url().then((url) => {
@@ -103,13 +102,6 @@ describe('Import Process Navigation', () => {
cy.get(SELECTOR_NAVIGATION_STEP_DECODE_FILE.back_btn_selector)
.should('be.visible')
.click();
- // Verify the selected value in the ng-select input
- cy.get(FIELDS_CONTENT_STEP_UPLOAD.datasetField.selector).within(() => {
- cy.get('.ng-value').should(
- 'contain.text',
- FIELDS_CONTENT_STEP_UPLOAD.datasetField.defaultValue
- );
- });
cy.get(FIELDS_CONTENT_STEP_UPLOAD.fileUploadField.selector).then(($el) => {
const expectedValue = $el
.text()
@@ -119,7 +111,6 @@ describe('Import Process Navigation', () => {
expect(defaultValue).to.include(expectedValue);
});
// Change values in upload step
- cy.pickDataset(FIELDS_CONTENT_STEP_UPLOAD.datasetField.newValue);
cy.loadImportFile(FIELDS_CONTENT_STEP_UPLOAD.fileUploadField.newValue);
cy.get(SELECTOR_NAVIGATION_STEP_DECODE_FILE.back_btn_selector)
.should('be.visible')
diff --git a/frontend/cypress/e2e/import/navigation-mappings-cancel-save-spec.js b/frontend/cypress/e2e/import/navigation-mappings-cancel-save-spec.js
index 003cffe2b4..29c8fbf763 100644
--- a/frontend/cypress/e2e/import/navigation-mappings-cancel-save-spec.js
+++ b/frontend/cypress/e2e/import/navigation-mappings-cancel-save-spec.js
@@ -7,6 +7,7 @@ import {
SELECTOR_IMPORT_CONTENTMAPPING_STEP_BUTTON,
SELECTOR_IMPORT_FIELDMAPPING_CD_NOM,
SELECTOR_IMPORT_FIELDMAPPING_DATE_MIN,
+ SELECTOR_IMPORT_FIELDMAPPING_DEFAULT_DATASET,
SELECTOR_IMPORT_FIELDMAPPING_NOM_CITE,
SELECTOR_IMPORT_FIELDMAPPING_OBSERVERS,
SELECTOR_IMPORT_FIELDMAPPING_WKT,
@@ -22,14 +23,13 @@ function runTheProcessUntilFieldMapping(user) {
cy.visitImport();
cy.startImport();
cy.pickDestination();
- cy.pickDataset(user.dataset);
cy.loadImportFile(FILES.synthese.valid.fixture);
cy.configureImportFile();
}
function runTheProcessUntilContentMapping(user) {
runTheProcessUntilFieldMapping(user);
- cy.configureImportFieldMapping();
+ cy.configureImportFieldMapping(user.dataset);
cy.wait(500);
}
@@ -67,14 +67,14 @@ function selectContentMappingField(dataQa, value) {
cy.get(`[data-qa=import-contentmapping-theme-${dataQa}]`).should('exist').select(value);
}
-function fillTheFieldMappingFormRaw() {
+function fillTheFieldMappingFormRaw(datasetName) {
selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_DATE_MIN, 'date_debut');
selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_OBSERVERS, 'date_debut');
selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_NOM_CITE, 'date_debut');
selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_WKT, 'date_debut');
selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_CD_NOM, 'date_debut');
+ selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_DEFAULT_DATASET, datasetName);
}
-
// ////////////////////////////////////////////////////////////////////////////
// Create a mapping with dummy values
// ////////////////////////////////////////////////////////////////////////////
@@ -97,7 +97,7 @@ describe('Navigation - cancel and save', () => {
const parts = url.split('/');
const importID = parts[parts.length - 2]; // Get the penultimate element
- fillTheFieldMappingFormRaw();
+ fillTheFieldMappingFormRaw(user.dataset);
cy.get(SELECTOR_IMPORT_FOOTER_DELETE).should('be.enabled').click();
cy.wait(TIMEOUT_WAIT);
cy.checkCurrentPageIsImport();
@@ -112,7 +112,7 @@ describe('Navigation - cancel and save', () => {
const parts = url.split('/');
const importID = parts[parts.length - 2]; // Get the penultimate element
- fillTheFieldMappingFormRaw();
+ fillTheFieldMappingFormRaw(user.dataset);
cy.visitImport();
checkImportIsFirstInList(importID);
clickOnFirstLineEdit();
@@ -133,7 +133,7 @@ describe('Navigation - cancel and save', () => {
// Extract the ID using string manipulation
const parts = url.split('/');
const importID = parts[parts.length - 2]; // Get the penultimate element
- fillTheFieldMappingFormRaw();
+ fillTheFieldMappingFormRaw(user.dataset);
cy.get(SELECTOR_IMPORT_FOOTER_SAVE).should('be.enabled').click();
checkImportIsFirstInList(importID);
clickOnFirstLineEdit();
diff --git a/frontend/cypress/e2e/import/propcess-import-in-synthese-spec.js b/frontend/cypress/e2e/import/propcess-import-in-synthese-spec.js
index c1e2f5d20b..b3cfea90b1 100644
--- a/frontend/cypress/e2e/import/propcess-import-in-synthese-spec.js
+++ b/frontend/cypress/e2e/import/propcess-import-in-synthese-spec.js
@@ -23,10 +23,9 @@ describe('Import - create a new import', () => {
it('Should be able to import a valid-file in synthese', () => {
cy.startImport();
cy.pickDestination();
- cy.pickDataset(USER.dataset);
cy.loadImportFile(FILES.synthese.valid.fixture);
cy.configureImportFile();
- cy.configureImportFieldMapping();
+ cy.configureImportFieldMapping(USER.dataset);
cy.configureImportContentMapping();
cy.verifyImport();
cy.executeImport();
diff --git a/frontend/cypress/e2e/import/step1-upload-spec.js b/frontend/cypress/e2e/import/step1-upload-spec.js
index b2ec1e5aac..e22d9a7f2f 100644
--- a/frontend/cypress/e2e/import/step1-upload-spec.js
+++ b/frontend/cypress/e2e/import/step1-upload-spec.js
@@ -2,7 +2,6 @@ import { USERS } from './constants/users';
import { VIEWPORTS } from './constants/common';
import { FILES } from './constants/files';
import {
- SELECTOR_IMPORT_UPLOAD_DATASET,
SELECTOR_IMPORT_UPLOAD_FILE,
SELECTOR_IMPORT_UPLOAD_VALIDATE,
} from './constants/selectors';
@@ -29,38 +28,8 @@ describe('Import - Upload step', () => {
cy.get(SELECTOR_IMPORT_UPLOAD_VALIDATE).should('exist').should('be.disabled');
});
- it('Should be able to select a jdd', () => {
- cy.pickDataset(USER.dataset);
- cy.get(`${SELECTOR_IMPORT_UPLOAD_DATASET} > ng-select`)
- .should('have.class', 'ng-valid')
- .find('.ng-value-label')
- .should('exist')
- .should('contains.text', USER.dataset);
-
- cy.get(SELECTOR_IMPORT_UPLOAD_DATASET).find('.ng-clear-wrapper').should('exist').click();
-
- cy.get(`${SELECTOR_IMPORT_UPLOAD_DATASET} > ng-select`).should('have.class', 'ng-invalid');
-
- cy.pickDataset(USER.dataset);
-
- cy.get(`${SELECTOR_IMPORT_UPLOAD_DATASET} > ng-select`)
- .should('have.class', 'ng-valid')
- .find('.ng-value-label')
- .should('exist')
- .should('contains.text', USER.dataset);
- });
-
- it('Should access jdd only filtered based on permissions ', () => {
- cy.get(`${SELECTOR_IMPORT_UPLOAD_DATASET} > ng-select`)
- .click()
- .get('.ng-option')
- .should('have.length', 1)
- .should('contain', USER.dataset);
- });
-
it('Should throw error if file is empty', () => {
// required to trigger file validation
- cy.pickDataset(USER.dataset);
const file = FILES.synthese.empty;
cy.get(file.formErrorElement).should('not.exist');
cy.loadImportFile(file.fixture);
@@ -70,7 +39,6 @@ describe('Import - Upload step', () => {
it('Should throw error if csv is not valid', () => {
// required to trigger file validation
- cy.pickDataset(USER.dataset);
const file = FILES.synthese.bad;
cy.get(file.formErrorElement).should('not.exist');
cy.fixture(file.fixture, null).as('import_file');
diff --git a/frontend/cypress/e2e/import/step3-field-mapping-spec.js b/frontend/cypress/e2e/import/step3-field-mapping-spec.js
index 79317eb885..035e2acd8e 100644
--- a/frontend/cypress/e2e/import/step3-field-mapping-spec.js
+++ b/frontend/cypress/e2e/import/step3-field-mapping-spec.js
@@ -7,6 +7,8 @@ import {
SELECTOR_IMPORT_FIELDMAPPING_BUTTON_DELETE,
SELECTOR_IMPORT_FIELDMAPPING_BUTTON_DELETE_OK,
SELECTOR_IMPORT_FIELDMAPPING_CD_NOM,
+ SELECTOR_IMPORT_FIELDMAPPING_DEFAULT_DATASET,
+ SELECTOR_IMPORT_FIELDMAPPING_DATASET,
SELECTOR_IMPORT_FIELDMAPPING_DATE_MIN,
SELECTOR_IMPORT_FIELDMAPPING_MODAL,
SELECTOR_IMPORT_FIELDMAPPING_MODAL_CLOSE,
@@ -76,25 +78,14 @@ function fillTheFormRaw() {
selectField(SELECTOR_IMPORT_FIELDMAPPING_NOM_CITE, 'date_debut');
selectField(SELECTOR_IMPORT_FIELDMAPPING_WKT, 'date_debut');
selectField(SELECTOR_IMPORT_FIELDMAPPING_CD_NOM, 'date_debut');
+ selectField(SELECTOR_IMPORT_FIELDMAPPING_DATASET, 'date_debut');
}
function fillTheForm() {
// Fill in the form with mandatory field
cy.get(SELECTOR_IMPORT_FIELDMAPPING_VALIDATE).should('exist');
- selectField(SELECTOR_IMPORT_FIELDMAPPING_DATE_MIN, 'date_debut');
- cy.get(SELECTOR_IMPORT_FIELDMAPPING_VALIDATE).should('exist').should('not.be.enabled');
-
- selectField(SELECTOR_IMPORT_FIELDMAPPING_OBSERVERS, 'date_debut');
- cy.get(SELECTOR_IMPORT_FIELDMAPPING_VALIDATE).should('exist').should('not.be.enabled');
- selectField;
- selectField(SELECTOR_IMPORT_FIELDMAPPING_NOM_CITE, 'date_debut');
- cy.get(SELECTOR_IMPORT_FIELDMAPPING_VALIDATE).should('exist').should('not.be.enabled');
-
- selectField(SELECTOR_IMPORT_FIELDMAPPING_WKT, 'date_debut');
- cy.get(SELECTOR_IMPORT_FIELDMAPPING_VALIDATE).should('exist').should('not.be.enabled');
-
- selectField(SELECTOR_IMPORT_FIELDMAPPING_CD_NOM, 'date_debut');
+ fillTheFormRaw();
// Every mandatory field is filled: should be able to validate
cy.get(SELECTOR_IMPORT_FIELDMAPPING_VALIDATE).should('exist').should('be.enabled').click();
@@ -113,20 +104,19 @@ function fillTheForm() {
cy.wait(TIMEOUT_WAIT);
}
-function runTheProcess(user) {
+function runTheProcess() {
cy.visitImport();
cy.startImport();
cy.pickDestination();
- cy.pickDataset(user.dataset);
cy.loadImportFile(FILES.synthese.valid.fixture);
cy.configureImportFile();
}
-function restartTheProcess(user) {
+function restartTheProcess() {
cy.wait(TIMEOUT_WAIT);
cy.deleteCurrentImport();
cy.wait(TIMEOUT_WAIT);
- runTheProcess(user);
+ runTheProcess();
}
function checkThatMappingCanBeSaved() {
@@ -169,10 +159,19 @@ describe('Import - Field mapping step', () => {
beforeEach(() => {
cy.viewport(VIEWPORT.width, VIEWPORT.height);
cy.geonatureLogin(USER_ADMIN.login.username, USER_ADMIN.login.password);
- runTheProcess(USER_ADMIN);
+ runTheProcess();
cy.get('[data-qa="import-new-fieldmapping-form"]').should('exist');
});
+ it('Should access jdd only filtered based on permissions ', () => {
+ cy.get(`${SELECTOR_IMPORT_FIELDMAPPING_DEFAULT_DATASET}`)
+ .click()
+ .get('.ng-option')
+ .should('have.length', 2)
+ .should('contain', USER_ADMIN.dataset)
+ .should('contain', USER_AGENT.dataset);
+ });
+
it('Should be able to create a new field mapping, rename it, and delete it', () => {
fillTheForm();
restartTheProcess(USER_ADMIN);
@@ -253,7 +252,7 @@ describe('Import - Field mapping step', () => {
cy.deleteCurrentImport();
cy.geonatureLogout();
cy.geonatureLogin(USER_AGENT.login.username, USER_AGENT.login.password);
- runTheProcess(USER_AGENT);
+ runTheProcess();
// Check that field mapping does not exist
cy.get(SELECTOR_IMPORT_FIELDMAPPING_SELECTION)
@@ -268,7 +267,7 @@ describe('Import - Field mapping step', () => {
cy.deleteCurrentImport();
cy.geonatureLogout();
cy.geonatureLogin(USER_ADMIN.login.username, USER_ADMIN.login.password);
- runTheProcess(USER_ADMIN);
+ runTheProcess();
// Check that field mapping does exist
cy.get(SELECTOR_IMPORT_FIELDMAPPING_SELECTION)
@@ -289,7 +288,7 @@ describe('Import - Field mapping step', () => {
cy.deleteCurrentImport();
cy.geonatureLogout();
cy.geonatureLogin(USER_AGENT.login.username, USER_AGENT.login.password);
- runTheProcess(USER_AGENT);
+ runTheProcess();
// Create a mapping
fillTheForm();
@@ -298,7 +297,7 @@ describe('Import - Field mapping step', () => {
cy.deleteCurrentImport();
cy.geonatureLogout();
cy.geonatureLogin(USER_ADMIN.login.username, USER_ADMIN.login.password);
- runTheProcess(USER_ADMIN);
+ runTheProcess();
// Check that field mapping does exist
cy.get(SELECTOR_IMPORT_FIELDMAPPING_SELECTION)
@@ -317,7 +316,7 @@ describe('Import - Field mapping step', () => {
it('Should be able to modifiy the default mapping if user got rights. A save to alternative should be offered to the user.', () => {
// Mapping Synthese
selectMapping(DEFAULT_FIELDMAPPINGS[0]);
- selectField(SELECTOR_IMPORT_FIELDMAPPING_DATE_MIN, 'date_fin');
+ selectField(SELECTOR_IMPORT_FIELDMAPPING_DATASET, 'date_fin');
checkThatMappingCanBeSaved();
restartTheProcess(USER_ADMIN);
@@ -328,9 +327,9 @@ describe('Import - Field mapping step', () => {
it('Should not be able to modifiy the default mapping if user does not got rights', () => {
cy.geonatureLogout();
cy.geonatureLogin(USER_AGENT.login.username, USER_AGENT.login.password);
- runTheProcess(USER_AGENT);
+ runTheProcess();
selectMapping(DEFAULT_FIELDMAPPINGS[0]);
- selectField(SELECTOR_IMPORT_FIELDMAPPING_DATE_MIN, 'date_fin');
+ selectField(SELECTOR_IMPORT_FIELDMAPPING_DATASET, 'date_fin');
checkThatMappingCanNotBeSaved();
});
diff --git a/frontend/cypress/e2e/import/step4-content-mapping-spec.js b/frontend/cypress/e2e/import/step4-content-mapping-spec.js
index 352dc0ae82..61488aac6b 100644
--- a/frontend/cypress/e2e/import/step4-content-mapping-spec.js
+++ b/frontend/cypress/e2e/import/step4-content-mapping-spec.js
@@ -19,6 +19,13 @@ import {
SELECTOR_IMPORT_CONTENTMAPPING_SELECTION_TEXT,
SELECTOR_IMPORT_CONTENTMAPPING_VALIDATE,
SELECTOR_IMPORT_NEW_VERIFICATION_START,
+ SELECTOR_IMPORT_FIELDMAPPING_DATASET,
+ SELECTOR_IMPORT_FIELDMAPPING_DATE_MIN,
+ SELECTOR_IMPORT_FIELDMAPPING_WKT,
+ SELECTOR_IMPORT_FIELDMAPPING_NOM_CITE,
+ SELECTOR_IMPORT_FIELDMAPPING_CD_HAB,
+ SELECTOR_IMPORT_FIELDMAPPING_VALIDATE,
+ SELECTOR_IMPORT_FIELDMAPPING_MODAL_CANCEL,
} from './constants/selectors';
// ////////////////////////////////////////////////////////////////////////////
@@ -114,28 +121,26 @@ function runTheProcess(user) {
cy.visitImport();
cy.startImport();
cy.pickDestination();
- cy.pickDataset(user.dataset);
cy.loadImportFile(FILES.synthese.valid.fixture);
cy.configureImportFile();
- cy.configureImportFieldMapping();
+ cy.configureImportFieldMapping(user.dataset);
}
function runTheProcessForOcchab(user) {
cy.visitImport();
cy.startImport();
cy.pickDestination('Occhab');
- cy.pickDataset(user.dataset);
- cy.loadImportFile(FILES.synthese.valid.fixture);
+ cy.loadImportFile(FILES.occhab.valid.fixture);
cy.configureImportFile();
- // cy.configureImportFieldMapping();
- selectFieldMappingField('import-fieldmapping-theme-date_min', 'error');
- selectFieldMappingField('import-fieldmapping-theme-WKT', 'error');
+ selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_DATE_MIN, 'date_debut');
+ selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_WKT, 'date_debut');
+ selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_DATASET, 'date_debut');
cy.get('#mat-tab-label-0-1').click();
- selectFieldMappingField('import-fieldmapping-theme-nom_cite', 'error');
- selectFieldMappingField('import-fieldmapping-theme-cd_hab', 'error');
+ selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_NOM_CITE, 'date_debut');
+ selectFieldMappingField(SELECTOR_IMPORT_FIELDMAPPING_CD_HAB, 'date_debut');
- cy.get('[data-qa="import-new-fieldmapping-model-validate"]').click();
- cy.get('[data-qa="import-fieldmapping-saving-modal-cancel"]', { force: true }).click();
+ cy.get(SELECTOR_IMPORT_FIELDMAPPING_VALIDATE).click();
+ cy.get(SELECTOR_IMPORT_FIELDMAPPING_MODAL_CANCEL, { force: true }).click();
}
function restartTheProcess(user) {
@@ -146,7 +151,7 @@ function restartTheProcess(user) {
// Occhab dedicated
function selectFieldMappingField(dataQa, value) {
- cy.get(`[data-qa="${dataQa}"]`)
+ cy.get(dataQa)
.should('exist')
.click()
.get('ng-dropdown-panel >')
diff --git a/frontend/cypress/e2e/import/step5-recaptiulatif-spec.js b/frontend/cypress/e2e/import/step5-recaptiulatif-spec.js
index 1ff9303e8e..999bacae31 100644
--- a/frontend/cypress/e2e/import/step5-recaptiulatif-spec.js
+++ b/frontend/cypress/e2e/import/step5-recaptiulatif-spec.js
@@ -17,10 +17,9 @@ function runTheProcess(user) {
cy.visitImport();
cy.startImport();
cy.pickDestination();
- cy.pickDataset(user.dataset);
cy.loadImportFile(FILES.synthese.valid.fixture);
cy.configureImportFile();
- cy.configureImportFieldMapping();
+ cy.configureImportFieldMapping(user.dataset);
cy.configureImportContentMapping();
cy.triggerImportVerification();
}
diff --git a/frontend/cypress/e2e/import/step6-report-spec.js b/frontend/cypress/e2e/import/step6-report-spec.js
index 47c056db9a..58bac4c25f 100644
--- a/frontend/cypress/e2e/import/step6-report-spec.js
+++ b/frontend/cypress/e2e/import/step6-report-spec.js
@@ -23,10 +23,9 @@ function runTheProcess(user) {
cy.visitImport();
cy.startImport();
cy.pickDestination();
- cy.pickDataset(user.dataset);
cy.loadImportFile(FILES.synthese.valid.fixture);
cy.configureImportFile();
- cy.configureImportFieldMapping();
+ cy.configureImportFieldMapping(user.dataset);
cy.configureImportContentMapping();
cy.triggerImportVerification();
cy.executeImport();
@@ -68,23 +67,16 @@ describe('Import - Report step', () => {
cy.deleteFile(FILENAME_INVALID_DATA, DOWNLOADS_FOLDER);
});
- cy.url().then((url) => {
- // Extract the ID using string manipulation
- const parts = url.split('/');
- const importID = parts[parts.length - 2]; // Get the penultimate element
- const destination = parts[parts.length - 3];
-
- // PDF report
- cy.get(SELECTOR_IMPORT_REPORT_DOWNLOAD_PDF).click({
- force: true,
- });
+ // PDF report
+ cy.get(SELECTOR_IMPORT_REPORT_DOWNLOAD_PDF).click({
+ force: true,
+ });
- cy.wait(TIMEOUT_WAIT);
- // https://github.com/cypress-io/cypress/issues/25443
- cy.task('getLastDownloadFileName', DOWNLOADS_FOLDER).then((filename) => {
- cy.verifyDownload(filename, DOWNLOADS_FOLDER);
- cy.deleteFile(filename, DOWNLOADS_FOLDER);
- });
+ cy.wait(TIMEOUT_WAIT);
+ // https://github.com/cypress-io/cypress/issues/25443
+ cy.task('getLastDownloadFileName', DOWNLOADS_FOLDER).then((filename) => {
+ cy.verifyDownload(filename, DOWNLOADS_FOLDER);
+ cy.deleteFile(filename, DOWNLOADS_FOLDER);
});
});
diff --git a/frontend/cypress/fixtures/import/occhab/valid_file.csv b/frontend/cypress/fixtures/import/occhab/valid_file.csv
index d9285de36e..4894c952ea 100644
--- a/frontend/cypress/fixtures/import/occhab/valid_file.csv
+++ b/frontend/cypress/fixtures/import/occhab/valid_file.csv
@@ -1,6 +1,6 @@
-Erreur station;Erreur habitat;id_station_source;unique_id_sinp_station;unique_dataset_id;date_min;date_max;observers_txt;id_nomenclature_area_surface_calculation;WKT;id_nomenclature_geographic_object;unique_id_sinp_habitat;nom_cite;cd_hab;technical_precision
-OK !;OK !;;afa81c29-c75d-408d-bf48-53cce02d5561;VALID_DATASET_UUID;17/11/2023;17/11/2023;;;POINT(3.634 44.399);St;4ee53579-b09b-408f-aa1f-d62495a66667;prairie;24;
-OK !;OK !;;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;17/11/2023;;;;POINT(3.634 44.399);St;d91496e9-d904-45a8-9e18-cb8acbbb6ea6;prairie;24;
+Erreur station;Erreur habitat;id_station;unique_id_sinp_station;unique_dataset_id;date_debut;date_fin;observateurs;methode_calcul_surface;geometry;nature_objet_geo;unique_id_sinp_habitat;nom_cite;cd_hab;precision_technique
+OK !;OK !;;afa81c29-c75d-408d-bf48-53cce02d5561;VALID_DATASET_UUID;17/11/2023;17/11/2023;;;POINT(3.634 44.399);St;4ee53579-b09b-408f-aa1f-d62495a66667;prairie;24;
+OK !;OK !;;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;17/11/2023;;;;POINT(3.634 44.399);St;d91496e9-d904-45a8-9e18-cb8acbbb6ea6;prairie;24;
DUPLICATE_UUID(unique_id_sinp_station);ERRONEOUS_PARENT_ENTITY;;462d385f-489a-436b-babb-8cca5fc62e1d;;17/11/2023;17/11/2023;;;POINT(3.634 44.399);St;e5e7a184-3e92-4adb-a721-5bd004b3397f;forêt;24;
DUPLICATE_UUID(unique_id_sinp_station);ERRONEOUS_PARENT_ENTITY;;462d385f-489a-436b-babb-8cca5fc62e1d;;17/11/2023;17/11/2023;;;POINT(3.634 44.399);St;8f52f122-b9ae-45b3-b947-2c9f7934b823;prairie;24;
DATASET_NOT_FOUND(unique_dataset_id);ERRONEOUS_PARENT_ENTITY;;bdc3346d-0fc3-40fa-b787-be927e4dd82e;050d613c-543f-47fd-800a-13931b2721c7;17/11/2023;17/11/2023;;;POINT(3.634 44.399);St;2ff4867d-6943-45d8-873d-187fbc6d67a7;prairie;24;
@@ -13,9 +13,9 @@ ORPHAN_ROW(unique_id_sinp_station);ORPHAN_ROW(unique_id_sinp_station);;258a2478-
ORPHAN_ROW(id_station_source);ORPHAN_ROW(id_station_source);Station 0;;;;;;;;;;;;
DUPLICATE_SOURCE_ENTITY_PK(id_station_source);ERRONEOUS_PARENT_ENTITY;Station 1;;;17/11/2023;17/11/2023;;;POINT(3.634 44.399);St;;prairie;24;
DUPLICATE_SOURCE_ENTITY_PK(id_station_source);ERRONEOUS_PARENT_ENTITY;Station 1;;;17/11/2023;17/11/2023;;;POINT(3.634 44.399);St;;prairie;24;
-OK !;OK !;Station 2;;;17/11/2023;17/11/2023;;;POINT(3.634 44.399);St;;prairie;24;
-Pas de station;OK !;Station 2;;;;;;;;;;prairie;24;
-Pas de station;OK !;;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;;;;;;;;prairie;24;
+OK !;OK !;Station 2;;;17/11/2023;17/11/2023;;;POINT(3.634 44.399);St;;prairie;24;
+Pas de station;OK !;Station 2;;;;;;;;;;prairie;24;
+Pas de station;OK !;;74be5e79-72e7-42a8-ba2e-d5e27c9caddb;;;;;;;;;prairie;24;
Pas de station;ERRONEOUS_PARENT_ENTITY;;bdc3346d-0fc3-40fa-b787-be927e4dd82e;;;;;;;;;prairie;24;
INVALID_UUID(unique_id_sinp_station);INVALID_UUID(unique_id_sinp_station),ERRONEOUS_PARENT_ENTITY;;erroneous;;17/11/2023;17/11/2023;;;POINT(3.634 44.399);St;6c02ef80-2e78-4c2c-b8b5-1c75e2349fc2;prairie;24;
Pas de station;INVALID_UUID(unique_id_sinp_station);;erroneous;;;;;;;;;prairie;24;
diff --git a/frontend/cypress/fixtures/import/synthese/invalid_data.csv b/frontend/cypress/fixtures/import/synthese/invalid_data.csv
index 82e9687ad6..4d358c967f 100644
--- a/frontend/cypress/fixtures/import/synthese/invalid_data.csv
+++ b/frontend/cypress/fixtures/import/synthese/invalid_data.csv
@@ -1,4 +1,4 @@
-error;id_synthese;id_origine;comment_releve;comment_occurrence;date_debut;date_fin;heure_debut;heure_fin;cd_nom;cd_ref;nom_valide;nom_vernaculaire;nom_cite;regne;group1_inpn;group2_inpn;classe;ordre;famille;rang_taxo;nombre_min;nombre_max;alti_min;alti_max;prof_min;prof_max;observateurs;determinateur;communes;geometrie_wkt_4326;x_centroid_4326;y_centroid_4326;nom_lieu;validateur;niveau_validation;date_validation;comment_validation;preuve_numerique_url;preuve_non_numerique;jdd_nom;jdd_uuid;jdd_id;ca_nom;ca_uuid;ca_id;cd_habref;cd_habitat;nom_habitat;precision_geographique;nature_objet_geo;type_regroupement;methode_regroupement;technique_observation;biologique_statut;etat_biologique;biogeographique_statut;naturalite;preuve_existante;niveau_precision_diffusion;stade_vie;sexe;objet_denombrement;type_denombrement;niveau_sensibilite;statut_observation;floutage_dee;statut_source;type_info_geo;methode_determination;comportement;reference_biblio;uuid_perm_sinp;uuid_perm_grp_sinp;date_creation;date_modification
-duplicate id;3;3;Relevé n°3;Occurrence n°3;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e3;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-duplicate id;3;4;Relevé n°4;Occurrence n°4;2017-01-08;2017-01-08;20:00:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e4;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-count min > count max;5;5;Relevé n°5;Occurrence n°5;2017-01-08;2017/01/08;20:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;20;5;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e5;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+error;id_synthese;id_origine;comment_releve;comment_occurrence;date_debut;date_fin;heure_debut;heure_fin;cd_nom;cd_ref;nom_valide;nom_vernaculaire;nom_cite;regne;group1_inpn;group2_inpn;classe;ordre;famille;rang_taxo;nombre_min;nombre_max;alti_min;alti_max;prof_min;prof_max;observateurs;determinateur;communes;geometrie_wkt_4326;x_centroid_4326;y_centroid_4326;nom_lieu;validateur;niveau_validation;date_validation;comment_validation;preuve_numerique_url;preuve_non_numerique;cd_habref;cd_habitat;nom_habitat;precision_geographique;nature_objet_geo;type_regroupement;methode_regroupement;technique_observation;biologique_statut;etat_biologique;biogeographique_statut;naturalite;preuve_existante;niveau_precision_diffusion;stade_vie;sexe;objet_denombrement;type_denombrement;niveau_sensibilite;statut_observation;floutage_dee;statut_source;type_info_geo;methode_determination;comportement;reference_biblio;uuid_perm_sinp;uuid_perm_grp_sinp;date_creation;date_modification
+duplicate id;3;3;Relevé n°3;Occurrence n°3;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+duplicate id;3;4;Relevé n°4;Occurrence n°4;2017-01-08;2017-01-08;20:00:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+count min > count max;5;5;Relevé n°5;Occurrence n°5;2017-01-08;2017/01/08;20:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;20;5;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
diff --git a/frontend/cypress/fixtures/import/synthese/valid_file_import_synthese_test_changed.csv b/frontend/cypress/fixtures/import/synthese/valid_file_import_synthese_test_changed.csv
index 1c12d057f1..c5354abbac 100644
--- a/frontend/cypress/fixtures/import/synthese/valid_file_import_synthese_test_changed.csv
+++ b/frontend/cypress/fixtures/import/synthese/valid_file_import_synthese_test_changed.csv
@@ -1,7 +1,7 @@
error;id_synthese;id_origine;comment_releve;comment_occurrence;date_debut;date_fin;heure_debut;heure_fin;cd_nom;cd_ref;nom_valide;nom_vernaculaire;nom_cite;regne;group1_inpn;group2_inpn;classe;ordre;famille;rang_taxo;nombre_min;nombre_max;alti_min;alti_max;prof_min;prof_max;observateurs;determinateur;communes;geometrie_wkt_4326;x_centroid_4326;y_centroid_4326;nom_lieu;validateur;niveau_validation;date_validation;comment_validation;preuve_numerique_url;preuve_non_numerique;jdd_nom;jdd_uuid;jdd_id;ca_nom;ca_uuid;ca_id;cd_habref;cd_habitat;nom_habitat;precision_geographique;nature_objet_geo;type_regroupement;methode_regroupement;technique_observation;biologique_statut;etat_biologique;biogeographique_statut;naturalite;preuve_existante;niveau_precision_diffusion;stade_vie;sexe;objet_denombrement;type_denombrement;niveau_sensibilite;statut_observation;floutage_dee;statut_source;type_info_geo;methode_determination;comportement;reference_biblio;uuid_perm_sinp;uuid_perm_grp_sinp;date_creation;date_modification
-valid;1;1;Relevé n°1;Occurrence n°1;2017-01-01;2017-01-01;12:05:02;12:05:02;60612;60612;Lynx lynx (Linnaeus, 1758);;Lynx Boréal;Animalia;Chordés;Mammifères;Mammalia;Carnivora;Felidae;ES;5;5;1500;1565;;;Administrateur test;Gil;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poil;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Adulte;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;b4f85a2e-dd88-4cdd-aa86-f1c7370faf3f;5b427c76-bd8c-4103-a33c-884c7037aa2b;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-valid;2;2;Relevé n°2;Occurrence n°2;2017-01-01;2017-01-02;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1500;1565;;;Administrateur test;Théo;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Immature;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;830c93c7-288e-40f0-a17f-15fbb50e643a;5b427c76-bd8c-4103-a33c-884c7037aa2b;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-duplicate id;3;3;Relevé n°3;Occurrence n°3;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e3;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-duplicate id;3;4;Relevé n°4;Occurrence n°4;2017-01-08;2017-01-08;20:00:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e4;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-count min > count max;5;5;Relevé n°5;Occurrence n°5;2017-01-08;2017/01/08;20:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;20;5;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e5;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-valid;6;6;Relevé n°6;Occurrence n°6;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;f5515e2a-b30d-11eb-8cc8-af8c2d0867b4;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+valid;1;1;Relevé n°1;Occurrence n°1;2017-01-01;2017-01-01;12:05:02;12:05:02;60612;60612;Lynx lynx (Linnaeus, 1758);;Lynx Boréal;Animalia;Chordés;Mammifères;Mammalia;Carnivora;Felidae;ES;5;5;1500;1565;;;Administrateur test;Gil;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poil;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Adulte;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+valid;2;2;Relevé n°2;Occurrence n°2;2017-01-01;2017-01-02;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1500;1565;;;Administrateur test;Théo;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Immature;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+duplicate id;3;3;Relevé n°3;Occurrence n°3;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+duplicate id;3;4;Relevé n°4;Occurrence n°4;2017-01-08;2017-01-08;20:00:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+count min > count max;5;5;Relevé n°5;Occurrence n°5;2017-01-08;2017/01/08;20:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;20;5;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+valid;6;6;Relevé n°6;Occurrence n°6;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
diff --git a/frontend/cypress/fixtures/import/synthese/valid_file_test_link_list_import_synthese.csv b/frontend/cypress/fixtures/import/synthese/valid_file_test_link_list_import_synthese.csv
index 1c12d057f1..a076624950 100644
--- a/frontend/cypress/fixtures/import/synthese/valid_file_test_link_list_import_synthese.csv
+++ b/frontend/cypress/fixtures/import/synthese/valid_file_test_link_list_import_synthese.csv
@@ -1,7 +1,7 @@
-error;id_synthese;id_origine;comment_releve;comment_occurrence;date_debut;date_fin;heure_debut;heure_fin;cd_nom;cd_ref;nom_valide;nom_vernaculaire;nom_cite;regne;group1_inpn;group2_inpn;classe;ordre;famille;rang_taxo;nombre_min;nombre_max;alti_min;alti_max;prof_min;prof_max;observateurs;determinateur;communes;geometrie_wkt_4326;x_centroid_4326;y_centroid_4326;nom_lieu;validateur;niveau_validation;date_validation;comment_validation;preuve_numerique_url;preuve_non_numerique;jdd_nom;jdd_uuid;jdd_id;ca_nom;ca_uuid;ca_id;cd_habref;cd_habitat;nom_habitat;precision_geographique;nature_objet_geo;type_regroupement;methode_regroupement;technique_observation;biologique_statut;etat_biologique;biogeographique_statut;naturalite;preuve_existante;niveau_precision_diffusion;stade_vie;sexe;objet_denombrement;type_denombrement;niveau_sensibilite;statut_observation;floutage_dee;statut_source;type_info_geo;methode_determination;comportement;reference_biblio;uuid_perm_sinp;uuid_perm_grp_sinp;date_creation;date_modification
-valid;1;1;Relevé n°1;Occurrence n°1;2017-01-01;2017-01-01;12:05:02;12:05:02;60612;60612;Lynx lynx (Linnaeus, 1758);;Lynx Boréal;Animalia;Chordés;Mammifères;Mammalia;Carnivora;Felidae;ES;5;5;1500;1565;;;Administrateur test;Gil;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poil;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Adulte;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;b4f85a2e-dd88-4cdd-aa86-f1c7370faf3f;5b427c76-bd8c-4103-a33c-884c7037aa2b;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-valid;2;2;Relevé n°2;Occurrence n°2;2017-01-01;2017-01-02;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1500;1565;;;Administrateur test;Théo;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Immature;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;830c93c7-288e-40f0-a17f-15fbb50e643a;5b427c76-bd8c-4103-a33c-884c7037aa2b;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-duplicate id;3;3;Relevé n°3;Occurrence n°3;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e3;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-duplicate id;3;4;Relevé n°4;Occurrence n°4;2017-01-08;2017-01-08;20:00:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e4;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-count min > count max;5;5;Relevé n°5;Occurrence n°5;2017-01-08;2017/01/08;20:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;20;5;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;2f92f91a-64a2-4684-90e4-140466bb34e5;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
-valid;6;6;Relevé n°6;Occurrence n°6;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;Contact aléatoire tous règnes confondus;4d331cae-65e4-4948-b0b2-a11bc5bb46c2;1;Données d'observation de la faune, de la Flore et de la fonge du Parc national des Ecrins;57b7d0f2-4183-4b7b-8f08-6e105d476dc5;1;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;f5515e2a-b30d-11eb-8cc8-af8c2d0867b4;5937d0f2-c96d-424b-bea4-9e3fdac894ed;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+error;id_synthese;id_origine;comment_releve;comment_occurrence;date_debut;date_fin;heure_debut;heure_fin;cd_nom;cd_ref;nom_valide;nom_vernaculaire;nom_cite;regne;group1_inpn;group2_inpn;classe;ordre;famille;rang_taxo;nombre_min;nombre_max;alti_min;alti_max;prof_min;prof_max;observateurs;determinateur;communes;geometrie_wkt_4326;x_centroid_4326;y_centroid_4326;nom_lieu;validateur;niveau_validation;date_validation;comment_validation;preuve_numerique_url;preuve_non_numerique;cd_habref;cd_habitat;nom_habitat;precision_geographique;nature_objet_geo;type_regroupement;methode_regroupement;technique_observation;biologique_statut;etat_biologique;biogeographique_statut;naturalite;preuve_existante;niveau_precision_diffusion;stade_vie;sexe;objet_denombrement;type_denombrement;niveau_sensibilite;statut_observation;floutage_dee;statut_source;type_info_geo;methode_determination;comportement;reference_biblio;uuid_perm_sinp;uuid_perm_grp_sinp;date_creation;date_modification
+valid;1;1;Relevé n°1;Occurrence n°1;2017-01-01;2017-01-01;12:05:02;12:05:02;60612;60612;Lynx lynx (Linnaeus, 1758);;Lynx Boréal;Animalia;Chordés;Mammifères;Mammalia;Carnivora;Felidae;ES;5;5;1500;1565;;;Administrateur test;Gil;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poil;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Adulte;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+valid;2;2;Relevé n°2;Occurrence n°2;2017-01-01;2017-01-02;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1500;1565;;;Administrateur test;Théo;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;;;;10;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Immature;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+duplicate id;3;3;Relevé n°3;Occurrence n°3;2017-01-08;;;;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+duplicate id;3;4;Relevé n°4;Occurrence n°4;2017-01-08;2017-01-08;20:00:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+count min > count max;5;5;Relevé n°5;Occurrence n°5;2017-01-08;2017/01/08;20:00;23:00:00;67111;67111;Alburnus alburnus (Linnaeus, 1758);Ablette;Ablette;Animalia;Chordés;Poissons;Actinopterygii;Cypriniformes;Leuciscidae;ES;20;5;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
+valid;6;6;Relevé n°6;Occurrence n°6;2017-01-01;2017-01-01;12:05:02;12:05:02;351;351;Rana temporaria Linnaeus, 1758;Grenouille rousse (La);Grenouille rousse;Animalia;Chordés;Amphibiens;Amphibia;Anura;Ranidae;ES;1;1;1600;1600;;;Administrateur test;Donovan;Vallouise-Pelvoux;POINT(6.5 44.85);6.5;44.85;;;En attente de validation;;;;Poils de plumes;;;;100;Inventoriel;OBS;;Galerie/terrier;Non renseigné;Non renseigné;Non renseigné;Sauvage;Oui;Précise;Juvénile;Femelle;Individu;Compté;Non sensible - Diffusion précise;Présent;Non;Terrain;Géoréférencement;Autre méthode de détermination;Non renseigné;;;;2021-01-11 14:20:46.492497;2021-01-11 14:20:46.492497
diff --git a/frontend/cypress/support/import/configureImportFieldMapping.js b/frontend/cypress/support/import/configureImportFieldMapping.js
index 53335b251a..88baae4974 100644
--- a/frontend/cypress/support/import/configureImportFieldMapping.js
+++ b/frontend/cypress/support/import/configureImportFieldMapping.js
@@ -1,6 +1,7 @@
const DEFAULT_MAPPING = 'Synthese GeoNature';
+const DEFAULT_DATASET = '';
-Cypress.Commands.add('configureImportFieldMapping', () => {
+Cypress.Commands.add('configureImportFieldMapping', (datasetName) => {
cy.get('[data-qa="import-fieldmapping-selection-select"]')
.should('exist')
.click()
@@ -11,9 +12,24 @@ Cypress.Commands.add('configureImportFieldMapping', () => {
cy.wrap(v).should('exist').click();
});
+ cy.get('[data-qa="import-fieldmapping-theme-default-unique_dataset_id"] ng-select')
+ .should('exist')
+ .click()
+ .get('ng-dropdown-panel')
+ .get('.ng-option')
+ .contains(datasetName)
+ .then((dataset) => {
+ cy.wrap(dataset).should('exist').click();
+ });
+
// Every mandatory field is filled: should be able to validate
cy.get('[data-qa="import-new-fieldmapping-model-validate"]')
.should('exist')
.should('be.enabled')
.click();
+
+ cy.get('[data-qa="import-fieldmapping-saving-modal-cancel"]')
+ .should('exist')
+ .should('be.enabled')
+ .click();
});
diff --git a/frontend/cypress/support/import/index.js b/frontend/cypress/support/import/index.js
index aac0a74e1e..867cf09f00 100644
--- a/frontend/cypress/support/import/index.js
+++ b/frontend/cypress/support/import/index.js
@@ -17,7 +17,6 @@ import './getGlobalConfig';
import './getRowIndexByCellValue';
import './hasToastError';
import './loadImportFile';
-import './pickDataset';
import './pickDestination';
import './removeFirstImportInList';
import './startImport';
diff --git a/frontend/cypress/support/import/pickDataset.js b/frontend/cypress/support/import/pickDataset.js
deleted file mode 100644
index 33ac7265a2..0000000000
--- a/frontend/cypress/support/import/pickDataset.js
+++ /dev/null
@@ -1,11 +0,0 @@
-Cypress.Commands.add('pickDataset', (datasetName) => {
- cy.get('[data-qa="import-new-upload-datasets"]')
- .should('exist')
- .click()
- .get('ng-dropdown-panel')
- .get('.ng-option')
- .contains(datasetName)
- .then((dataset) => {
- cy.wrap(dataset).should('exist').click();
- });
-});
diff --git a/frontend/src/app/GN2CommonModule/form/dynamic-form/dynamic-form.component.html b/frontend/src/app/GN2CommonModule/form/dynamic-form/dynamic-form.component.html
index f023e1aa0d..6cac2ecb1b 100644
--- a/frontend/src/app/GN2CommonModule/form/dynamic-form/dynamic-form.component.html
+++ b/frontend/src/app/GN2CommonModule/form/dynamic-form/dynamic-form.component.html
@@ -308,6 +308,7 @@
[multiSelect]="formDef.multi_select"
[moduleCode]="formDef.module_code"
[creatableInModule]="formDef.creatable_in_module"
+ [bindValue]="formDef.bind_value"
>
Suppression
- Supprimer cet import associé au JDD "{{ row.dataset.dataset_name }}" et commencé le
+ Supprimer cet import commencé le
{{ row.date_create_import }}?
Attention : cela supprimera aussi les données importées.
diff --git a/frontend/src/app/modules/imports/components/import_errors/import_errors.component.html b/frontend/src/app/modules/imports/components/import_errors/import_errors.component.html
index 46fb3f07b4..171708df76 100644
--- a/frontend/src/app/modules/imports/components/import_errors/import_errors.component.html
+++ b/frontend/src/app/modules/imports/components/import_errors/import_errors.component.html
@@ -11,10 +11,6 @@
Description de l'import
Nom du fichier :
{{ importData.full_file_name }}
-
- Jeu de données :
- {{ importData.dataset.dataset_name }}
-
Date de soumission de l'import :
{{ importData.date_create_import | date: 'dd/MM/yyyy' }}
diff --git a/frontend/src/app/modules/imports/components/import_list/import-list.component.html b/frontend/src/app/modules/imports/components/import_list/import-list.component.html
index e69c7af8bf..27efa32f64 100644
--- a/frontend/src/app/modules/imports/components/import_list/import-list.component.html
+++ b/frontend/src/app/modules/imports/components/import_list/import-list.component.html
@@ -89,14 +89,6 @@
Liste des imports
"
>
-
-
- {{ row.dataset ? row.dataset.dataset_name : '' }}
-
-
{{ row.date_create_import | date: 'dd-MM-yyyy' }}
@@ -202,7 +194,7 @@ Liste des imports
ngx-datatable-cell-template
>
Liste des imports
>
{
@@ -204,8 +200,6 @@ export class ImportListComponent implements OnInit {
getTooltip(row, tooltipType) {
if (!row?.cruved?.U) {
return "Vous n'avez pas les droits";
- } else if (!row?.dataset?.active) {
- return 'JDD clos';
} else if (tooltipType === 'edit') {
return "Modifier l'import";
} else {
diff --git a/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/mapping-theme/mapping-theme.component.html b/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/mapping-theme/mapping-theme.component.html
index a1ec086102..399467f20b 100644
--- a/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/mapping-theme/mapping-theme.component.html
+++ b/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/mapping-theme/mapping-theme.component.html
@@ -91,6 +91,7 @@
class="d-block mt-2"
[formDef]="defaultValueFormDefs[field.name_field]"
[form]="_fm.mappingFormGroup"
+ [attr.data-qa]="'import-fieldmapping-theme-default-' + field.name_field"
>