From 8e8a3bf5b1f5a6edf1f4331651347330f69eff5c Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Tue, 28 Nov 2023 17:20:32 +0100 Subject: [PATCH 01/53] =?UTF-8?q?Creation=20des=20nouvelles=20tables=20de?= =?UTF-8?q?=20gestion=20des=20th=C3=A8mes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migration des données 2023 Insertion de données test Co-authored-by: Claire Dagan --- .../internal/V0.103__create_action_theme.sql | 84 +++++++++++++++++++ .../V666.12__insert_new_themes_pscem_pirc.sql | 23 +++++ 2 files changed, 107 insertions(+) create mode 100644 backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql create mode 100644 backend/src/main/resources/db/testdata/V666.12__insert_new_themes_pscem_pirc.sql diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql new file mode 100644 index 000000000..72fd103d1 --- /dev/null +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -0,0 +1,84 @@ +-- Création des tables + +CREATE TABLE themes_control_plan ( + id serial PRIMARY KEY, + theme text UNIQUE NOT NULL +); + +CREATE TABLE subthemes_control_plan ( + id serial PRIMARY KEY, + subtheme text, + allowed_tags text[], + theme_id int REFERENCES themes_control_plan(id), + year int +); +CREATE INDEX idx_subthemes_control_plan_year ON subthemes_control_plan USING btree(year); + +CREATE TABLE env_actions_subthemes ( + env_action_id uuid, + subtheme_id integer, + tags text[], + foreign key (env_action_id) references env_actions(id), + foreign key (subtheme_id) references subthemes_control_plan(id), + primary key (env_action_id, subtheme_id) +); +-- TODO: Décider s'il faut ajouter une contrainte sur les tags de env_actions_subthemes +-- Si oui, il faudra probablement passer par un trigger +-- (pas possible avec postgres de faire une contrainte "classique") + + +COMMENT ON TABLE themes_control_plan IS 'Table des thèmes du plan de contrôle'; +COMMENT ON TABLE subthemes_control_plan IS 'Table des sous-thèmes du plan de contrôle versionnés par année'; +COMMENT ON TABLE env_actions_subthemes IS 'Table de jointure entre les actions et les sous-thèmes du plan de contrôle'; + +-- Insertion des themes et sous-themes à partir de la table control_themes +INSERT INTO themes_control_plan (theme) + SELECT distinct theme_level_1 FROM control_themes ORDER BY theme_level_1 + ; + +INSERT INTO subthemes_control_plan (subtheme, theme_id, year) + SELECT distinct theme_level_2, t.id, 2023 + FROM control_themes c JOIN themes_control_plan t ON t.theme = theme_level_1 + WHERE theme_level_2 IS NOT NULL ORDER BY theme_level_2 + ; + +UPDATE subthemes_control_plan + SET allowed_tags = '{"Oiseaux", "Habitat", "Flore", "Autres espèces protégées", "Reptiles", "Mammifères marins"}' + FROM themes_control_plan t + WHERE + t.id = subthemes_control_plan.theme_id + AND t.theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; + +-- Insertion des données dans la table env_actions_subthemes +INSERT INTO env_actions_subthemes (env_action_id, subtheme_id, tags) + WITH themes AS ( + SELECT + id as env_action_id, + jsonb_array_elements(value->'themes')->>'theme' as theme, + jsonb_array_elements_text(jsonb_array_elements(value->'themes')->'subThemes') as subtheme, + jsonb_array_elements(value->'themes')->'protectedSpecies' as protectedspecies + FROM env_actions + ) + SELECT themes.env_action_id, sbt.id, CASE WHEN cardinality(d.tags) >0 THEN d.tags END + FROM themes, + LATERAL ( + SELECT ARRAY( + SELECT CASE species + WHEN 'BIRDS' THEN 'Oiseaux' + WHEN 'HABITAT' THEN 'Habitat' + WHEN 'FLORA' THEN 'Flore' + WHEN 'OTHER' THEN 'Autres espèces protégées' + WHEN 'REPTILES' THEN 'Reptiles' + WHEN 'MARINE_MAMMALS' THEN 'Mammifères marins' + ELSE 'Non défini' + END + FROM (SELECT jsonb_array_elements_text(protectedspecies) species) t + ) + ) d(tags), + subthemes_control_plan sbt, + themes_control_plan t + WHERE sbt.subtheme = themes.subtheme + AND sbt.theme_id = t.id + AND t.theme = themes.theme + AND sbt.year = 2023; + diff --git a/backend/src/main/resources/db/testdata/V666.12__insert_new_themes_pscem_pirc.sql b/backend/src/main/resources/db/testdata/V666.12__insert_new_themes_pscem_pirc.sql new file mode 100644 index 000000000..7c00d9fa2 --- /dev/null +++ b/backend/src/main/resources/db/testdata/V666.12__insert_new_themes_pscem_pirc.sql @@ -0,0 +1,23 @@ + +INSERT INTO themes_control_plan (id, theme) VALUES (100001, 'Mouillage Individuel'); +INSERT INTO themes_control_plan (id, theme) VALUES (100002, 'Rejet'); + +INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage réglementé par arrêté', null, 100001, 2024); +INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage réglementé par AMP', null, 100001, 2024); +INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage avec AOT individuelle', null, 100001, 2024); +INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) VALUES ('Autre mouillage', null, 100001, 2024); +INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) VALUES ('Jet de déchet (macro déchet)', null, 100002, 2024); + +INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) + SELECT 'Destruction, capture, arrachage', null, id, 2024 + FROM themes_control_plan + WHERE theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; + +INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) + SELECT 'Atteinte aux habitats d’espèces protégées', + '{"Oiseaux", "Faune", "Flore", "Autres espèces protégées", "Reptiles", "Mammifères marins"}', + id, + 2024 + FROM themes_control_plan + WHERE theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; + From a67aa77d45ab618af4d90a267045def551e58769 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Wed, 29 Nov 2023 09:55:35 +0100 Subject: [PATCH 02/53] rename to proper english --- .../internal/V0.103__create_action_theme.sql | 32 +++++++++---------- .../V666.12__insert_new_themes_pscem_pirc.sql | 22 ++++++------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index 72fd103d1..0e24f12a5 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -1,25 +1,25 @@ -- Création des tables -CREATE TABLE themes_control_plan ( +CREATE TABLE control_plan_themes ( id serial PRIMARY KEY, theme text UNIQUE NOT NULL ); -CREATE TABLE subthemes_control_plan ( +CREATE TABLE control_plan_subthemes ( id serial PRIMARY KEY, subtheme text, allowed_tags text[], - theme_id int REFERENCES themes_control_plan(id), + theme_id int REFERENCES control_plan_themes(id), year int ); -CREATE INDEX idx_subthemes_control_plan_year ON subthemes_control_plan USING btree(year); +CREATE INDEX idx_control_plan_subthemes_year ON control_plan_subthemes USING btree(year); CREATE TABLE env_actions_subthemes ( env_action_id uuid, subtheme_id integer, tags text[], foreign key (env_action_id) references env_actions(id), - foreign key (subtheme_id) references subthemes_control_plan(id), + foreign key (subtheme_id) references control_plan_subthemes(id), primary key (env_action_id, subtheme_id) ); -- TODO: Décider s'il faut ajouter une contrainte sur les tags de env_actions_subthemes @@ -27,29 +27,29 @@ CREATE TABLE env_actions_subthemes ( -- (pas possible avec postgres de faire une contrainte "classique") -COMMENT ON TABLE themes_control_plan IS 'Table des thèmes du plan de contrôle'; -COMMENT ON TABLE subthemes_control_plan IS 'Table des sous-thèmes du plan de contrôle versionnés par année'; +COMMENT ON TABLE control_plan_themes IS 'Table des thèmes du plan de contrôle'; +COMMENT ON TABLE control_plan_subthemes IS 'Table des sous-thèmes du plan de contrôle versionnés par année'; COMMENT ON TABLE env_actions_subthemes IS 'Table de jointure entre les actions et les sous-thèmes du plan de contrôle'; -- Insertion des themes et sous-themes à partir de la table control_themes -INSERT INTO themes_control_plan (theme) +INSERT INTO control_plan_themes (theme) SELECT distinct theme_level_1 FROM control_themes ORDER BY theme_level_1 ; -INSERT INTO subthemes_control_plan (subtheme, theme_id, year) +INSERT INTO control_plan_subthemes (subtheme, theme_id, year) SELECT distinct theme_level_2, t.id, 2023 - FROM control_themes c JOIN themes_control_plan t ON t.theme = theme_level_1 + FROM control_themes c JOIN control_plan_themes t ON t.theme = theme_level_1 WHERE theme_level_2 IS NOT NULL ORDER BY theme_level_2 ; -UPDATE subthemes_control_plan +UPDATE control_plan_subthemes SET allowed_tags = '{"Oiseaux", "Habitat", "Flore", "Autres espèces protégées", "Reptiles", "Mammifères marins"}' - FROM themes_control_plan t + FROM control_plan_themes t WHERE - t.id = subthemes_control_plan.theme_id + t.id = control_plan_subthemes.theme_id AND t.theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; --- Insertion des données dans la table env_actions_subthemes +-- Insertion des données depuis les env actions dans la table env_actions_subthemes INSERT INTO env_actions_subthemes (env_action_id, subtheme_id, tags) WITH themes AS ( SELECT @@ -75,8 +75,8 @@ INSERT INTO env_actions_subthemes (env_action_id, subtheme_id, tags) FROM (SELECT jsonb_array_elements_text(protectedspecies) species) t ) ) d(tags), - subthemes_control_plan sbt, - themes_control_plan t + control_plan_subthemes sbt, + control_plan_themes t WHERE sbt.subtheme = themes.subtheme AND sbt.theme_id = t.id AND t.theme = themes.theme diff --git a/backend/src/main/resources/db/testdata/V666.12__insert_new_themes_pscem_pirc.sql b/backend/src/main/resources/db/testdata/V666.12__insert_new_themes_pscem_pirc.sql index 7c00d9fa2..d06a6fdb2 100644 --- a/backend/src/main/resources/db/testdata/V666.12__insert_new_themes_pscem_pirc.sql +++ b/backend/src/main/resources/db/testdata/V666.12__insert_new_themes_pscem_pirc.sql @@ -1,23 +1,23 @@ -INSERT INTO themes_control_plan (id, theme) VALUES (100001, 'Mouillage Individuel'); -INSERT INTO themes_control_plan (id, theme) VALUES (100002, 'Rejet'); +INSERT INTO control_plan_themes (id, theme) VALUES (100001, 'Mouillage Individuel'); +INSERT INTO control_plan_themes (id, theme) VALUES (100002, 'Rejet'); -INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage réglementé par arrêté', null, 100001, 2024); -INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage réglementé par AMP', null, 100001, 2024); -INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage avec AOT individuelle', null, 100001, 2024); -INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) VALUES ('Autre mouillage', null, 100001, 2024); -INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) VALUES ('Jet de déchet (macro déchet)', null, 100002, 2024); +INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage réglementé par arrêté', null, 100001, 2024); +INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage réglementé par AMP', null, 100001, 2024); +INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage avec AOT individuelle', null, 100001, 2024); +INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) VALUES ('Autre mouillage', null, 100001, 2024); +INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) VALUES ('Jet de déchet (macro déchet)', null, 100002, 2024); -INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) +INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) SELECT 'Destruction, capture, arrachage', null, id, 2024 - FROM themes_control_plan + FROM control_plan_themes WHERE theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; -INSERT INTO subthemes_control_plan (subtheme, allowed_tags, theme_id, year) +INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) SELECT 'Atteinte aux habitats d’espèces protégées', '{"Oiseaux", "Faune", "Flore", "Autres espèces protégées", "Reptiles", "Mammifères marins"}', id, 2024 - FROM themes_control_plan + FROM control_plan_themes WHERE theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; From 1356c12ba48897f9718c8583fbce912aeee280de Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 03/53] implements domain & controller --- .../ControlPlanThemeEntity.kt | 9 ++++ .../controlTheme/ControlThemeEntity.kt | 1 + .../IControlPlanThemeRepository.kt | 7 ++++ .../repositories/IControlThemeRepository.kt | 1 + .../GetControlPlanThemesByYear.kt | 16 ++++++++ .../controlThemes/GetAllControlThemes.kt | 1 + .../controlThemes/GetControlThemeById.kt | 1 + .../bff/outputs/ControlPlanThemeDataOutput.kt | 22 ++++++++++ .../bff/ControlPlanThemesController.kt | 30 ++++++++++++++ .../JpaControlPlanThemeRepository.kt | 12 ++++++ .../repositories/JpaControlThemeRepository.kt | 1 + .../GetAllControlPlanThemesUTest.kt | 41 +++++++++++++++++++ 12 files changed, 142 insertions(+) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanThemesByYear.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesController.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetAllControlPlanThemesUTest.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt new file mode 100644 index 000000000..7d2655896 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt @@ -0,0 +1,9 @@ +package fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme + +data class ControlPlanThemeEntity( + val id: Int, + val theme: String, + val subTheme: String, + val allowedTags: List ? = null, + val year: Int, +) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlTheme/ControlThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlTheme/ControlThemeEntity.kt index b5cd4eb4a..325a5584e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlTheme/ControlThemeEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlTheme/ControlThemeEntity.kt @@ -1,5 +1,6 @@ package fr.gouv.cacem.monitorenv.domain.entities.controlTheme +@Deprecated("Use ThemeControlPlan instead") data class ControlThemeEntity( val id: Int, val themeLevel1: String, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt new file mode 100644 index 000000000..7f78f2c7c --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt @@ -0,0 +1,7 @@ +package fr.gouv.cacem.monitorenv.domain.repositories + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity + +interface IControlPlanThemeRepository { + fun findByYear(year: Int): List +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt index 3f0b145a7..1ca10226c 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt @@ -2,6 +2,7 @@ package fr.gouv.cacem.monitorenv.domain.repositories import fr.gouv.cacem.monitorenv.domain.entities.controlTheme.ControlThemeEntity +@Deprecated("Use ControlPlanThemeRepository instead") interface IControlThemeRepository { fun findById(controlThemeId: Int): ControlThemeEntity fun findAll(): List diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanThemesByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanThemesByYear.kt new file mode 100644 index 000000000..32762352e --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanThemesByYear.kt @@ -0,0 +1,16 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanThemes + +import fr.gouv.cacem.monitorenv.config.UseCase +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository +import org.slf4j.LoggerFactory + +@UseCase +class GetControlPlanThemesByYear(private val controlPlanThemeRepository: IControlPlanThemeRepository) { + private val logger = LoggerFactory.getLogger(GetControlPlanThemesByYear::class.java) + fun execute(year: Int): List { + val controlPlanThemes = controlPlanThemeRepository.findByYear(year) + logger.info("Found ${controlPlanThemes.size} control plan (sub)themes for year $year") + return controlPlanThemes + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt index 03d8f3e59..7c9076f8d 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt @@ -7,6 +7,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlTheme.ControlThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlThemeRepository import org.slf4j.LoggerFactory +@Deprecated("Use GetControlPlanThemesByYear instead") @UseCase class GetAllControlThemes(private val controlThemeRepository: IControlThemeRepository) { private val logger = LoggerFactory.getLogger(GetAllControlThemes::class.java) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetControlThemeById.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetControlThemeById.kt index 285f7b952..74eca6e04 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetControlThemeById.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetControlThemeById.kt @@ -7,6 +7,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlTheme.ControlThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlThemeRepository import org.slf4j.LoggerFactory +@Deprecated("Not used") @UseCase class GetControlThemeById(private val controlThemeRepository: IControlThemeRepository) { private val logger = LoggerFactory.getLogger(GetControlThemeById::class.java) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt new file mode 100644 index 000000000..aadb4f65f --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt @@ -0,0 +1,22 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity + +data class ControlPlanThemeDataOutput( + val id: Int, + val theme: String, + val subTheme: String, + val allowedTags: List? = null, + val year: Int, +) { + companion object { + fun fromControlPlanThemeEntity(controlPlanTheme: ControlPlanThemeEntity) = + ControlPlanThemeDataOutput( + id = controlPlanTheme.id, + theme = controlPlanTheme.theme, + subTheme = controlPlanTheme.subTheme, + allowedTags = controlPlanTheme.allowedTags, + year = controlPlanTheme.year, + ) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesController.kt new file mode 100644 index 000000000..7b3ccdd41 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesController.kt @@ -0,0 +1,30 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff + +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanThemes.GetControlPlanThemesByYear +import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.ControlPlanThemeDataOutput +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import jakarta.websocket.server.PathParam +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/bff/v1/controlplanthemes") +@Tag(name = "Control Plan Themes", description = "API thématiques du plan de contrôle") +class ControlPlanThemesController( + private val getControlPlanThemesByYear: GetControlPlanThemesByYear, +) { + + @GetMapping("/{year}") + @Operation(summary = "Get control plan (sub)themes and allowed tags for a given year") + fun getAll( + @PathParam("validity year of the control plan themes") + @PathVariable(name = "year") + year: Int, + ): List { + val controlPlanThemes = getControlPlanThemesByYear.execute(year) + return controlPlanThemes.map { ControlPlanThemeDataOutput.fromControlPlanThemeEntity(it) } + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt new file mode 100644 index 000000000..e12e3e12e --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt @@ -0,0 +1,12 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository +import org.springframework.stereotype.Repository + +@Repository +class JpaControlPlanThemeRepository() : IControlPlanThemeRepository { + override fun findByYear(year: Int): List { + return listOf() + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlThemeRepository.kt index 66eb9385c..79dda9b0c 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlThemeRepository.kt @@ -5,6 +5,7 @@ import fr.gouv.cacem.monitorenv.domain.repositories.IControlThemeRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlThemeRepository import org.springframework.stereotype.Repository +@Deprecated("Use JpaControlPlanThemeRepository instead") @Repository class JpaControlThemeRepository(private val dbControlThemeRepository: IDBControlThemeRepository) : IControlThemeRepository { diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetAllControlPlanThemesUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetAllControlPlanThemesUTest.kt new file mode 100644 index 000000000..fc3e517fb --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetAllControlPlanThemesUTest.kt @@ -0,0 +1,41 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanThemes + +import com.nhaarman.mockitokotlin2.given +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.junit.jupiter.SpringExtension + +@ExtendWith(SpringExtension::class) +class GetAllControlPlanThemesUTest { + @MockBean + private lateinit var controlPlanThemeRepository: IControlPlanThemeRepository + + fun `execute should return all controlPlanThemes for the given year`() { + val controlPlanThemes = listOf( + ControlPlanThemeEntity( + id = 1, + theme = "ControlPlanTheme Name", + subTheme = "ControlPlanTheme Name", + allowedTags = listOf("tag1", "tag2"), + year = 2023, + ), + ControlPlanThemeEntity( + id = 2, + theme = "ControlPlanTheme Name 2", + subTheme = "ControlPlanTheme Name 2", + allowedTags = null, + year = 2023, + ), + ) + + given(controlPlanThemeRepository.findByYear(2023)).willReturn(controlPlanThemes) + + val result = GetControlPlanThemesByYear(controlPlanThemeRepository).execute(2023) + + assertThat(result.size).isEqualTo(2) + assertThat(result).isEqualTo(controlPlanThemes) + } +} From b1c45f085ff58d517d9d76008f816261299a8aff Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 04/53] implement db --- .../model/ControlPlanSubThemeModel.kt | 42 +++++++++++++++++++ .../database/model/ControlPlanThemeModel.kt | 16 +++++++ .../JpaControlPlanThemeRepository.kt | 7 +++- .../IDBControlPlanThemeRepository.kt | 8 ++++ .../interfaces/IDBControlThemeRepository.kt | 1 + .../JpaControlPlanThemeRepositoryITests.kt | 29 +++++++++++++ 6 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanThemeModel.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt new file mode 100644 index 000000000..a205ec59e --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt @@ -0,0 +1,42 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.model + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity +import io.hypersistence.utils.hibernate.type.array.ListArrayType +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.FetchType +import jakarta.persistence.Id +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne +import jakarta.persistence.Table +import org.hibernate.annotations.Type + +@Entity +@Table(name = "control_plan_subthemes") +data class ControlPlanSubThemeModel( + @Id + @Column(name = "id") + val id: Int, + + @Column(name = "subtheme") + val subTheme: String, + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "theme_id") + val controlPlanTheme: ControlPlanThemeModel, + + @Column(name = "year") + val year: Int, + + @Column(name = "allowed_tags") + @Type(ListArrayType::class) + val allowedTags: List? = null, +) { + fun toControlPlanTheme() = ControlPlanThemeEntity( + id = id, + subTheme = subTheme, + theme = controlPlanTheme.theme, + year = year, + allowedTags = allowedTags, + ) +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanThemeModel.kt new file mode 100644 index 000000000..fb8073108 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanThemeModel.kt @@ -0,0 +1,16 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.model + +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.Id +import jakarta.persistence.Table + +@Entity +@Table(name = "control_plan_themes") +data class ControlPlanThemeModel( + @Id + @Column(name = "id") + val id: Int, + @Column(name = "theme") + val theme: String, +) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt index e12e3e12e..e263343f0 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt @@ -2,11 +2,14 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository +import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanThemeRepository import org.springframework.stereotype.Repository @Repository -class JpaControlPlanThemeRepository() : IControlPlanThemeRepository { +class JpaControlPlanThemeRepository( + private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, +) : IControlPlanThemeRepository { override fun findByYear(year: Int): List { - return listOf() + return dbControlPlanThemeRepository.findByYearOrderById(year).map { it.toControlPlanTheme() } } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt new file mode 100644 index 000000000..8a132af85 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt @@ -0,0 +1,8 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces + +import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanSubThemeModel +import org.springframework.data.repository.CrudRepository + +interface IDBControlPlanThemeRepository : CrudRepository { + fun findByYearOrderById(year: Int): List +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlThemeRepository.kt index 7447f1fae..709f0a229 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlThemeRepository.kt @@ -3,4 +3,5 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlThemeModel import org.springframework.data.repository.CrudRepository +@Deprecated("Use IDBControlPlanThemeRepository instead") interface IDBControlThemeRepository : CrudRepository diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt new file mode 100644 index 000000000..24c685682 --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt @@ -0,0 +1,29 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +class JpaControlPlanThemeRepositoryITests : AbstractDBTests() { + @Autowired + private lateinit var jpaControlPlanThemeRepository: JpaControlPlanThemeRepository + + @Test + fun `findByYear Should return all control plan theme for a specific year`() { + // When + val requestedControlPlanThemesFor2023 = jpaControlPlanThemeRepository.findByYear(2023) + val requestedControlPlanThemesFor2024 = jpaControlPlanThemeRepository.findByYear(2024) + // Then + assertThat(requestedControlPlanThemesFor2023.size).isEqualTo(83) + assertThat(requestedControlPlanThemesFor2024.size).isEqualTo(7) + assertThat(requestedControlPlanThemesFor2024[6].id).isEqualTo(90) + assertThat(requestedControlPlanThemesFor2024[6].theme).isEqualTo( + "Police des espèces protégées et de leurs habitats (faune et flore)", + ) + assertThat(requestedControlPlanThemesFor2024[6].subTheme).isEqualTo("Atteinte aux habitats d’espèces protégées") + assertThat(requestedControlPlanThemesFor2024[6].allowedTags).isEqualTo( + listOf("Oiseaux", "Faune", "Flore", "Autres espèces protégées", "Reptiles", "Mammifères marins"), + ) + assertThat(requestedControlPlanThemesFor2024[6].year).isEqualTo(2024) + } +} From be980390272d52b694a35357ab12071249305c79 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 05/53] add test for ControlPlanThemesController --- .../endpoints/bff/ControlThemesController.kt | 1 + .../bff/ControlPlanThemesControllerITests.kt | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt index 67e56f248..06df29fed 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +@Deprecated("Use ControlPlanThemesController instead") @RestController @RequestMapping("/bff/v1/controlthemes") @Tag(name = "BFF.Control Themes", description = "API control themes") diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt new file mode 100644 index 000000000..35c99e37e --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt @@ -0,0 +1,51 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff + +import com.nhaarman.mockitokotlin2.verify +import fr.gouv.cacem.monitorenv.config.WebSecurityConfig +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanThemes.GetControlPlanThemesByYear +import org.junit.jupiter.api.Test +import org.mockito.BDDMockito +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.context.annotation.Import +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status + +@Import(WebSecurityConfig::class) +@WebMvcTest(value = [(ControlPlanThemesController::class)]) +class ControlPlanThemesControllerITests { + @Autowired + private lateinit var mockMvc: MockMvc + + @MockBean + private lateinit var getControlPlanThemesByYear: GetControlPlanThemesByYear + + @Test + fun `Should get all control plan themes`() { + // Given + val controlPlanTheme = ControlPlanThemeEntity( + id = 1, + theme = "Theme Police des mouillages", + subTheme = "Sous Theme Mouillage individuel", + allowedTags = listOf("tag1", "tag2"), + year = 2024, + ) + BDDMockito.given(getControlPlanThemesByYear.execute(2024)).willReturn(listOf(controlPlanTheme)) + // When + mockMvc.perform(get("/bff/v1/controlplanthemes/2024")) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$[0].id").value(controlPlanTheme.id)) + .andExpect(jsonPath("$[0].theme").value(controlPlanTheme.theme)) + .andExpect(jsonPath("$[0].subTheme").value(controlPlanTheme.subTheme)) + .andExpect(jsonPath("$[0].year").value(controlPlanTheme.year)) + .andExpect(jsonPath("$[0].allowedTags[0]").value(controlPlanTheme.allowedTags?.get(0))) + .andExpect(jsonPath("$[0].allowedTags[1]").value(controlPlanTheme.allowedTags?.get(1))) + + verify(getControlPlanThemesByYear).execute(2024) + } +} From 3a5ca86f7545077ee2e24953f7cf289356445332 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 06/53] wip --- .../ControlPlanThemeEntity.kt | 4 +- .../EnvActionControlPlanSubThemeEntity.kt | 8 +++ .../mission/envAction/EnvActionEntity.kt | 3 +- .../envAction/EnvActionSurveillanceEntity.kt | 8 ++- .../EnvActionSurveillanceProperties.kt | 19 +++--- .../entities/mission/envAction/ThemeEntity.kt | 1 + .../EnvActionControlEntity.kt | 15 ++-- .../EnvActionControlProperties.kt | 40 +++++------ .../domain/mappers/EnvActionMapper.kt | 48 +++++++------ .../IControlPlanSubThemeRepository.kt | 7 ++ .../IControlPlanThemeRepository.kt | 7 -- .../repositories/IControlThemeRepository.kt | 2 +- .../GetControlPlanSubThemesByYear.kt | 16 +++++ .../GetControlPlanThemesByYear.kt | 16 ----- .../controlThemes/GetAllControlThemes.kt | 2 +- .../missions/MissionEnvActionDataInput.kt | 4 ++ .../outputs/ControlPlanSubThemeDataOutput.kt | 22 ++++++ .../bff/outputs/ControlPlanThemeDataOutput.kt | 22 ------ .../MissionEnvActionControlDataOutput.kt | 6 ++ .../MissionEnvActionSubThemeDataOutput.kt | 22 ++++++ ...r.kt => ControlPlanSubThemesController.kt} | 18 ++--- .../endpoints/bff/ControlThemesController.kt | 2 +- .../model/ControlPlanSubThemeModel.kt | 8 +-- .../database/model/EnvActionModel.kt | 54 +++++++++++---- .../database/model/EnvActionsSubThemeModel.kt | 68 +++++++++++++++++++ .../JpaControlPlanSubThemeRepository.kt | 15 ++++ .../JpaControlPlanThemeRepository.kt | 15 ---- .../repositories/JpaControlThemeRepository.kt | 2 +- ...kt => IDBControlPlanSubThemeRepository.kt} | 2 +- .../interfaces/IDBControlThemeRepository.kt | 2 +- .../GetAllControlPlanThemesUTest.kt | 41 ----------- .../GetControlPlanSubThemesByYearUTest.kt | 41 +++++++++++ ...> ControlPlanSubThemesControllerITests.kt} | 30 ++++---- .../JpaControlPlanSubThemeRepositoryITests.kt | 31 +++++++++ .../JpaControlPlanThemeRepositoryITests.kt | 29 -------- 35 files changed, 392 insertions(+), 238 deletions(-) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanThemesByYear.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt rename backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/{ControlPlanThemesController.kt => ControlPlanSubThemesController.kt} (55%) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt rename backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/{IDBControlPlanThemeRepository.kt => IDBControlPlanSubThemeRepository.kt} (76%) delete mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetAllControlPlanThemesUTest.kt create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt rename backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/{ControlPlanThemesControllerITests.kt => ControlPlanSubThemesControllerITests.kt} (50%) create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt delete mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt index 7d2655896..8645a3bb4 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt @@ -1,6 +1,6 @@ -package fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme +package fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme -data class ControlPlanThemeEntity( +data class ControlPlanSubThemeEntity( val id: Int, val theme: String, val subTheme: String, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt new file mode 100644 index 000000000..2fb3ef3ad --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt @@ -0,0 +1,8 @@ +package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction + +data class EnvActionControlPlanSubThemeEntity( + val subThemeId: Int, + val tags: List, + val theme: String, + val subTheme: String, +) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt index 64eb35fa9..b577a922e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt @@ -21,8 +21,9 @@ import java.util.UUID abstract class EnvActionEntity( open val id: UUID, open val actionType: ActionTypeEnum, - open val actionStartDateTimeUtc: ZonedDateTime? = null, open val actionEndDateTimeUtc: ZonedDateTime? = null, + open val actionStartDateTimeUtc: ZonedDateTime? = null, + open val controlPlanSubThemes: List? = listOf(), open val department: String? = null, open val facade: String? = null, open val geom: Geometry? = null, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt index 5720faffb..8da15ce1f 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt @@ -6,14 +6,16 @@ import java.util.UUID data class EnvActionSurveillanceEntity( override val id: UUID, - override val actionStartDateTimeUtc: ZonedDateTime? = null, override val actionEndDateTimeUtc: ZonedDateTime? = null, + override val actionStartDateTimeUtc: ZonedDateTime? = null, + override val controlPlanSubThemes: List? = listOf(), override val geom: Geometry? = null, override val facade: String? = null, override val department: String? = null, - val themes: List? = listOf(), - val observations: String? = null, val coverMissionZone: Boolean? = null, + val observations: String? = null, + @Deprecated("Use ControlPlanSubThemes instead") + val themes: List? = listOf(), ) : EnvActionEntity( actionType = ActionTypeEnum.SURVEILLANCE, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt index 68381345c..113178069 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt @@ -5,35 +5,38 @@ import java.time.ZonedDateTime import java.util.* data class EnvActionSurveillanceProperties( - val themes: List? = listOf(), - val observations: String? = null, val coverMissionZone: Boolean? = null, + val observations: String? = null, + @Deprecated("Use ControlPlanSubThemes instead") + val themes: List? = listOf(), ) { fun toEnvActionSurveillanceEntity( id: UUID, actionStartDateTimeUtc: ZonedDateTime?, actionEndDateTimeUtc: ZonedDateTime?, - facade: String?, + controlPlanSubThemes: List?, department: String?, + facade: String?, geom: Geometry?, ) = EnvActionSurveillanceEntity( id = id, actionStartDateTimeUtc = actionStartDateTimeUtc, actionEndDateTimeUtc = actionEndDateTimeUtc, - facade = facade, + controlPlanSubThemes = controlPlanSubThemes, + coverMissionZone = coverMissionZone, department = department, + facade = facade, geom = geom, - themes = themes, observations = observations, - coverMissionZone = coverMissionZone, + themes = themes, ) companion object { fun fromEnvActionSurveillanceEntity(envAction: EnvActionSurveillanceEntity) = EnvActionSurveillanceProperties( - themes = envAction.themes, - observations = envAction.observations, coverMissionZone = envAction.coverMissionZone, + observations = envAction.observations, + themes = envAction.themes, ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/ThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/ThemeEntity.kt index fcd2333a8..7ed8ee5bf 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/ThemeEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/ThemeEntity.kt @@ -1,5 +1,6 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction +@Deprecated("Use EnvActionControlPlanSubThemeEntity instead") data class ThemeEntity( val theme: String? = null, val subThemes: List? = listOf(), diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt index fb009e592..bdd08cc0a 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt @@ -2,6 +2,7 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionCont import fr.gouv.cacem.monitorenv.domain.entities.VehicleTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.InfractionEntity @@ -11,21 +12,23 @@ import java.util.UUID data class EnvActionControlEntity( override val id: UUID, - override val actionStartDateTimeUtc: ZonedDateTime? = null, override val actionEndDateTimeUtc: ZonedDateTime? = null, - override val geom: Geometry? = null, - override val facade: String? = null, + override val actionStartDateTimeUtc: ZonedDateTime? = null, + override val controlPlanSubThemes: List? = listOf(), override val department: String? = null, + override val facade: String? = null, + override val geom: Geometry? = null, override val isAdministrativeControl: Boolean? = null, override val isComplianceWithWaterRegulationsControl: Boolean? = null, override val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, override val isSeafarersControl: Boolean? = null, - val themes: List? = listOf(), - val observations: String? = null, val actionNumberOfControls: Int? = null, val actionTargetType: ActionTargetTypeEnum? = null, - val vehicleType: VehicleTypeEnum? = null, val infractions: List? = listOf(), + val observations: String? = null, + @Deprecated("Use ControlPlanSubThemes instead") + val themes: List? = listOf(), + val vehicleType: VehicleTypeEnum? = null, ) : EnvActionEntity( id = id, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt index 4d7988c55..4d9af6c55 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt @@ -1,6 +1,7 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl import fr.gouv.cacem.monitorenv.domain.entities.VehicleTypeEnum +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.InfractionEntity import org.locationtech.jts.geom.Geometry @@ -8,19 +9,21 @@ import java.time.ZonedDateTime import java.util.UUID data class EnvActionControlProperties( - val themes: List? = listOf(), - val observations: String? = null, val actionNumberOfControls: Int? = null, val actionTargetType: ActionTargetTypeEnum? = null, - val vehicleType: VehicleTypeEnum? = null, val infractions: List? = listOf(), + val observations: String? = null, + @Deprecated("Use ControlPlanSubThemes instead") + val themes: List? = listOf(), + val vehicleType: VehicleTypeEnum? = null, ) { fun toEnvActionControlEntity( id: UUID, - actionStartDateTimeUtc: ZonedDateTime?, actionEndDateTimeUtc: ZonedDateTime?, - facade: String?, + actionStartDateTimeUtc: ZonedDateTime?, + controlPlanSubThemes: List?, department: String?, + facade: String?, geom: Geometry?, isAdministrativeControl: Boolean?, isComplianceWithWaterRegulationsControl: Boolean?, @@ -29,34 +32,33 @@ data class EnvActionControlProperties( ) = EnvActionControlEntity( id = id, - actionStartDateTimeUtc = actionStartDateTimeUtc, actionEndDateTimeUtc = actionEndDateTimeUtc, - facade = facade, - department = department, - geom = geom, - themes = themes, - observations = observations, actionNumberOfControls = actionNumberOfControls, + actionStartDateTimeUtc = actionStartDateTimeUtc, actionTargetType = actionTargetType, - vehicleType = vehicleType, + controlPlanSubThemes = controlPlanSubThemes, + department = department, + facade = facade, + geom = geom, infractions = infractions, isAdministrativeControl = isAdministrativeControl, - isComplianceWithWaterRegulationsControl = - isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - isSafetyEquipmentAndStandardsComplianceControl, + isComplianceWithWaterRegulationsControl = isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = isSafetyEquipmentAndStandardsComplianceControl, isSeafarersControl = isSeafarersControl, + observations = observations, + themes = themes, + vehicleType = vehicleType, ) companion object { fun fromEnvActionControlEntity(envAction: EnvActionControlEntity) = EnvActionControlProperties( - themes = envAction.themes, - observations = envAction.observations, actionNumberOfControls = envAction.actionNumberOfControls, actionTargetType = envAction.actionTargetType, - vehicleType = envAction.vehicleType, infractions = envAction.infractions, + observations = envAction.observations, + themes = envAction.themes, + vehicleType = envAction.vehicleType, ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt index b1f81abe8..d470150a7 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt @@ -2,6 +2,7 @@ package fr.gouv.cacem.monitorenv.domain.mappers import com.fasterxml.jackson.databind.ObjectMapper import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionNoteEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionNoteProperties @@ -22,17 +23,18 @@ object EnvActionMapper { fun getEnvActionEntityFromJSON( mapper: ObjectMapper, id: UUID, - actionStartDateTimeUtc: ZonedDateTime?, actionEndDateTimeUtc: ZonedDateTime?, - geom: Geometry?, actionType: ActionTypeEnum, - facade: String?, + actionStartDateTimeUtc: ZonedDateTime?, + controlPlanSubThemes: List?, department: String?, - value: String?, + facade: String?, + geom: Geometry?, isAdministrativeControl: Boolean?, isComplianceWithWaterRegulationsControl: Boolean?, isSafetyEquipmentAndStandardsComplianceControl: Boolean?, isSeafarersControl: Boolean?, + value: String?, ): EnvActionEntity { return try { if (!value.isNullOrEmpty() && value != jsonbNullString) { @@ -43,12 +45,13 @@ object EnvActionMapper { EnvActionSurveillanceProperties::class.java, ) .toEnvActionSurveillanceEntity( - id, - actionStartDateTimeUtc, - actionEndDateTimeUtc, - facade, - department, - geom, + id = id, + actionEndDateTimeUtc = actionEndDateTimeUtc, + actionStartDateTimeUtc = actionStartDateTimeUtc, + controlPlanSubThemes = controlPlanSubThemes, + department = department, + facade = facade, + geom = geom, ) ActionTypeEnum.CONTROL -> mapper.readValue( @@ -56,16 +59,17 @@ object EnvActionMapper { EnvActionControlProperties::class.java, ) .toEnvActionControlEntity( - id, - actionStartDateTimeUtc, - actionEndDateTimeUtc, - facade, - department, - geom, - isAdministrativeControl, - isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl, + id = id, + actionEndDateTimeUtc = actionEndDateTimeUtc, + actionStartDateTimeUtc = actionStartDateTimeUtc, + controlPlanSubThemes = controlPlanSubThemes, + department = department, + facade = facade, + geom = geom, + isAdministrativeControl = isAdministrativeControl, + isComplianceWithWaterRegulationsControl = isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = isSeafarersControl, ) ActionTypeEnum.NOTE -> mapper.readValue( @@ -73,8 +77,8 @@ object EnvActionMapper { EnvActionNoteProperties::class.java, ) .toEnvActionNoteEntity( - id, - actionStartDateTimeUtc, + id = id, + actionStartDateTimeUtc = actionStartDateTimeUtc, ) } } else { diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt new file mode 100644 index 000000000..4c501f2c0 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt @@ -0,0 +1,7 @@ +package fr.gouv.cacem.monitorenv.domain.repositories + +import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity + +interface IControlPlanSubThemeRepository { + fun findByYear(year: Int): List +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt deleted file mode 100644 index 7f78f2c7c..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.repositories - -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity - -interface IControlPlanThemeRepository { - fun findByYear(year: Int): List -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt index 1ca10226c..655f12a3b 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt @@ -2,7 +2,7 @@ package fr.gouv.cacem.monitorenv.domain.repositories import fr.gouv.cacem.monitorenv.domain.entities.controlTheme.ControlThemeEntity -@Deprecated("Use ControlPlanThemeRepository instead") +@Deprecated("Use ControlPlanSubThemeRepository instead") interface IControlThemeRepository { fun findById(controlThemeId: Int): ControlThemeEntity fun findAll(): List diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt new file mode 100644 index 000000000..a1d2b4309 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt @@ -0,0 +1,16 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes + +import fr.gouv.cacem.monitorenv.config.UseCase +import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository +import org.slf4j.LoggerFactory + +@UseCase +class GetControlPlanSubThemesByYear(private val ControlPlanSubThemeRepository: IControlPlanSubThemeRepository) { + private val logger = LoggerFactory.getLogger(GetControlPlanSubThemesByYear::class.java) + fun execute(year: Int): List { + val ControlPlanSubThemes = ControlPlanSubThemeRepository.findByYear(year) + logger.info("Found ${ControlPlanSubThemes.size} control plan (sub)themes for year $year") + return ControlPlanSubThemes + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanThemesByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanThemesByYear.kt deleted file mode 100644 index 32762352e..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanThemesByYear.kt +++ /dev/null @@ -1,16 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanThemes - -import fr.gouv.cacem.monitorenv.config.UseCase -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity -import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository -import org.slf4j.LoggerFactory - -@UseCase -class GetControlPlanThemesByYear(private val controlPlanThemeRepository: IControlPlanThemeRepository) { - private val logger = LoggerFactory.getLogger(GetControlPlanThemesByYear::class.java) - fun execute(year: Int): List { - val controlPlanThemes = controlPlanThemeRepository.findByYear(year) - logger.info("Found ${controlPlanThemes.size} control plan (sub)themes for year $year") - return controlPlanThemes - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt index 7c9076f8d..69b2e7dc4 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt @@ -7,7 +7,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlTheme.ControlThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlThemeRepository import org.slf4j.LoggerFactory -@Deprecated("Use GetControlPlanThemesByYear instead") +@Deprecated("Use GetControlPlanSubThemesByYear instead") @UseCase class GetAllControlThemes(private val controlThemeRepository: IControlThemeRepository) { private val logger = LoggerFactory.getLogger(GetAllControlThemes::class.java) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt index 70eb9df70..dca32492b 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt @@ -23,6 +23,8 @@ data class MissionEnvActionDataInput( // EnvActionControl + EnvSurveillance Properties val actionEndDateTimeUtc: ZonedDateTime? = null, + val controlPlanSubThemes: List? = null, + @Deprecated("Use controlPlanSubThemes instead") val themes: List? = null, val department: String? = null, val facade: String? = null, @@ -108,3 +110,5 @@ data class MissionEnvActionDataInput( } } } + +typealias ControlPlanSubThemeDataInput = Pair> diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt new file mode 100644 index 000000000..8aae90395 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt @@ -0,0 +1,22 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs + +import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity + +data class ControlPlanSubThemeDataOutput( + val id: Int, + val theme: String, + val subTheme: String, + val allowedTags: List? = null, + val year: Int, +) { + companion object { + fun fromControlPlanSubThemeEntity(ControlPlanSubTheme: ControlPlanSubThemeEntity) = + ControlPlanSubThemeDataOutput( + id = ControlPlanSubTheme.id, + theme = ControlPlanSubTheme.theme, + subTheme = ControlPlanSubTheme.subTheme, + allowedTags = ControlPlanSubTheme.allowedTags, + year = ControlPlanSubTheme.year, + ) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt deleted file mode 100644 index aadb4f65f..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt +++ /dev/null @@ -1,22 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs - -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity - -data class ControlPlanThemeDataOutput( - val id: Int, - val theme: String, - val subTheme: String, - val allowedTags: List? = null, - val year: Int, -) { - companion object { - fun fromControlPlanThemeEntity(controlPlanTheme: ControlPlanThemeEntity) = - ControlPlanThemeDataOutput( - id = controlPlanTheme.id, - theme = controlPlanTheme.theme, - subTheme = controlPlanTheme.subTheme, - allowedTags = controlPlanTheme.allowedTags, - year = controlPlanTheme.year, - ) - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt index cbeef65c1..cc0bf8527 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt @@ -17,6 +17,7 @@ data class MissionEnvActionControlDataOutput( override val actionStartDateTimeUtc: ZonedDateTime? = null, val actionTargetType: ActionTargetTypeEnum? = null, override val actionType: ActionTypeEnum = ActionTypeEnum.CONTROL, + val controlPlans: List? = listOf(), val department: String? = null, val facade: String? = null, val geom: Geometry? = null, @@ -27,7 +28,9 @@ data class MissionEnvActionControlDataOutput( val isSeafarersControl: Boolean? = null, val observations: String? = null, val reportingIds: List, + @Deprecated("Use ControlPlanSubThemes instead") val themes: List? = listOf(), + val controlPlanSubThemes: List? = listOf(), val vehicleType: VehicleTypeEnum? = null, ) : MissionEnvActionDataOutput( @@ -46,6 +49,9 @@ data class MissionEnvActionControlDataOutput( actionStartDateTimeUtc = envActionControlEntity.actionStartDateTimeUtc, actionEndDateTimeUtc = envActionControlEntity.actionEndDateTimeUtc, actionTargetType = envActionControlEntity.actionTargetType, + controlPlanSubThemes = envActionControlEntity.controlPlanSubThemes?.map { + MissionEnvActionSubThemeDataOutput.fromEnvActionControlPlanSubThemeEntity(it) + }, department = envActionControlEntity.department, facade = envActionControlEntity.facade, geom = envActionControlEntity.geom, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt new file mode 100644 index 000000000..a51a1ca3f --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt @@ -0,0 +1,22 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.missions + +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity + +data class MissionEnvActionSubThemeDataOutput( + val id: Int, + val subTheme: String, + val theme: String, + val tags: List, +) { + companion object { + fun fromEnvActionControlPlanSubThemeEntity( + envActionControlPlanSubThemeEntity: EnvActionControlPlanSubThemeEntity, + ) = + MissionEnvActionSubThemeDataOutput( + id = envActionControlPlanSubThemeEntity.subThemeId, + theme = envActionControlPlanSubThemeEntity.theme, + subTheme = envActionControlPlanSubThemeEntity.subTheme, + tags = envActionControlPlanSubThemeEntity.tags, + ) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt similarity index 55% rename from backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesController.kt rename to backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt index 7b3ccdd41..cf40bd3bb 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt @@ -1,7 +1,7 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff -import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanThemes.GetControlPlanThemesByYear -import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.ControlPlanThemeDataOutput +import fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes.GetControlPlanSubThemesByYear +import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.ControlPlanSubThemeDataOutput import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.tags.Tag import jakarta.websocket.server.PathParam @@ -11,10 +11,10 @@ import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController -@RequestMapping("/bff/v1/controlplanthemes") -@Tag(name = "Control Plan Themes", description = "API thématiques du plan de contrôle") -class ControlPlanThemesController( - private val getControlPlanThemesByYear: GetControlPlanThemesByYear, +@RequestMapping("/bff/v1/controlPlanSubThemes") +@Tag(name = "Control Plan Sub Themes", description = "API des sous thématiques des plan de contrôle") +class ControlPlanSubThemesController( + private val getControlPlanSubThemesByYear: GetControlPlanSubThemesByYear, ) { @GetMapping("/{year}") @@ -23,8 +23,8 @@ class ControlPlanThemesController( @PathParam("validity year of the control plan themes") @PathVariable(name = "year") year: Int, - ): List { - val controlPlanThemes = getControlPlanThemesByYear.execute(year) - return controlPlanThemes.map { ControlPlanThemeDataOutput.fromControlPlanThemeEntity(it) } + ): List { + val ControlPlanSubThemes = getControlPlanSubThemesByYear.execute(year) + return ControlPlanSubThemes.map { ControlPlanSubThemeDataOutput.fromControlPlanSubThemeEntity(it) } } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt index 06df29fed..fe39e6cb8 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt @@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -@Deprecated("Use ControlPlanThemesController instead") +@Deprecated("Use ControlPlanSubThemesController instead") @RestController @RequestMapping("/bff/v1/controlthemes") @Tag(name = "BFF.Control Themes", description = "API control themes") diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt index a205ec59e..9f98e9b2a 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt @@ -1,6 +1,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.model -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity import io.hypersistence.utils.hibernate.type.array.ListArrayType import jakarta.persistence.Column import jakarta.persistence.Entity @@ -23,7 +23,7 @@ data class ControlPlanSubThemeModel( @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "theme_id") - val controlPlanTheme: ControlPlanThemeModel, + val ControlPlanTheme: ControlPlanThemeModel, @Column(name = "year") val year: Int, @@ -32,10 +32,10 @@ data class ControlPlanSubThemeModel( @Type(ListArrayType::class) val allowedTags: List? = null, ) { - fun toControlPlanTheme() = ControlPlanThemeEntity( + fun toControlPlanSubTheme() = ControlPlanSubThemeEntity( id = id, subTheme = subTheme, - theme = controlPlanTheme.theme, + theme = ControlPlanTheme.theme, year = year, allowedTags = allowedTags, ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt index 225a1adb7..13fb0df8c 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt @@ -43,54 +43,76 @@ data class EnvActionModel( @JdbcType(UUIDJdbcType::class) @Column(name = "id", nullable = false, updatable = false, columnDefinition = "uuid") val id: UUID, - @Column(name = "action_start_datetime_utc") val actionStartDateTime: Instant? = null, - @Column(name = "action_end_datetime_utc") val actionEndDateTime: Instant? = null, + + @Column(name = "action_start_datetime_utc") + val actionStartDateTime: Instant? = null, + + @Column(name = "action_end_datetime_utc") + val actionEndDateTime: Instant? = null, + @JsonSerialize(using = GeometrySerializer::class) @JsonDeserialize(contentUsing = GeometryDeserializer::class) @Column(name = "geom") val geom: Geometry? = null, + @Column(name = "action_type") @Enumerated(EnumType.STRING) val actionType: ActionTypeEnum, + @Type(JsonBinaryType::class) @Column(name = "value", columnDefinition = "jsonb") val value: String, + @Column(name = "facade") val facade: String? = null, @Column(name = "department") val department: String? = null, @ManyToOne(fetch = FetchType.EAGER, optional = false) @JoinColumn(name = "mission_id") @JsonBackReference val mission: MissionModel, - @Column(name = "is_administrative_control") val isAdministrativeControl: Boolean? = null, + + @Column(name = "is_administrative_control") + val isAdministrativeControl: Boolean? = null, + @Column(name = "is_compliance_with_water_regulations_control") val isComplianceWithWaterRegulationsControl: Boolean? = null, + @Column(name = "is_safety_equipment_and_standards_compliance_control") val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - @Column(name = "is_seafarers_control") val isSeafarersControl: Boolean? = null, + + @Column(name = "is_seafarers_control") + val isSeafarersControl: Boolean? = null, + @OneToMany( fetch = FetchType.EAGER, mappedBy = "attachedEnvAction", ) @JsonManagedReference val attachedReporting: List? = listOf(), + + @OneToMany( + fetch = FetchType.EAGER, + mappedBy = "envAction", + ) + val controlPlanSubThemes: List? = listOf(), ) { fun toActionEntity(mapper: ObjectMapper): EnvActionEntity { return EnvActionMapper.getEnvActionEntityFromJSON( mapper = mapper, id = id, - actionStartDateTimeUtc = actionStartDateTime?.atZone(UTC), actionEndDateTimeUtc = actionEndDateTime?.atZone(UTC), - geom = geom, actionType = actionType, - facade = facade, + actionStartDateTimeUtc = actionStartDateTime?.atZone(UTC), + controlPlanSubThemes = controlPlanSubThemes?.map { it.toEnvActionControlPlanSubThemeEntity() }, department = department, - value = value, + facade = facade, + geom = geom, isAdministrativeControl = isAdministrativeControl, isComplianceWithWaterRegulationsControl = isComplianceWithWaterRegulationsControl, isSafetyEquipmentAndStandardsComplianceControl = isSafetyEquipmentAndStandardsComplianceControl, isSeafarersControl = isSeafarersControl, + value = value, ) } companion object { @@ -101,20 +123,26 @@ data class EnvActionModel( ) = EnvActionModel( id = action.id, + actionEndDateTime = action.actionEndDateTimeUtc?.toInstant(), actionType = action.actionType, actionStartDateTime = action.actionStartDateTimeUtc?.toInstant(), - actionEndDateTime = action.actionEndDateTimeUtc?.toInstant(), - facade = action.facade, + controlPlanSubThemes = action.controlPlanSubThemes?.map { + EnvActionsSubThemeModel.fromEnvActionControlPlanSubThemeEntity( + envActionId = action.id, + envActionControlPlanSubTheme = it, + ) + }, department = action.department, - value = EnvActionMapper.envActionEntityToJSON(mapper, action), - mission = mission, - geom = action.geom, + facade = action.facade, isAdministrativeControl = action.isAdministrativeControl, isComplianceWithWaterRegulationsControl = action.isComplianceWithWaterRegulationsControl, isSafetyEquipmentAndStandardsComplianceControl = action.isSafetyEquipmentAndStandardsComplianceControl, isSeafarersControl = action.isSeafarersControl, + mission = mission, + geom = action.geom, + value = EnvActionMapper.envActionEntityToJSON(mapper, action), ) } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt new file mode 100644 index 000000000..78fb12a7e --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt @@ -0,0 +1,68 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.model + +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity +import io.hypersistence.utils.hibernate.type.array.ListArrayType +import jakarta.persistence.Column +import jakarta.persistence.Embeddable +import jakarta.persistence.EmbeddedId +import jakarta.persistence.Entity +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne +import jakarta.persistence.MapsId +import jakarta.persistence.Table +import org.hibernate.annotations.Type +import java.io.Serializable +import java.util.UUID + +@Entity +@Table(name = "env_actions_subthemes") +data class EnvActionsSubThemeModel( + + @EmbeddedId + val id: EnvActionsSubThemePk, + + @ManyToOne + @MapsId("envActionId") + @JoinColumn(name = "env_action_id") + val envAction: EnvActionModel? = null, + + @ManyToOne + @MapsId("subthemeId") + @JoinColumn(name = "subtheme_id") + val controlPlanSubTheme: ControlPlanSubThemeModel? = null, + + @Column(name = "tags") + @Type(ListArrayType::class) + val tags: List? = null, +) { + fun toEnvActionControlPlanSubThemeEntity(): EnvActionControlPlanSubThemeEntity { + require(controlPlanSubTheme != null) { "controlPlanSubTheme must not be null when converting to Entity" } + return EnvActionControlPlanSubThemeEntity( + subThemeId = controlPlanSubTheme.id, + theme = controlPlanSubTheme.ControlPlanTheme.theme, + subTheme = controlPlanSubTheme.subTheme, + tags = tags ?: emptyList(), + ) + } + companion object { + fun fromEnvActionControlPlanSubThemeEntity( + envActionId: UUID, + envActionControlPlanSubTheme: EnvActionControlPlanSubThemeEntity, + ) = EnvActionsSubThemeModel( + id = EnvActionsSubThemePk( + envActionId = envActionId, + subthemeId = envActionControlPlanSubTheme.subThemeId, + ), + tags = envActionControlPlanSubTheme.tags, + ) + } +} + +@Embeddable +data class EnvActionsSubThemePk( + @Column(name = "env_action_id") + val envActionId: UUID, + + @Column(name = "subtheme_id") + val subthemeId: Int, +) : Serializable diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt new file mode 100644 index 000000000..579feffeb --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt @@ -0,0 +1,15 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories + +import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository +import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanSubThemeRepository +import org.springframework.stereotype.Repository + +@Repository +class JpaControlPlanSubThemeRepository( + private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, +) : IControlPlanSubThemeRepository { + override fun findByYear(year: Int): List { + return dbControlPlanSubThemeRepository.findByYearOrderById(year).map { it.toControlPlanSubTheme() } + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt deleted file mode 100644 index e263343f0..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt +++ /dev/null @@ -1,15 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.database.repositories - -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity -import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository -import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanThemeRepository -import org.springframework.stereotype.Repository - -@Repository -class JpaControlPlanThemeRepository( - private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, -) : IControlPlanThemeRepository { - override fun findByYear(year: Int): List { - return dbControlPlanThemeRepository.findByYearOrderById(year).map { it.toControlPlanTheme() } - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlThemeRepository.kt index 79dda9b0c..be90d2af1 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlThemeRepository.kt @@ -5,7 +5,7 @@ import fr.gouv.cacem.monitorenv.domain.repositories.IControlThemeRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlThemeRepository import org.springframework.stereotype.Repository -@Deprecated("Use JpaControlPlanThemeRepository instead") +@Deprecated("Use JpaControlPlanSubThemeRepository instead") @Repository class JpaControlThemeRepository(private val dbControlThemeRepository: IDBControlThemeRepository) : IControlThemeRepository { diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt similarity index 76% rename from backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt rename to backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt index 8a132af85..bd6acea2f 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt @@ -3,6 +3,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanSubThemeModel import org.springframework.data.repository.CrudRepository -interface IDBControlPlanThemeRepository : CrudRepository { +interface IDBControlPlanSubThemeRepository : CrudRepository { fun findByYearOrderById(year: Int): List } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlThemeRepository.kt index 709f0a229..f31d355bc 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlThemeRepository.kt @@ -3,5 +3,5 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlThemeModel import org.springframework.data.repository.CrudRepository -@Deprecated("Use IDBControlPlanThemeRepository instead") +@Deprecated("Use IDBControlPlanSubThemeRepository instead") interface IDBControlThemeRepository : CrudRepository diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetAllControlPlanThemesUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetAllControlPlanThemesUTest.kt deleted file mode 100644 index fc3e517fb..000000000 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetAllControlPlanThemesUTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanThemes - -import com.nhaarman.mockitokotlin2.given -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity -import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.extension.ExtendWith -import org.springframework.boot.test.mock.mockito.MockBean -import org.springframework.test.context.junit.jupiter.SpringExtension - -@ExtendWith(SpringExtension::class) -class GetAllControlPlanThemesUTest { - @MockBean - private lateinit var controlPlanThemeRepository: IControlPlanThemeRepository - - fun `execute should return all controlPlanThemes for the given year`() { - val controlPlanThemes = listOf( - ControlPlanThemeEntity( - id = 1, - theme = "ControlPlanTheme Name", - subTheme = "ControlPlanTheme Name", - allowedTags = listOf("tag1", "tag2"), - year = 2023, - ), - ControlPlanThemeEntity( - id = 2, - theme = "ControlPlanTheme Name 2", - subTheme = "ControlPlanTheme Name 2", - allowedTags = null, - year = 2023, - ), - ) - - given(controlPlanThemeRepository.findByYear(2023)).willReturn(controlPlanThemes) - - val result = GetControlPlanThemesByYear(controlPlanThemeRepository).execute(2023) - - assertThat(result.size).isEqualTo(2) - assertThat(result).isEqualTo(controlPlanThemes) - } -} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt new file mode 100644 index 000000000..d333d2464 --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt @@ -0,0 +1,41 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes + +import com.nhaarman.mockitokotlin2.given +import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.junit.jupiter.SpringExtension + +@ExtendWith(SpringExtension::class) +class GetControlPlanSubThemesByYearUTest { + @MockBean + private lateinit var controlPlanSubThemeRepository: IControlPlanSubThemeRepository + + fun `execute should return all ControlPlanSubThemes for the given year`() { + val controlPlanSubThemes = listOf( + ControlPlanSubThemeEntity( + id = 1, + theme = "ControlPlanTheme Name", + subTheme = "ControlPlanSubTheme Name", + allowedTags = listOf("tag1", "tag2"), + year = 2023, + ), + ControlPlanSubThemeEntity( + id = 2, + theme = "ControlPlanTheme Name 2", + subTheme = "ControlPlanSubTheme Name 2", + allowedTags = null, + year = 2023, + ), + ) + + given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) + + val result = GetControlPlanSubThemesByYear(controlPlanSubThemeRepository).execute(2023) + + assertThat(result.size).isEqualTo(2) + assertThat(result).isEqualTo(controlPlanSubThemes) + } +} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt similarity index 50% rename from backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt rename to backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt index 35c99e37e..3d2fd33e9 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt @@ -2,8 +2,8 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff import com.nhaarman.mockitokotlin2.verify import fr.gouv.cacem.monitorenv.config.WebSecurityConfig -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity -import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanThemes.GetControlPlanThemesByYear +import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes.GetControlPlanSubThemesByYear import org.junit.jupiter.api.Test import org.mockito.BDDMockito import org.springframework.beans.factory.annotation.Autowired @@ -16,36 +16,36 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPat import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status @Import(WebSecurityConfig::class) -@WebMvcTest(value = [(ControlPlanThemesController::class)]) -class ControlPlanThemesControllerITests { +@WebMvcTest(value = [(ControlPlanSubThemesController::class)]) +class ControlPlanSubThemesControllerITests { @Autowired private lateinit var mockMvc: MockMvc @MockBean - private lateinit var getControlPlanThemesByYear: GetControlPlanThemesByYear + private lateinit var getControlPlanSubThemesByYear: GetControlPlanSubThemesByYear @Test fun `Should get all control plan themes`() { // Given - val controlPlanTheme = ControlPlanThemeEntity( + val ControlPlanSubTheme = ControlPlanSubThemeEntity( id = 1, theme = "Theme Police des mouillages", subTheme = "Sous Theme Mouillage individuel", allowedTags = listOf("tag1", "tag2"), year = 2024, ) - BDDMockito.given(getControlPlanThemesByYear.execute(2024)).willReturn(listOf(controlPlanTheme)) + BDDMockito.given(getControlPlanSubThemesByYear.execute(2024)).willReturn(listOf(ControlPlanSubTheme)) // When - mockMvc.perform(get("/bff/v1/controlplanthemes/2024")) + mockMvc.perform(get("/bff/v1/controlPlanSubThemes/2024")) // Then .andExpect(status().isOk) - .andExpect(jsonPath("$[0].id").value(controlPlanTheme.id)) - .andExpect(jsonPath("$[0].theme").value(controlPlanTheme.theme)) - .andExpect(jsonPath("$[0].subTheme").value(controlPlanTheme.subTheme)) - .andExpect(jsonPath("$[0].year").value(controlPlanTheme.year)) - .andExpect(jsonPath("$[0].allowedTags[0]").value(controlPlanTheme.allowedTags?.get(0))) - .andExpect(jsonPath("$[0].allowedTags[1]").value(controlPlanTheme.allowedTags?.get(1))) + .andExpect(jsonPath("$[0].id").value(ControlPlanSubTheme.id)) + .andExpect(jsonPath("$[0].theme").value(ControlPlanSubTheme.theme)) + .andExpect(jsonPath("$[0].subTheme").value(ControlPlanSubTheme.subTheme)) + .andExpect(jsonPath("$[0].year").value(ControlPlanSubTheme.year)) + .andExpect(jsonPath("$[0].allowedTags[0]").value(ControlPlanSubTheme.allowedTags?.get(0))) + .andExpect(jsonPath("$[0].allowedTags[1]").value(ControlPlanSubTheme.allowedTags?.get(1))) - verify(getControlPlanThemesByYear).execute(2024) + verify(getControlPlanSubThemesByYear).execute(2024) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt new file mode 100644 index 000000000..d4965b21c --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt @@ -0,0 +1,31 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +class JpaControlPlanSubThemeRepositoryITests : AbstractDBTests() { + @Autowired + private lateinit var jpaControlPlanSubThemeRepository: JpaControlPlanSubThemeRepository + + @Test + fun `findByYear Should return all control plan theme for a specific year`() { + // When + val requestedControlPlanSubThemesFor2023 = jpaControlPlanSubThemeRepository.findByYear(2023) + val requestedControlPlanSubThemesFor2024 = jpaControlPlanSubThemeRepository.findByYear(2024) + // Then + assertThat(requestedControlPlanSubThemesFor2023.size).isEqualTo(83) + assertThat(requestedControlPlanSubThemesFor2024.size).isEqualTo(7) + assertThat(requestedControlPlanSubThemesFor2024[6].id).isEqualTo(90) + assertThat(requestedControlPlanSubThemesFor2024[6].theme).isEqualTo( + "Police des espèces protégées et de leurs habitats (faune et flore)", + ) + assertThat(requestedControlPlanSubThemesFor2024[6].subTheme).isEqualTo( + "Atteinte aux habitats d’espèces protégées", + ) + assertThat(requestedControlPlanSubThemesFor2024[6].allowedTags).isEqualTo( + listOf("Oiseaux", "Faune", "Flore", "Autres espèces protégées", "Reptiles", "Mammifères marins"), + ) + assertThat(requestedControlPlanSubThemesFor2024[6].year).isEqualTo(2024) + } +} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt deleted file mode 100644 index 24c685682..000000000 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt +++ /dev/null @@ -1,29 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.database.repositories - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired - -class JpaControlPlanThemeRepositoryITests : AbstractDBTests() { - @Autowired - private lateinit var jpaControlPlanThemeRepository: JpaControlPlanThemeRepository - - @Test - fun `findByYear Should return all control plan theme for a specific year`() { - // When - val requestedControlPlanThemesFor2023 = jpaControlPlanThemeRepository.findByYear(2023) - val requestedControlPlanThemesFor2024 = jpaControlPlanThemeRepository.findByYear(2024) - // Then - assertThat(requestedControlPlanThemesFor2023.size).isEqualTo(83) - assertThat(requestedControlPlanThemesFor2024.size).isEqualTo(7) - assertThat(requestedControlPlanThemesFor2024[6].id).isEqualTo(90) - assertThat(requestedControlPlanThemesFor2024[6].theme).isEqualTo( - "Police des espèces protégées et de leurs habitats (faune et flore)", - ) - assertThat(requestedControlPlanThemesFor2024[6].subTheme).isEqualTo("Atteinte aux habitats d’espèces protégées") - assertThat(requestedControlPlanThemesFor2024[6].allowedTags).isEqualTo( - listOf("Oiseaux", "Faune", "Flore", "Autres espèces protégées", "Reptiles", "Mammifères marins"), - ) - assertThat(requestedControlPlanThemesFor2024[6].year).isEqualTo(2024) - } -} From 11d64e5e02704c6af83c5e44f769b7776b0ad619 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 07/53] fix package names, dataoutput + tests on controller --- .../ControlPlanSubThemeEntity.kt} | 2 +- .../IControlPlanSubThemeRepository.kt | 2 +- .../GetControlPlanSubThemesByYear.kt | 12 +++--- ...ateOrUpdateMissionWithAttachedReporting.kt | 2 +- .../use_cases/missions/dtos/MissionDTO.kt | 1 - .../CreateOrUpdateMissionDataInput.kt | 4 +- .../outputs/ControlPlanSubThemeDataOutput.kt | 2 +- .../missions/MissionEnvActionDataOutput.kt | 37 ++++++++++++++++++- .../outputs/missions/MissionsDataOutput.kt | 10 +++-- .../bff/ControlPlanSubThemesController.kt | 2 +- .../model/ControlPlanSubThemeModel.kt | 2 +- .../JpaControlPlanSubThemeRepository.kt | 2 +- .../GetControlPlanSubThemesByYearUTest.kt | 4 +- .../ControlPlanSubThemesControllerITests.kt | 4 +- .../endpoints/bff/MissionsControllerITests.kt | 31 +++++++++++++++- 15 files changed, 91 insertions(+), 26 deletions(-) rename backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/{controlPlanTheme/ControlPlanThemeEntity.kt => controlPlanSubTheme/ControlPlanSubThemeEntity.kt} (73%) rename backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/{controlPlanThemes => controlPlanSubThemes}/GetControlPlanSubThemesByYear.kt (57%) rename backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/{controlPlanThemes => controlPlanSubThemes}/GetControlPlanSubThemesByYearUTest.kt (92%) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubTheme/ControlPlanSubThemeEntity.kt similarity index 73% rename from backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt rename to backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubTheme/ControlPlanSubThemeEntity.kt index 8645a3bb4..8633e1753 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanTheme/ControlPlanThemeEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubTheme/ControlPlanSubThemeEntity.kt @@ -1,4 +1,4 @@ -package fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme +package fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme data class ControlPlanSubThemeEntity( val id: Int, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt index 4c501f2c0..e8701a36a 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt @@ -1,6 +1,6 @@ package fr.gouv.cacem.monitorenv.domain.repositories -import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity interface IControlPlanSubThemeRepository { fun findByYear(year: Int): List diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt similarity index 57% rename from backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt rename to backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt index a1d2b4309..8d2c485a9 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt @@ -1,16 +1,16 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes import fr.gouv.cacem.monitorenv.config.UseCase -import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository import org.slf4j.LoggerFactory @UseCase -class GetControlPlanSubThemesByYear(private val ControlPlanSubThemeRepository: IControlPlanSubThemeRepository) { +class GetControlPlanSubThemesByYear(private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository) { private val logger = LoggerFactory.getLogger(GetControlPlanSubThemesByYear::class.java) fun execute(year: Int): List { - val ControlPlanSubThemes = ControlPlanSubThemeRepository.findByYear(year) - logger.info("Found ${ControlPlanSubThemes.size} control plan (sub)themes for year $year") - return ControlPlanSubThemes + val controlPlanSubThemes = controlPlanSubThemeRepository.findByYear(year) + logger.info("Found ${controlPlanSubThemes.size} control plan (sub)themes for year $year") + return controlPlanSubThemes } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/CreateOrUpdateMissionWithAttachedReporting.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/CreateOrUpdateMissionWithAttachedReporting.kt index dd7034873..aa6f3707e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/CreateOrUpdateMissionWithAttachedReporting.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/CreateOrUpdateMissionWithAttachedReporting.kt @@ -6,8 +6,8 @@ import fr.gouv.cacem.monitorenv.config.UseCase import fr.gouv.cacem.monitorenv.domain.entities.mission.* import fr.gouv.cacem.monitorenv.domain.repositories.IMissionRepository import fr.gouv.cacem.monitorenv.domain.repositories.IReportingRepository +import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.EnvActionAttachedToReportingIds import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO -import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions.EnvActionAttachedToReportingIds import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.exceptions.ReportingAlreadyAttachedException import org.slf4j.LoggerFactory import java.util.UUID diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/dtos/MissionDTO.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/dtos/MissionDTO.kt index f2216404d..69bd0d963 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/dtos/MissionDTO.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/dtos/MissionDTO.kt @@ -2,7 +2,6 @@ package fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionEntity import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos.ReportingDTO -import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions.EnvActionAttachedToReportingIds import java.util.UUID data class MissionDTO( diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/CreateOrUpdateMissionDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/CreateOrUpdateMissionDataInput.kt index bc818b1d6..dcd39b1eb 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/CreateOrUpdateMissionDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/CreateOrUpdateMissionDataInput.kt @@ -5,9 +5,9 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionSourceEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum +import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.EnvActionAttachedToReportingIds import org.locationtech.jts.geom.MultiPolygon import java.time.ZonedDateTime -import java.util.UUID data class CreateOrUpdateMissionDataInput( val id: Int? = null, @@ -64,5 +64,3 @@ data class CreateOrUpdateMissionDataInput( ?: listOf() } } - -typealias EnvActionAttachedToReportingIds = Pair> diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt index 8aae90395..7155b12a6 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt @@ -1,6 +1,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs -import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity data class ControlPlanSubThemeDataOutput( val id: Int, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt index 86f15aee0..698a7970b 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt @@ -1,6 +1,11 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.missions import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionEntity +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionNoteEntity +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionSurveillanceEntity +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity +import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.EnvActionAttachedToReportingIds import java.time.ZonedDateTime import java.util.UUID @@ -8,4 +13,34 @@ abstract class MissionEnvActionDataOutput( open val id: UUID, open val actionStartDateTimeUtc: ZonedDateTime? = null, open val actionType: ActionTypeEnum, -) +) { + companion object { + fun fromEnvActionEntity( + envActionEntity: EnvActionEntity, + envActionsAttachedToReportingIds: List?, + ): MissionEnvActionDataOutput { + return when (envActionEntity.actionType) { + ActionTypeEnum.CONTROL -> + MissionEnvActionControlDataOutput + .fromEnvActionControlEntity( + envActionControlEntity = envActionEntity as EnvActionControlEntity, + reportingIds = envActionsAttachedToReportingIds?.find { id -> + id.first == envActionEntity.id + }?.second ?: listOf(), + ) + ActionTypeEnum.SURVEILLANCE -> + MissionEnvActionSurveillanceDataOutput + .fromEnvActionSurveillanceEntity( + envActionSurveillanceEntity = envActionEntity as EnvActionSurveillanceEntity, + reportingIds = envActionsAttachedToReportingIds?.find { id -> + id.first == envActionEntity.id + }?.second ?: listOf(), + ) + ActionTypeEnum.NOTE -> + MissionEnvActionNoteDataOutput.fromEnvActionNoteEntity( + envActionEntity as EnvActionNoteEntity, + ) + } + } + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionsDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionsDataOutput.kt index 199f58b28..463553c2a 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionsDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionsDataOutput.kt @@ -3,7 +3,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.mission import fr.gouv.cacem.monitorenv.domain.entities.controlUnit.LegacyControlUnitEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionSourceEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionTypeEnum -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionEntity import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO import org.locationtech.jts.geom.MultiPolygon import java.time.ZonedDateTime @@ -20,7 +19,7 @@ data class MissionsDataOutput( val geom: MultiPolygon? = null, val startDateTimeUtc: ZonedDateTime, val endDateTimeUtc: ZonedDateTime? = null, - val envActions: List? = null, + val envActions: List? = null, val missionSource: MissionSourceEnum, val isClosed: Boolean, val hasMissionOrder: Boolean, @@ -43,7 +42,12 @@ data class MissionsDataOutput( geom = dto.mission.geom, startDateTimeUtc = dto.mission.startDateTimeUtc, endDateTimeUtc = dto.mission.endDateTimeUtc, - envActions = dto.mission.envActions, + envActions = dto.mission.envActions?.map { + MissionEnvActionDataOutput.fromEnvActionEntity( + envActionEntity = it, + envActionsAttachedToReportingIds = dto.envActionsAttachedToReportingIds, + ) + }, missionSource = dto.mission.missionSource, isClosed = dto.mission.isClosed, hasMissionOrder = dto.mission.hasMissionOrder, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt index cf40bd3bb..b4f801711 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt @@ -1,6 +1,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff -import fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes.GetControlPlanSubThemesByYear +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes.GetControlPlanSubThemesByYear import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.ControlPlanSubThemeDataOutput import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.tags.Tag diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt index 9f98e9b2a..82f5e0d29 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt @@ -1,6 +1,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.model -import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity import io.hypersistence.utils.hibernate.type.array.ListArrayType import jakarta.persistence.Column import jakarta.persistence.Entity diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt index 579feffeb..cd3a9c474 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt @@ -1,6 +1,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories -import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanSubThemeRepository import org.springframework.stereotype.Repository diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt similarity index 92% rename from backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt rename to backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt index d333d2464..3b457c9d5 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt @@ -1,7 +1,7 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes import com.nhaarman.mockitokotlin2.given -import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.extension.ExtendWith diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt index 3d2fd33e9..59d8cae7a 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt @@ -2,8 +2,8 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff import com.nhaarman.mockitokotlin2.verify import fr.gouv.cacem.monitorenv.config.WebSecurityConfig -import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity -import fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes.GetControlPlanSubThemesByYear +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes.GetControlPlanSubThemesByYear import org.junit.jupiter.api.Test import org.mockito.BDDMockito import org.springframework.beans.factory.annotation.Autowired diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt index 3c0725316..257947f1a 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt @@ -10,6 +10,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionSourceEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.ActionTargetTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity @@ -20,10 +21,10 @@ import fr.gouv.cacem.monitorenv.domain.entities.reporting.SourceTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.reporting.TargetTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.semaphore.SemaphoreEntity import fr.gouv.cacem.monitorenv.domain.use_cases.missions.* +import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.EnvActionAttachedToReportingIds import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos.ReportingDTO import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions.CreateOrUpdateMissionDataInput -import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions.EnvActionAttachedToReportingIds import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions.MissionEnvActionDataInput import org.hamcrest.Matchers.equalTo import org.junit.jupiter.api.Test @@ -141,6 +142,14 @@ class MissionsControllerITests { id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + controlPlanSubThemes = listOf( + EnvActionControlPlanSubThemeEntity( + subThemeId = 1, + subTheme = "sous theme 1", + tags = listOf("tag 1", "tag 2"), + theme = "Theme 1", + ), + ), geom = point, facade = "Outre-Mer", department = "29", @@ -289,6 +298,7 @@ class MissionsControllerITests { mockMvc.perform(get("/bff/v1/missions")) // Then .andExpect(status().isOk) + .andDo(MockMvcResultHandlers.print()) .andExpect(jsonPath("$.length()", equalTo(1))) .andExpect(jsonPath("$[0].id", equalTo(10))) .andExpect( @@ -334,6 +344,11 @@ class MissionsControllerITests { equalTo("2022-01-23T20:29:03Z"), ), ) + .andExpect(jsonPath("$[0].envActions[0].controlPlanSubThemes[0].id", equalTo(1))) + .andExpect(jsonPath("$[0].envActions[0].controlPlanSubThemes[0].theme", equalTo("Theme 1"))) + .andExpect(jsonPath("$[0].envActions[0].controlPlanSubThemes[0].subTheme", equalTo("sous theme 1"))) + .andExpect(jsonPath("$[0].envActions[0].controlPlanSubThemes[0].tags[0]", equalTo("tag 1"))) + .andExpect(jsonPath("$[0].envActions[0].controlPlanSubThemes[0].tags[1]", equalTo("tag 2"))) .andExpect(jsonPath("$[0].envActions[0].geom.type", equalTo("Point"))) .andExpect(jsonPath("$[0].envActions[0].facade", equalTo("Outre-Mer"))) .andExpect(jsonPath("$[0].envActions[0].department", equalTo("29"))) @@ -465,6 +480,14 @@ class MissionsControllerITests { id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + controlPlanSubThemes = listOf( + EnvActionControlPlanSubThemeEntity( + subThemeId = 1, + subTheme = "sous theme 1", + tags = listOf("tag 1", "tag 2"), + theme = "Theme 1", + ), + ), geom = point, facade = "Outre-Mer", department = "29", @@ -601,6 +624,7 @@ class MissionsControllerITests { // When mockMvc.perform(get("/bff/v1/missions/$requestedId")) // Then + .andDo(MockMvcResultHandlers.print()) .andExpect(status().isOk) .andExpect(jsonPath("$.missionTypes[0]", equalTo(MissionTypeEnum.SEA.toString()))) .andExpect(jsonPath("$.id", equalTo(10))) @@ -644,6 +668,11 @@ class MissionsControllerITests { equalTo("2022-01-23T20:29:03Z"), ), ) + .andExpect(jsonPath("$.envActions[0].controlPlanSubThemes[0].id", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlanSubThemes[0].subTheme", equalTo("sous theme 1"))) + .andExpect(jsonPath("$.envActions[0].controlPlanSubThemes[0].tags[0]", equalTo("tag 1"))) + .andExpect(jsonPath("$.envActions[0].controlPlanSubThemes[0].tags[1]", equalTo("tag 2"))) + .andExpect(jsonPath("$.envActions[0].controlPlanSubThemes[0].theme", equalTo("Theme 1"))) .andExpect(jsonPath("$.envActions[0].geom.type", equalTo("Point"))) .andExpect(jsonPath("$.envActions[0].facade", equalTo("Outre-Mer"))) .andExpect(jsonPath("$.envActions[0].department", equalTo("29"))) From 53e1a7a0018c54644e542af3fc30a60eb5001919 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 08/53] wip test --- .../database/repositories/JpaMissionRepositoryITests.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt index 8effac223..14e2f591d 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt @@ -6,6 +6,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlUnit.LegacyControlUnitRes import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionSourceEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionTypeEnum +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionNoteEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionSurveillanceEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity @@ -98,6 +99,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { "33310163-4e22-4d3d-b585-dac4431eb4b5", ), facade = "Facade 1", + controlPlanSubThemes = listOf( + EnvActionControlPlanSubThemeEntity( + subThemeId = 1, + subTheme = "Sub theme 1", + theme = "Theme 1", + tags = listOf("Tag 1", "Tag 2"), + ), + ), department = "Department 1", geom = point, vehicleType = VehicleTypeEnum.VEHICLE_LAND, From 276bda07abf989cbf9a9e9dc3b9c5b721beb594a Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 09/53] fix EnvActionControlPlanSubThemeModel --- .../ControlPlanSubthemeEntity.kt} | 0 ... => EnvActionControlPlanSubthemeEntity.kt} | 6 +- .../missions/ControlPlanSubThemeDataInput.kt | 15 +++++ .../missions/MissionEnvActionDataInput.kt | 15 ++--- .../MissionEnvActionSubThemeDataOutput.kt | 6 +- .../model/ControlPlanSubThemeModel.kt | 33 +++++++--- .../database/model/EnvActionModel.kt | 47 ++++++++------ ... => EnvActionsControlPlanSubThemeModel.kt} | 63 ++++++++++++------ .../database/model/MissionModel.kt | 64 +++++++++++++++---- .../repositories/JpaMissionRepository.kt | 17 ++++- .../IDBControlPlanSubThemeRepository.kt | 4 +- .../internal/V0.103__create_action_theme.sql | 10 +-- 12 files changed, 198 insertions(+), 82 deletions(-) rename backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/{controlPlanSubTheme/ControlPlanSubThemeEntity.kt => controlPlanSubtheme/ControlPlanSubthemeEntity.kt} (100%) rename backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/{EnvActionControlPlanSubThemeEntity.kt => EnvActionControlPlanSubthemeEntity.kt} (58%) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt rename backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/{EnvActionsSubThemeModel.kt => EnvActionsControlPlanSubThemeModel.kt} (55%) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubTheme/ControlPlanSubThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubtheme/ControlPlanSubthemeEntity.kt similarity index 100% rename from backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubTheme/ControlPlanSubThemeEntity.kt rename to backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubtheme/ControlPlanSubthemeEntity.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubthemeEntity.kt similarity index 58% rename from backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt rename to backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubthemeEntity.kt index 2fb3ef3ad..c51b67af9 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubthemeEntity.kt @@ -2,7 +2,7 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction data class EnvActionControlPlanSubThemeEntity( val subThemeId: Int, - val tags: List, - val theme: String, - val subTheme: String, + val tags: List? = null, + val theme: String? = null, + val subTheme: String? = null, ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt new file mode 100644 index 000000000..df563ffea --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt @@ -0,0 +1,15 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions + +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity + +data class ControlPlanSubThemeDataInput( + val id: Int, + val tags: List ? = null, +) { + fun toEnvActionControlPlanSubThemeEntity(): EnvActionControlPlanSubThemeEntity { + return EnvActionControlPlanSubThemeEntity( + subThemeId = this.id, + tags = this.tags, + ) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt index dca32492b..b0e4411c8 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt @@ -70,23 +70,24 @@ data class MissionEnvActionDataInput( ActionTypeEnum.CONTROL -> return EnvActionControlEntity( id = this.id, - actionStartDateTimeUtc = this.actionStartDateTimeUtc, actionEndDateTimeUtc = this.actionEndDateTimeUtc, + actionNumberOfControls = this.actionNumberOfControls, + actionTargetType = this.actionTargetType, + actionStartDateTimeUtc = this.actionStartDateTimeUtc, + controlPlanSubThemes = this.controlPlanSubThemes?.map { it.toEnvActionControlPlanSubThemeEntity() }, department = this.department, facade = this.facade, geom = this.geom, - themes = this.themes, - actionNumberOfControls = this.actionNumberOfControls, - actionTargetType = this.actionTargetType, - vehicleType = this.vehicleType, infractions = this.infractions?.map { it.toInfractionEntity() }, - observations = this.observations, isAdministrativeControl = this.isAdministrativeControl, isComplianceWithWaterRegulationsControl = this.isComplianceWithWaterRegulationsControl, isSafetyEquipmentAndStandardsComplianceControl = this.isSafetyEquipmentAndStandardsComplianceControl, isSeafarersControl = this.isSeafarersControl, + observations = this.observations, + themes = this.themes, + vehicleType = this.vehicleType, ) ActionTypeEnum.SURVEILLANCE -> return EnvActionSurveillanceEntity( @@ -110,5 +111,3 @@ data class MissionEnvActionDataInput( } } } - -typealias ControlPlanSubThemeDataInput = Pair> diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt index a51a1ca3f..1da3192e2 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt @@ -4,9 +4,9 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionContr data class MissionEnvActionSubThemeDataOutput( val id: Int, - val subTheme: String, - val theme: String, - val tags: List, + val subTheme: String? = null, + val theme: String? = null, + val tags: List? = null, ) { companion object { fun fromEnvActionControlPlanSubThemeEntity( diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt index 82f5e0d29..6545c8258 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt @@ -5,38 +5,53 @@ import io.hypersistence.utils.hibernate.type.array.ListArrayType import jakarta.persistence.Column import jakarta.persistence.Entity import jakarta.persistence.FetchType +import jakarta.persistence.GeneratedValue +import jakarta.persistence.GenerationType import jakarta.persistence.Id import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne import jakarta.persistence.Table +import org.hibernate.Hibernate import org.hibernate.annotations.Type @Entity @Table(name = "control_plan_subthemes") -data class ControlPlanSubThemeModel( +class ControlPlanSubThemeModel( @Id - @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false, updatable = false) val id: Int, - @Column(name = "subtheme") - val subTheme: String, + @Column(name = "allowed_tags") + @Type(ListArrayType::class) + val allowedTags: List? = null, @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "theme_id") - val ControlPlanTheme: ControlPlanThemeModel, + val controlPlanTheme: ControlPlanThemeModel, + + @Column(name = "subtheme") + val subTheme: String, @Column(name = "year") val year: Int, - @Column(name = "allowed_tags") - @Type(ListArrayType::class) - val allowedTags: List? = null, ) { fun toControlPlanSubTheme() = ControlPlanSubThemeEntity( id = id, subTheme = subTheme, - theme = ControlPlanTheme.theme, + theme = controlPlanTheme.theme, year = year, allowedTags = allowedTags, ) + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false + other as ControlPlanSubThemeModel + + return id == other.id + } + + override fun hashCode(): Int = javaClass.hashCode() } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt index 13fb0df8c..61dcefdb0 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt @@ -11,6 +11,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionEntity import fr.gouv.cacem.monitorenv.domain.mappers.EnvActionMapper import io.hypersistence.utils.hibernate.type.json.JsonBinaryType +import jakarta.persistence.CascadeType import jakarta.persistence.Column import jakarta.persistence.Entity import jakarta.persistence.EnumType @@ -38,7 +39,7 @@ import java.util.UUID ) @Entity @Table(name = "env_actions") -data class EnvActionModel( +class EnvActionModel( @Id @JdbcType(UUIDJdbcType::class) @Column(name = "id", nullable = false, updatable = false, columnDefinition = "uuid") @@ -63,8 +64,12 @@ data class EnvActionModel( @Column(name = "value", columnDefinition = "jsonb") val value: String, - @Column(name = "facade") val facade: String? = null, - @Column(name = "department") val department: String? = null, + @Column(name = "facade") + val facade: String? = null, + + @Column(name = "department") + val department: String? = null, + @ManyToOne(fetch = FetchType.EAGER, optional = false) @JoinColumn(name = "mission_id") @JsonBackReference @@ -91,9 +96,11 @@ data class EnvActionModel( @OneToMany( fetch = FetchType.EAGER, - mappedBy = "envAction", + cascade = [CascadeType.ALL], + orphanRemoval = true, ) - val controlPlanSubThemes: List? = listOf(), + @JoinColumn(name = "env_action_id") + val controlPlanSubThemes: MutableList? = ArrayList(), ) { fun toActionEntity(mapper: ObjectMapper): EnvActionEntity { @@ -119,19 +126,15 @@ data class EnvActionModel( fun fromEnvActionEntity( action: EnvActionEntity, mission: MissionModel, + controlPlanSubThemesReferenceModelMap: Map, mapper: ObjectMapper, - ) = - EnvActionModel( + ): EnvActionModel { + var envActionModel = EnvActionModel( id = action.id, actionEndDateTime = action.actionEndDateTimeUtc?.toInstant(), actionType = action.actionType, actionStartDateTime = action.actionStartDateTimeUtc?.toInstant(), - controlPlanSubThemes = action.controlPlanSubThemes?.map { - EnvActionsSubThemeModel.fromEnvActionControlPlanSubThemeEntity( - envActionId = action.id, - envActionControlPlanSubTheme = it, - ) - }, + department = action.department, facade = action.facade, isAdministrativeControl = action.isAdministrativeControl, @@ -144,6 +147,18 @@ data class EnvActionModel( geom = action.geom, value = EnvActionMapper.envActionEntityToJSON(mapper, action), ) + action.controlPlanSubThemes?.map { + val envActionControlPlanSubThemeModel = EnvActionsControlPlanSubThemeModel.fromEnvActionControlPlanSubThemeEntity( + envAction = envActionModel, + controlPlanSubTheme = controlPlanSubThemesReferenceModelMap[it.subThemeId]!!, + tags = it.tags, + ) + envActionModel.controlPlanSubThemes?.add( + envActionControlPlanSubThemeModel, + ) + } + return envActionModel + } } override fun equals(other: Any?): Boolean { @@ -155,10 +170,4 @@ data class EnvActionModel( } override fun hashCode(): Int = javaClass.hashCode() - - @Override - override fun toString(): String { - return this::class.simpleName + - "(id = $id , geom = $geom , actionStartDateTime = $actionStartDateTime, actionEndDateTime = $actionEndDateTime, actionType = $actionType , value = $value, facade = $facade, department = $department, isAdministrativeControl = $isAdministrativeControl, isComplianceWithWaterRegulationsControl = $isComplianceWithWaterRegulationsControl, isSeafarersControl = $isSeafarersControl, isSafetyEquipmentAndStandardsComplianceControl = $isSafetyEquipmentAndStandardsComplianceControl )" - } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt similarity index 55% rename from backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt rename to backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt index 78fb12a7e..f6d43d472 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt @@ -6,27 +6,28 @@ import jakarta.persistence.Column import jakarta.persistence.Embeddable import jakarta.persistence.EmbeddedId import jakarta.persistence.Entity +import jakarta.persistence.FetchType import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne import jakarta.persistence.MapsId import jakarta.persistence.Table +import org.hibernate.Hibernate import org.hibernate.annotations.Type import java.io.Serializable import java.util.UUID @Entity -@Table(name = "env_actions_subthemes") -data class EnvActionsSubThemeModel( - +@Table(name = "env_actions_control_plan_sub_themes") +class EnvActionsControlPlanSubThemeModel( @EmbeddedId val id: EnvActionsSubThemePk, - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @MapsId("envActionId") @JoinColumn(name = "env_action_id") val envAction: EnvActionModel? = null, - @ManyToOne + @ManyToOne(fetch = FetchType.EAGER) @MapsId("subthemeId") @JoinColumn(name = "subtheme_id") val controlPlanSubTheme: ControlPlanSubThemeModel? = null, @@ -35,27 +36,41 @@ data class EnvActionsSubThemeModel( @Type(ListArrayType::class) val tags: List? = null, ) { + companion object { + fun fromEnvActionControlPlanSubThemeEntity( + envAction: EnvActionModel, + controlPlanSubTheme: ControlPlanSubThemeModel, + tags: List? = null, + ) = EnvActionsControlPlanSubThemeModel( + id = EnvActionsSubThemePk( + envActionId = envAction.id!!, + subthemeId = controlPlanSubTheme.id!!, + ), + envAction = envAction, + controlPlanSubTheme = controlPlanSubTheme, + tags = tags, + ) + } + fun toEnvActionControlPlanSubThemeEntity(): EnvActionControlPlanSubThemeEntity { require(controlPlanSubTheme != null) { "controlPlanSubTheme must not be null when converting to Entity" } return EnvActionControlPlanSubThemeEntity( subThemeId = controlPlanSubTheme.id, - theme = controlPlanSubTheme.ControlPlanTheme.theme, + theme = controlPlanSubTheme.controlPlanTheme.theme, subTheme = controlPlanSubTheme.subTheme, tags = tags ?: emptyList(), ) } - companion object { - fun fromEnvActionControlPlanSubThemeEntity( - envActionId: UUID, - envActionControlPlanSubTheme: EnvActionControlPlanSubThemeEntity, - ) = EnvActionsSubThemeModel( - id = EnvActionsSubThemePk( - envActionId = envActionId, - subthemeId = envActionControlPlanSubTheme.subThemeId, - ), - tags = envActionControlPlanSubTheme.tags, - ) + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false + other as EnvActionsControlPlanSubThemeModel + + return id == other.id } + + override fun hashCode(): Int = javaClass.hashCode() } @Embeddable @@ -65,4 +80,16 @@ data class EnvActionsSubThemePk( @Column(name = "subtheme_id") val subthemeId: Int, -) : Serializable +) : Serializable { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is EnvActionsSubThemePk) return false + + return envActionId == other.envActionId && + subthemeId == other.subthemeId + } + + override fun hashCode(): Int { + return listOf(envActionId, subthemeId).hashCode() + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt index e4d3c252a..f1e77fb4c 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt @@ -33,39 +33,66 @@ import java.time.ZoneOffset.UTC ) @Entity @Table(name = "missions") -data class MissionModel( +class MissionModel( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(name = "id", unique = true, nullable = false) val id: Int? = null, + @Type( ListArrayType::class, parameters = [Parameter(name = SQL_ARRAY_TYPE, value = "text")], ) @Column(name = "mission_types", columnDefinition = "text[]") val missionTypes: List, - @Column(name = "open_by") val openBy: String? = null, - @Column(name = "closed_by") val closedBy: String? = null, - @Column(name = "observations_cacem") val observationsCacem: String? = null, - @Column(name = "observations_cnsp") val observationsCnsp: String? = null, - @Column(name = "facade") val facade: String? = null, + + @Column(name = "open_by") + val openBy: String? = null, + + @Column(name = "closed_by") + val closedBy: String? = null, + + @Column(name = "observations_cacem") + val observationsCacem: String? = null, + + @Column(name = "observations_cnsp") + val observationsCnsp: String? = null, + + @Column(name = "facade") + val facade: String? = null, + @JsonSerialize(using = GeometrySerializer::class) @JsonDeserialize(contentUsing = GeometryDeserializer::class) @Column(name = "geom") val geom: MultiPolygon? = null, - @Column(name = "start_datetime_utc") val startDateTimeUtc: Instant, - @Column(name = "end_datetime_utc") val endDateTimeUtc: Instant? = null, - @Column(name = "closed", nullable = false) val isClosed: Boolean, - @Column(name = "deleted", nullable = false) val isDeleted: Boolean, + + @Column(name = "start_datetime_utc") + val startDateTimeUtc: Instant, + + @Column(name = "end_datetime_utc") + val endDateTimeUtc: Instant? = null, + + @Column(name = "closed", nullable = false) + val isClosed: Boolean, + + @Column(name = "deleted", nullable = false) + val isDeleted: Boolean, + @Column(name = "mission_source", nullable = false, columnDefinition = "mission_source_type") @Enumerated(EnumType.STRING) @Type(PostgreSQLEnumType::class) val missionSource: MissionSourceEnum, - @Column(name = "has_mission_order", nullable = false) val hasMissionOrder: Boolean, + + @Column(name = "has_mission_order", nullable = false) + val hasMissionOrder: Boolean, + @Column(name = "is_geometry_computed_from_controls", nullable = false) val isGeometryComputedFromControls: Boolean, - @Column(name = "is_under_jdp", nullable = false) val isUnderJdp: Boolean, + + @Column(name = "is_under_jdp", nullable = false) + val isUnderJdp: Boolean, + @OneToMany( mappedBy = "mission", cascade = [CascadeType.ALL], @@ -75,6 +102,7 @@ data class MissionModel( @JsonManagedReference @Fetch(value = FetchMode.SUBSELECT) val envActions: MutableList? = ArrayList(), + @OneToMany( mappedBy = "mission", cascade = [CascadeType.ALL], @@ -84,6 +112,7 @@ data class MissionModel( @JsonManagedReference @Fetch(value = FetchMode.SUBSELECT) val controlResources: MutableList? = ArrayList(), + @OneToMany( mappedBy = "mission", cascade = [CascadeType.ALL], @@ -93,6 +122,7 @@ data class MissionModel( @JsonManagedReference @Fetch(value = FetchMode.SUBSELECT) val controlUnits: MutableList? = ArrayList(), + @OneToMany(mappedBy = "mission") @JsonManagedReference @Fetch(value = FetchMode.SUBSELECT) @@ -205,8 +235,9 @@ data class MissionModel( companion object { fun fromMissionEntity( mission: MissionEntity, - mapper: ObjectMapper, controlUnitResourceModelMap: Map, + controlPlanSubThemesReferenceModelMap: Map, + mapper: ObjectMapper, ): MissionModel { val missionModel = MissionModel( @@ -230,7 +261,12 @@ data class MissionModel( mission.envActions?.map { missionModel.envActions?.add( - EnvActionModel.fromEnvActionEntity(it, missionModel, mapper), + EnvActionModel.fromEnvActionEntity( + action = it, + mission = missionModel, + controlPlanSubThemesReferenceModelMap = controlPlanSubThemesReferenceModelMap, + mapper = mapper, + ), ) } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt index 8eb0d387d..3709ce0b6 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt @@ -6,6 +6,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionSourceEnum import fr.gouv.cacem.monitorenv.domain.repositories.IMissionRepository import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO import fr.gouv.cacem.monitorenv.infrastructure.database.model.MissionModel +import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanSubThemeRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlUnitResourceRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBMissionRepository import org.springframework.data.domain.Pageable @@ -16,6 +17,7 @@ import java.time.Instant @Repository class JpaMissionRepository( + private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, private val dbControlUnitResourceRepository: IDBControlUnitResourceRepository, private val dbMissionRepository: IDBMissionRepository, private val mapper: ObjectMapper, @@ -110,8 +112,21 @@ class JpaMissionRepository( // Create an `[id] → ControlUnitResourceModel` map val controlUnitResourceModelMap = controlUnitResourceModels.associateBy { requireNotNull(it.id) } - val missionModel = MissionModel.fromMissionEntity(mission, mapper, controlUnitResourceModelMap) + // get a list of all controlPlanSubThemes ids used in the mission + val controlPlanSubThemes = mission.envActions?.flatMap { it.controlPlanSubThemes?.map { id -> id.subThemeId } ?: emptyList() }?.distinct() + // Create a map from controlPlanSubThemes maping each id to a reference to the model + val controlPlanSubThemesReferenceModelMap = controlPlanSubThemes?.associateWith { id -> + dbControlPlanSubThemeRepository.getReferenceById( + id, + ) + } + val missionModel = MissionModel.fromMissionEntity( + mission = mission, + mapper = mapper, + controlUnitResourceModelMap = controlUnitResourceModelMap, + controlPlanSubThemesReferenceModelMap = controlPlanSubThemesReferenceModelMap ?: emptyMap(), + ) return dbMissionRepository.saveAndFlush(missionModel).toMissionDTO(mapper) } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt index bd6acea2f..21fad8c5e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt @@ -1,8 +1,8 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanSubThemeModel -import org.springframework.data.repository.CrudRepository +import org.springframework.data.jpa.repository.JpaRepository -interface IDBControlPlanSubThemeRepository : CrudRepository { +interface IDBControlPlanSubThemeRepository : JpaRepository { fun findByYearOrderById(year: Int): List } diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index 0e24f12a5..22bf84001 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -14,7 +14,7 @@ CREATE TABLE control_plan_subthemes ( ); CREATE INDEX idx_control_plan_subthemes_year ON control_plan_subthemes USING btree(year); -CREATE TABLE env_actions_subthemes ( +CREATE TABLE env_actions_control_plan_sub_themes ( env_action_id uuid, subtheme_id integer, tags text[], @@ -22,14 +22,14 @@ CREATE TABLE env_actions_subthemes ( foreign key (subtheme_id) references control_plan_subthemes(id), primary key (env_action_id, subtheme_id) ); --- TODO: Décider s'il faut ajouter une contrainte sur les tags de env_actions_subthemes +-- TODO: Décider s'il faut ajouter une contrainte sur les tags de env_actions_control_plan_sub_themes -- Si oui, il faudra probablement passer par un trigger -- (pas possible avec postgres de faire une contrainte "classique") COMMENT ON TABLE control_plan_themes IS 'Table des thèmes du plan de contrôle'; COMMENT ON TABLE control_plan_subthemes IS 'Table des sous-thèmes du plan de contrôle versionnés par année'; -COMMENT ON TABLE env_actions_subthemes IS 'Table de jointure entre les actions et les sous-thèmes du plan de contrôle'; +COMMENT ON TABLE env_actions_control_plan_sub_themes IS 'Table de jointure entre les actions et les sous-thèmes du plan de contrôle'; -- Insertion des themes et sous-themes à partir de la table control_themes INSERT INTO control_plan_themes (theme) @@ -49,8 +49,8 @@ UPDATE control_plan_subthemes t.id = control_plan_subthemes.theme_id AND t.theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; --- Insertion des données depuis les env actions dans la table env_actions_subthemes -INSERT INTO env_actions_subthemes (env_action_id, subtheme_id, tags) +-- Insertion des données depuis les env actions dans la table env_actions_control_plan_sub_themes +INSERT INTO env_actions_control_plan_sub_themes (env_action_id, subtheme_id, tags) WITH themes AS ( SELECT id as env_action_id, From e2a2ff2abc1d322f529d1f13f9654b39ad9e73a7 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 10/53] fix test data --- .../missions/ControlPlanSubThemeDataInput.kt | 4 +- ...s.sql => V666.01__insert_facade_areas.sql} | 0 ...cacem.sql => V666.02__dummy_amp_cacem.sql} | 0 ...66.03__insert_dummy_regulations_cacem.sql} | 0 ...666.04__insert_dummy_department_areas.sql} | 0 ...es.sql => V666.05__insert_dummy_bases.sql} | 0 ...V666.06__insert_dummy_administrations.sql} | 0 ...> V666.07__insert_dummy_control_units.sql} | 0 ....08__insert_dummy_control_plan_themes.sql} | 0 ...sql => V666.09__insert_dummy_missions.sql} | 0 .../V666.10__insert_dummy_env_actions.sql | 43 +++ .../V666.11__insert_dummy_reportings.sql | 362 ------------------ ...l => V666.11__insert_dummy_semaphores.sql} | 0 .../V666.12__insert_dummy_reportings.sql | 180 +++++++++ .../V666.6__insert_dummy_env_actions.sql | 28 -- 15 files changed, 225 insertions(+), 392 deletions(-) rename backend/src/main/resources/db/testdata/{V666.7__insert_facade_areas.sql => V666.01__insert_facade_areas.sql} (100%) rename backend/src/main/resources/db/testdata/{V666.8__dummy_amp_cacem.sql => V666.02__dummy_amp_cacem.sql} (100%) rename backend/src/main/resources/db/testdata/{V666.2__insert_dummy_regulations_cacem.sql => V666.03__insert_dummy_regulations_cacem.sql} (100%) rename backend/src/main/resources/db/testdata/{V666.10__insert_dummy_department_areas.sql => V666.04__insert_dummy_department_areas.sql} (100%) rename backend/src/main/resources/db/testdata/{V666.3__insert_dummy_bases.sql => V666.05__insert_dummy_bases.sql} (100%) rename backend/src/main/resources/db/testdata/{V666.1__insert_dummy_administrations.sql => V666.06__insert_dummy_administrations.sql} (100%) rename backend/src/main/resources/db/testdata/{V666.4__insert_dummy_control_units.sql => V666.07__insert_dummy_control_units.sql} (100%) rename backend/src/main/resources/db/testdata/{V666.12__insert_new_themes_pscem_pirc.sql => V666.08__insert_dummy_control_plan_themes.sql} (100%) rename backend/src/main/resources/db/testdata/{V666.5__insert_dummy_missions.sql => V666.09__insert_dummy_missions.sql} (100%) create mode 100644 backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql delete mode 100644 backend/src/main/resources/db/testdata/V666.11__insert_dummy_reportings.sql rename backend/src/main/resources/db/testdata/{V666.9__insert_dummy_semaphores.sql => V666.11__insert_dummy_semaphores.sql} (100%) create mode 100644 backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql delete mode 100644 backend/src/main/resources/db/testdata/V666.6__insert_dummy_env_actions.sql diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt index df563ffea..bb227d4c1 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt @@ -3,12 +3,12 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity data class ControlPlanSubThemeDataInput( - val id: Int, + val subThemeId: Int, val tags: List ? = null, ) { fun toEnvActionControlPlanSubThemeEntity(): EnvActionControlPlanSubThemeEntity { return EnvActionControlPlanSubThemeEntity( - subThemeId = this.id, + subThemeId = this.subThemeId, tags = this.tags, ) } diff --git a/backend/src/main/resources/db/testdata/V666.7__insert_facade_areas.sql b/backend/src/main/resources/db/testdata/V666.01__insert_facade_areas.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.7__insert_facade_areas.sql rename to backend/src/main/resources/db/testdata/V666.01__insert_facade_areas.sql diff --git a/backend/src/main/resources/db/testdata/V666.8__dummy_amp_cacem.sql b/backend/src/main/resources/db/testdata/V666.02__dummy_amp_cacem.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.8__dummy_amp_cacem.sql rename to backend/src/main/resources/db/testdata/V666.02__dummy_amp_cacem.sql diff --git a/backend/src/main/resources/db/testdata/V666.2__insert_dummy_regulations_cacem.sql b/backend/src/main/resources/db/testdata/V666.03__insert_dummy_regulations_cacem.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.2__insert_dummy_regulations_cacem.sql rename to backend/src/main/resources/db/testdata/V666.03__insert_dummy_regulations_cacem.sql diff --git a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_department_areas.sql b/backend/src/main/resources/db/testdata/V666.04__insert_dummy_department_areas.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.10__insert_dummy_department_areas.sql rename to backend/src/main/resources/db/testdata/V666.04__insert_dummy_department_areas.sql diff --git a/backend/src/main/resources/db/testdata/V666.3__insert_dummy_bases.sql b/backend/src/main/resources/db/testdata/V666.05__insert_dummy_bases.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.3__insert_dummy_bases.sql rename to backend/src/main/resources/db/testdata/V666.05__insert_dummy_bases.sql diff --git a/backend/src/main/resources/db/testdata/V666.1__insert_dummy_administrations.sql b/backend/src/main/resources/db/testdata/V666.06__insert_dummy_administrations.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.1__insert_dummy_administrations.sql rename to backend/src/main/resources/db/testdata/V666.06__insert_dummy_administrations.sql diff --git a/backend/src/main/resources/db/testdata/V666.4__insert_dummy_control_units.sql b/backend/src/main/resources/db/testdata/V666.07__insert_dummy_control_units.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.4__insert_dummy_control_units.sql rename to backend/src/main/resources/db/testdata/V666.07__insert_dummy_control_units.sql diff --git a/backend/src/main/resources/db/testdata/V666.12__insert_new_themes_pscem_pirc.sql b/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.12__insert_new_themes_pscem_pirc.sql rename to backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql diff --git a/backend/src/main/resources/db/testdata/V666.5__insert_dummy_missions.sql b/backend/src/main/resources/db/testdata/V666.09__insert_dummy_missions.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.5__insert_dummy_missions.sql rename to backend/src/main/resources/db/testdata/V666.09__insert_dummy_missions.sql diff --git a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql new file mode 100644 index 000000000..713ce207a --- /dev/null +++ b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql @@ -0,0 +1,43 @@ +-- +-- Data for Name: env_actions; Type: TABLE DATA; Schema: public; Owner: postgres +-- +DELETE FROM public.env_actions; + +INSERT INTO public.env_actions (id, mission_id, action_type, value, action_start_datetime_utc, geom, facade, department, action_end_datetime_utc, is_administrative_control, is_compliance_with_water_regulations_control, is_safety_equipment_and_standards_compliance_control, is_seafarers_control) VALUES +('e2257638-ddef-4611-960c-7675a3254c38', 38, 'SURVEILLANCE', '{"themes": [{"theme": "Police des activités de cultures marines", "subThemes": ["Contrôle du schéma des structures"], "protectedSpecies": []}], "observations": "", "coverMissionZone": true}', '2022-07-30 08:53:31.588693', NULL, NULL, '56', '2022-07-30 10:53:31.588693', NULL, NULL, NULL,NULL), +('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 38, 'CONTROL' , '{"themes": [{"theme": "Police des épaves", "subThemes": ["Épave/navire abandonné", "Contrôle administratif"], "protectedSpecies": []}], "infractions": [{"id": "6670e718-3ecd-46c1-8149-8b963c6f72dd", "natinf": ["10041"], "toProcess": false, "vesselSize": null, "vesselType": null, "companyName": "MASOCIETE", "formalNotice": "YES", "observations": "RAS", "relevantCourt": "LOCAL_COURT", "infractionType": "WITH_REPORT", "registrationNumber": null, "controlledPersonIdentity": null}], "vehicleType": null, "observations": null, "actionTargetType": "COMPANY", "actionNumberOfControls": 1}', '2022-07-29 11:53:31.588693', '0104000020E6100000010000000101000000399291D4BE1805C09E1A585CD6154840', NULL, NULL, NULL, NULL, NULL, NULL, NULL), +('475d2887-5344-46cd-903b-8cb5e42f9a9c', 49, 'SURVEILLANCE', '{"themes": [{"theme": "Police du conservatoire du littoral", "subThemes": ["Réglementation du conservatoire du littoral"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": false, "protectedSpecies": []}', NULL, '0106000020E61000000100000001030000000100000005000000D56979C3E95203C0BC117648B972474084387273B24D02C00C726AA38C6E4740BFFBD6B9762002C0349A2D10497347407A8D399212A102C0546E1659817A4740D56979C3E95203C0BC117648B9724740', NULL, NULL, NULL, NULL, NULL, NULL, NULL), +('16eeb9e8-f30c-430e-b36b-32b4673f81ce', 49, 'NOTE' , '{"observations": "Note libre"}', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), +('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 49, 'CONTROL' , '{"themes": [{"theme": "AMP sans réglementation particulière", "subThemes": ["Contrôle dans une AMP sans réglementation particulière"], "protectedSpecies": []}], "infractions": [{"id": "e56648c1-6ca3-4d5e-a5d2-114aa7c17126", "natinf": ["10231", "10228"], "toProcess": true, "vesselSize": null, "vesselType": null, "companyName": null, "formalNotice": "PENDING", "observations": "RAS", "relevantCourt": "PRE", "infractionType": "WAITING", "registrationNumber": null, "controlledPersonIdentity": "M DURAND"}], "vehicleType": null, "actionTargetType": "INDIVIDUAL", "actionNumberOfControls": 1}', NULL, '0104000020E61000000100000001010000003B0DADC6D4BB01C0A8387A2964714740', NULL, NULL, NULL, NULL, NULL, NULL, NULL), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 34, 'SURVEILLANCE', '{"themes": [{"theme": "Police des espèces protégées et de leurs habitats (faune et flore),", "subThemes": ["Destruction, capture, arrachage", "Atteinte aux habitats d''espèces protégées"], "protectedSpecies": ["FLORA", "BIRDS"]}, {"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": true, "protectedSpecies": []}', '2022-07-16 10:03:12.588693', NULL, NULL, NULL, '2022-07-16 12:03:12.588693', NULL, NULL, NULL, NULL), +('b8007c8a-5135-4bc3-816f-c69c7b75d807', 34, 'CONTROL' , '{"themes": [{"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "observations": "RAS", "infractions": [{"id": "5d5b7829-68cd-4436-8c0b-1cc8db7788a0", "natinf": ["10038","10231"], "toProcess": false, "vesselSize": "FROM_24_TO_46m", "vesselType": "COMMERCIAL", "companyName": null, "formalNotice": "PENDING", "observations": "Pas d''observations", "relevantCourt": "LOCAL_COURT", "infractionType": "WITH_REPORT", "registrationNumber": "BALTIK", "controlledPersonIdentity": "John Doe"}], "vehicleType": "VESSEL", "actionTargetType": "VEHICLE", "actionNumberOfControls": 1}', '2022-07-16 09:03:12.588693', '0104000020E610000001000000010100000047A07E6651E3DEBF044620AB65C54840', NULL, NULL, '2022-07-16 12:03:12.588693', NULL, NULL, NULL, NULL), +('4d9a3139-6c60-49a5-b443-0e6238a6a120', 41, 'CONTROL' , '{"themes": [{"theme": "Police des mouillages", "subThemes": ["Contrôle administratif"], "protectedSpecies": []}], "infractions": [], "vehicleType": null, "observations": "", "actionTargetType": null, "actionNumberOfControls": null}','2022-07-01 02:44:16.588693', NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE) +; + + +INSERT INTO public.env_actions VALUES +('2cdcd429-19ab-45ed-a892-7c695bd256e2', 53, 'SURVEILLANCE', '{"themes": [{"theme": "Pêche de loisir", "subThemes": ["Pêche embarquée"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": true, "protectedSpecies": []}', '2022-11-21 14:29:55.588693', NULL, NULL, NULL, '2022-11-22 12:14:48.588693'), +('3480657f-7845-4eb4-aa06-07b174b1da45', 53, 'CONTROL', '{"themes": [{"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "observations": "RAS", "infractions": [], "vehicleType": "VESSEL", "actionTargetType": "VEHICLE", "actionNumberOfControls": 0}', '2022-11-22 10:14:48.588693', '0104000020E610000001000000010100000047A07E6651E3DEBF044620AB65C54840', NULL, NULL, NULL), +('9969413b-b394-4db4-985f-b00743ffb833', 53, 'SURVEILLANCE', '{"themes": [{"theme": "Police des espèces protégées et de leurs habitats (faune et flore)", "subThemes": ["Destruction, capture, arrachage", "Atteinte aux habitats d''espèces protégées"], "protectedSpecies": ["FLORA", "BIRDS"]}, {"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": true, "protectedSpecies": []}', '2022-11-21 15:29:55.588693', NULL, NULL, NULL, '2022-11-22 13:14:48.588693') +; + +UPDATE public.env_actions SET + action_start_datetime_utc = action_start_datetime_utc + (now() - '2022-06-01 23:00:00'), + action_end_datetime_utc = action_end_datetime_utc + (now() - '2022-06-01 23:00:00') + WHERE mission_id > 20; + ; + +INSERT INTO public.env_actions_control_plan_sub_themes(env_action_id, subtheme_id, tags) VALUES +('e2257638-ddef-4611-960c-7675a3254c38', 51, NULL), +('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 83, NULL), +('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 43, NULL), +('475d2887-5344-46cd-903b-8cb5e42f9a9c', 79, NULL), +('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 48, NULL), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 52, '{"Flore, Oiseaux"}'), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 7, '{"Flore, Oiseaux"}'), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 64, NULL), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 82, NULL), +('b8007c8a-5135-4bc3-816f-c69c7b75d807', 64, NULL), +('b8007c8a-5135-4bc3-816f-c69c7b75d807', 82, NULL), +('4d9a3139-6c60-49a5-b443-0e6238a6a120', 42, NULL) +; diff --git a/backend/src/main/resources/db/testdata/V666.11__insert_dummy_reportings.sql b/backend/src/main/resources/db/testdata/V666.11__insert_dummy_reportings.sql deleted file mode 100644 index fe91ef936..000000000 --- a/backend/src/main/resources/db/testdata/V666.11__insert_dummy_reportings.sql +++ /dev/null @@ -1,362 +0,0 @@ -DELETE FROM reportings; - -INSERT INTO reportings ( - id, - reporting_id, - source_type , - semaphore_id , - control_unit_id , - source_name , - target_type , - vehicle_type, - target_details, - geom, - sea_front, - description, - report_type, - theme, - sub_themes, - action_taken, - is_control_required, - has_no_unit_available, - created_at, - validity_time, - is_deleted, - is_archived, - mission_id, - attached_to_mission_at_utc, - detached_from_mission_at_utc - ) -VALUES -( - 1, - 2300001, - 'SEMAPHORE', - 21, - null, - null, - 'VEHICLE', - 'VESSEL', - '[{"vesselName": "Vessel 1", "mmsi": "012314231343" }]', - ST_GeomFromText('MULTIPOINT((-4.938881879556736 48.4149566883917))', 4326), - 'NAMO', - 'Description 1', - 'INFRACTION_SUSPICION', - 'Rejets illicites', - '{"Jet de déchet","Carénage sauvage"}', - 'ACTION TAKEN', - true, - true, - now() - INTERVAL '3 days', - 24, - false, - false, - null, - null, - null - ), -( - 2, - 2300002, - 'SEMAPHORE', - 23, - null, - null, - 'VEHICLE', - 'VESSEL', - '[{"vesselName": "Vessel 2", "mmsi": "012314231344" }]', - ST_GeomFromText('MULTIPOINT((-4.779484119719514 48.619074487031526))', 4326), - 'NAMO', - 'Description 2', - 'INFRACTION_SUSPICION', - 'Police des mouillages', - '{"ZMEL"}', - 'ACTION TAKEN', - true, - true, - now() - INTERVAL '2 days', - 2, - false, - false, - null, - null, - null -), -( - 3, - 2300003, - 'CONTROL_UNIT', - null, - 10000, - null, - 'VEHICLE', - 'VESSEL', - '[{"vesselName": "Vessel 3", "mmsi": "012314231345" }]', - ST_GeomFromText('MULTIPOLYGON(((-3.504632038765229 48.938606793539606,-3.24829506967698 48.956239351532986,-3.484446288370139 48.996964545159244,-3.504632038765229 48.938606793539606)))', 4326), - 'NAMO', - 'Description 3', - 'INFRACTION_SUSPICION', - 'Police des mouillages', - '{"ZMEL"}', - 'ACTION TAKEN', - true, - true, - now() - INTERVAL '1 hour', - 1, - false, - false, - null, - null, - null -), -( - 4, - 2300004, - 'OTHER', - null, - null, - 'MA SUPER SOCIETE', - 'INDIVIDUAL', - NULL, - '[{"operatorName": "Mr le dirigeant" }]', - ST_GeomFromText('MULTIPOLYGON(((-2.81383107 49.49805557, -2.63290938 49.59886363, -2.80213877 49.69953506, -2.91683355 49.52263623, -2.81383107 49.49805557)))', 4326), - 'MED', - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ultrices risus ac arcu pellentesque, et tempor justo tempor. Pellentesque sem nisl, tempor id augue non, interdum sollicitudin felis.', - 'OBSERVATION', - 'Pêche à pied', - '{"Braconnage"}', - NULL, - true, - true, - now() - INTERVAL '3 hour', - 4, - false, - false, - null, - null, - null -), -( - 5, - 2300005, - 'SEMAPHORE', - 36, - NULL, - NULL, - 'COMPANY', - NULL, - '[{"operatorName": "Ma société", "vesselName": "Mr le gérant" }]', - ST_GeomFromText('MULTIPOINT((0.37083333 49.76777778))', 4326), - 'Guadeloupe', - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', - 'OBSERVATION', - NULL, - NULL, - NULL, - true, - true, - now() - INTERVAL '1 hour', - 6, - false, - false, - null, - null, - null -); - - --- Signalements rattachés à des missions -INSERT INTO reportings ( - id, - reporting_id, - source_type, - semaphore_id, - control_unit_id, - source_name, - target_type, - vehicle_type, - target_details, - geom, - sea_front, - description, - report_type, - theme, - sub_themes, - action_taken, - is_control_required, - has_no_unit_available, - created_at, - validity_time, - is_deleted, - mission_id, - attached_to_mission_at_utc, - detached_from_mission_at_utc, - attached_env_action_id, - open_by) -VALUES - (6, - 2300006, - 'SEMAPHORE', - 36, - NULL, - NULL, - 'COMPANY', - NULL, - '[{"operatorName": "La sociéter", "vesselName": "Héron" }]', - ST_GeomFromText('MULTIPOINT((-1.59695455 43.6569585))', 4326), - 'Guadeloupe', - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', - 'OBSERVATION', - 'Police des mouillages', - '{"ZMEL"}', - NULL, - true, - true, - now() - INTERVAL '75 minutes', - 6, - false, - 34, - now() - INTERVAL '15 minutes', - null, - 'b8007c8a-5135-4bc3-816f-c69c7b75d807', - 'ABC' - ), - (7, - 2300007, - 'CONTROL_UNIT', - null, - 10001, - NULL, - 'COMPANY', - NULL, - '[{"operatorName": "Good Company", "vesselName": "Mr le gérant" }]', - ST_GeomFromText('MULTIPOINT((-4.18759766312331 47.11281269827924))', 4326), - 'NAMO', - 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', - 'OBSERVATION', - NULL, - NULL, - NULL, - true, - true, - now() - INTERVAL '90 minutes', - 6, - false, - 34, - now() - INTERVAL '25 minutes', - null, - null, - 'DEF' - ), - (8, - 2300008, - 'CONTROL_UNIT', - null, - 10001, - NULL, - 'COMPANY', - NULL, - '[{"operatorName": "Good Company", "vesselName": "Mr le gérant" }]', - ST_GeomFromText('MULTIPOINT((-1.35943753 46.02911873))', 4326), - 'NAMO', - 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', - 'OBSERVATION', - NULL, - NULL, - NULL, - true, - true, - now() - INTERVAL '90 minutes', - 6, - false, - 38, - now() - INTERVAL '25 minutes', - null, - null, - 'GHI' - ), - (9, - 2300009, - 'CONTROL_UNIT', - null, - 10001, - NULL, - 'COMPANY', - NULL, - '[{"operatorName": "Good Company", "vesselName": "Mr le gérant" }]', - ST_GeomFromText('MULTIPOINT((-4.40757547 48.65546589))', 4326), - 'NAMO', - 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', - 'OBSERVATION', - NULL, - NULL, - NULL, - true, - true, - now() - INTERVAL '90 minutes', - 6, - false, - 53, - now() - INTERVAL '25 minutes', - NULL, - '9969413b-b394-4db4-985f-b00743ffb833', /* a surveillance */ - 'GHI' - ), - (10, - 2300010, - 'OTHER', - null, - null, - 'Vigipol', - 'COMPANY', - NULL, - '[{"operatorName": "Good Company", "vesselName": "Mr le gérant" }]', - ST_GeomFromText('MULTIPOINT((-3.91241571 48.67428686))', 4326), - 'NAMO', - 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', - 'OBSERVATION', - NULL, - NULL, - NULL, - true, - true, - now() - INTERVAL '90 minutes', - 6, - false, - 53, - now() - INTERVAL '25 minutes', - NULL, - '3480657f-7845-4eb4-aa06-07b174b1da45', /* a control */ - 'GHI' - ), - (11, - 2300011, - 'SEMAPHORE', - 36, - NULL, - NULL, - 'COMPANY', - NULL, - '[{"operatorName": "Good Company", "vesselName": "Mr le gérant" }]', - ST_GeomFromText('MULTIPOINT((-4.76689484 48.52102012))', 4326), - 'NAMO', - 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', - 'OBSERVATION', - NULL, - NULL, - NULL, - true, - true, - now() - INTERVAL '90 minutes', - 6, - false, - 53, - now() - INTERVAL '25 minutes', - NULL, - '9969413b-b394-4db4-985f-b00743ffb833', /* a surveillance */ - 'GHI' - ); - -SELECT setval('reportings_id_seq', (SELECT max(id) FROM reportings), true); -CREATE SEQUENCE IF NOT EXISTS reportings_2023_seq; -SELECT setval('reportings_2023_seq', (SELECT max(id) FROM reportings), true); diff --git a/backend/src/main/resources/db/testdata/V666.9__insert_dummy_semaphores.sql b/backend/src/main/resources/db/testdata/V666.11__insert_dummy_semaphores.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.9__insert_dummy_semaphores.sql rename to backend/src/main/resources/db/testdata/V666.11__insert_dummy_semaphores.sql diff --git a/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql b/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql new file mode 100644 index 000000000..447c8792c --- /dev/null +++ b/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql @@ -0,0 +1,180 @@ +DELETE FROM reportings; + +INSERT INTO reportings ( + id, + reporting_id, + source_type , + semaphore_id , + control_unit_id , + source_name , + target_type , + vehicle_type, + target_details, + geom, + sea_front, + description, + report_type, + theme, + sub_themes, + action_taken, + is_control_required, + has_no_unit_available, + created_at, + validity_time, + is_deleted, + is_archived, + mission_id, + attached_to_mission_at_utc, + detached_from_mission_at_utc + ) +VALUES +( + 1, + 2300001, + 'SEMAPHORE', + 21, + null, + null, + 'VEHICLE', + 'VESSEL', + '[{"vesselName": "Vessel 1", "mmsi": "012314231343" }]', + ST_GeomFromText('MULTIPOINT((-4.938881879556736 48.4149566883917))', 4326), + 'NAMO', + 'Description 1', + 'INFRACTION_SUSPICION', + 'Rejets illicites', + '{"Jet de déchet","Carénage sauvage"}', + 'ACTION TAKEN', + true, + true, + now() - INTERVAL '3 days', + 24, + false, + false, + null, + null, + null + ), +( + 2, + 2300002, + 'SEMAPHORE', + 23, + null, + null, + 'VEHICLE', + 'VESSEL', + '[{"vesselName": "Vessel 2", "mmsi": "012314231344" }]', + ST_GeomFromText('MULTIPOINT((-4.779484119719514 48.619074487031526))', 4326), + 'NAMO', + 'Description 2', + 'INFRACTION_SUSPICION', + 'Police des mouillages', + '{"ZMEL"}', + 'ACTION TAKEN', + true, + true, + now() - INTERVAL '2 days', + 2, + false, + false, + null, + null, + null +), +( + 3, + 2300003, + 'CONTROL_UNIT', + null, + 10000, + null, + 'VEHICLE', + 'VESSEL', + '[{"vesselName": "Vessel 3", "mmsi": "012314231345" }]', + ST_GeomFromText('MULTIPOLYGON(((-3.504632038765229 48.938606793539606,-3.24829506967698 48.956239351532986,-3.484446288370139 48.996964545159244,-3.504632038765229 48.938606793539606)))', 4326), + 'NAMO', + 'Description 3', + 'INFRACTION_SUSPICION', + 'Police des mouillages', + '{"ZMEL"}', + 'ACTION TAKEN', + true, + true, + now() - INTERVAL '1 hour', + 1, + false, + false, + null, + null, + null +), +( + 4, + 2300004, + 'OTHER', + null, + null, + 'MA SUPER SOCIETE', + 'INDIVIDUAL', + NULL, + '[{"operatorName": "Mr le dirigeant" }]', + ST_GeomFromText('MULTIPOLYGON(((-2.81383107 49.49805557, -2.63290938 49.59886363, -2.80213877 49.69953506, -2.91683355 49.52263623, -2.81383107 49.49805557)))', 4326), + 'MED', + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ultrices risus ac arcu pellentesque, et tempor justo tempor. Pellentesque sem nisl, tempor id augue non, interdum sollicitudin felis.', + 'OBSERVATION', + 'Pêche à pied', + '{"Braconnage"}', + NULL, + true, + true, + now() - INTERVAL '3 hour', + 4, + false, + false, + null, + null, + null +), +( + 5, + 2300005, + 'SEMAPHORE', + 36, + NULL, + NULL, + 'COMPANY', + NULL, + '[{"operatorName": "Ma société", "vesselName": "Mr le gérant" }]', + ST_GeomFromText('MULTIPOINT((0.37083333 49.76777778))', 4326), + 'Guadeloupe', + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'OBSERVATION', + NULL, + NULL, + NULL, + true, + true, + now() - INTERVAL '1 hour', + 6, + false, + false, + null, + null, + null +); + +/* reporting linked to a surveillance */ + + +INSERT INTO reportings (id, reporting_id, source_type, semaphore_id, control_unit_id, source_name, target_type, vehicle_type, target_details, geom, sea_front, description, report_type, theme, sub_themes, action_taken, is_control_required, has_no_unit_available, created_at, validity_time, is_deleted, mission_id, attached_to_mission_at_utc, detached_from_mission_at_utc, attached_env_action_id, open_by) VALUES +(9, 2300009, 'CONTROL_UNIT', null, 10001, NULL, 'COMPANY', NULL, '[{"operatorName": "Good Company", "vesselName": "Mr le gérant" }]', ST_GeomFromText('MULTIPOINT((-4.40757547 48.65546589))', 4326), 'NAMO', 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, now() - INTERVAL '90 minutes', 6, false, 53, now() - INTERVAL '25 minutes', NULL, '9969413b-b394-4db4-985f-b00743ffb833', 'GHI'), + /* reporting linked to a control */ +(10, 2300010, 'OTHER', null, null, 'Vigipol', 'COMPANY', NULL, '[{"operatorName": "Good Company", "vesselName": "Mr le gérant" }]', ST_GeomFromText('MULTIPOINT((-3.91241571 48.67428686))', 4326), 'NAMO', 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, now() - INTERVAL '90 minutes', 6, false, 53, now() - INTERVAL '25 minutes', NULL, '3480657f-7845-4eb4-aa06-07b174b1da45', 'GHI'), +/* reporting linked to a surveillance */ +(11, 2300011, 'SEMAPHORE', 36, NULL, NULL, 'COMPANY', NULL, '[{"operatorName": "Good Company", "vesselName": "Mr le gérant" }]', ST_GeomFromText('MULTIPOINT((-4.76689484 48.52102012))', 4326), 'NAMO', 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, now() - INTERVAL '90 minutes', 6, false, 53, now() - INTERVAL '25 minutes', NULL, '9969413b-b394-4db4-985f-b00743ffb833', 'GHI') +; + +SELECT setval('reportings_id_seq', (SELECT max(id) FROM reportings), true); +CREATE SEQUENCE IF NOT EXISTS reportings_2023_seq; +SELECT setval('reportings_2023_seq', (SELECT max(id) FROM reportings), true); diff --git a/backend/src/main/resources/db/testdata/V666.6__insert_dummy_env_actions.sql b/backend/src/main/resources/db/testdata/V666.6__insert_dummy_env_actions.sql deleted file mode 100644 index 32573d34c..000000000 --- a/backend/src/main/resources/db/testdata/V666.6__insert_dummy_env_actions.sql +++ /dev/null @@ -1,28 +0,0 @@ --- --- Data for Name: env_actions; Type: TABLE DATA; Schema: public; Owner: postgres --- -DELETE FROM public.env_actions; - -INSERT INTO public.env_actions VALUES ('e2257638-ddef-4611-960c-7675a3254c38', 38, 'SURVEILLANCE', '{"themes": [{"theme": "Police des activités de cultures marines", "subThemes": ["Contrôle du schéma des structures"], "protectedSpecies": []}], "observations": "", "coverMissionZone": true}', '2022-07-30 08:53:31.588693', NULL, NULL, '56', '2022-07-30 10:53:31.588693'); -INSERT INTO public.env_actions VALUES ('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 38, 'CONTROL', '{"themes": [{"theme": "Police des épaves", "subThemes": ["Épave/navire abandonné", "Contrôle administratif"], "protectedSpecies": []}], "infractions": [{"id": "6670e718-3ecd-46c1-8149-8b963c6f72dd", "natinf": ["10041"], "toProcess": false, "vesselSize": null, "vesselType": null, "companyName": "MASOCIETE", "formalNotice": "YES", "observations": "RAS", "relevantCourt": "LOCAL_COURT", "infractionType": "WITH_REPORT", "registrationNumber": null, "controlledPersonIdentity": null}], "vehicleType": null, "observations": null, "actionTargetType": "COMPANY", "actionNumberOfControls": 1}', '2022-07-29 11:53:31.588693', '0104000020E6100000010000000101000000399291D4BE1805C09E1A585CD6154840', NULL, NULL, NULL); - -INSERT INTO public.env_actions VALUES ('475d2887-5344-46cd-903b-8cb5e42f9a9c', 49, 'SURVEILLANCE', '{"themes": [{"theme": "Police du conservatoire du littoral", "subThemes": ["Réglementation du conservatoire du littoral"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": false, "protectedSpecies": []}', NULL, '0106000020E61000000100000001030000000100000005000000D56979C3E95203C0BC117648B972474084387273B24D02C00C726AA38C6E4740BFFBD6B9762002C0349A2D10497347407A8D399212A102C0546E1659817A4740D56979C3E95203C0BC117648B9724740'); -INSERT INTO public.env_actions VALUES ('16eeb9e8-f30c-430e-b36b-32b4673f81ce', 49, 'NOTE', '{"observations": "Note libre"}', NULL, NULL); -INSERT INTO public.env_actions VALUES ('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 49, 'CONTROL', '{"themes": [{"theme": "AMP sans réglementation particulière", "subThemes": ["Contrôle dans une AMP sans réglementation particulière"], "protectedSpecies": []}], "infractions": [{"id": "e56648c1-6ca3-4d5e-a5d2-114aa7c17126", "natinf": ["10231", "10228"], "toProcess": true, "vesselSize": null, "vesselType": null, "companyName": null, "formalNotice": "PENDING", "observations": "RAS", "relevantCourt": "PRE", "infractionType": "WAITING", "registrationNumber": null, "controlledPersonIdentity": "M DURAND"}], "vehicleType": null, "actionTargetType": "INDIVIDUAL", "actionNumberOfControls": 1}', NULL, '0104000020E61000000100000001010000003B0DADC6D4BB01C0A8387A2964714740'); - -INSERT INTO public.env_actions VALUES ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 34, 'SURVEILLANCE', '{"themes": [{"theme": "Police des espèces protégées et de leurs habitats (faune et flore)", "subThemes": ["Destruction, capture, arrachage", "Atteinte aux habitats d''espèces protégées"], "protectedSpecies": ["FLORA", "BIRDS"]}, {"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": true, "protectedSpecies": []}', '2022-07-16 10:03:12.588693', NULL, NULL, NULL, '2022-07-16 12:03:12.588693'); -INSERT INTO public.env_actions VALUES ('b8007c8a-5135-4bc3-816f-c69c7b75d807', 34, 'CONTROL', '{"themes": [{"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "observations": "RAS", "infractions": [{"id": "5d5b7829-68cd-4436-8c0b-1cc8db7788a0", "natinf": ["10038","10231"], "toProcess": false, "vesselSize": "FROM_24_TO_46m", "vesselType": "COMMERCIAL", "companyName": null, "formalNotice": "PENDING", "observations": "Pas d''observations", "relevantCourt": "LOCAL_COURT", "infractionType": "WITH_REPORT", "registrationNumber": "BALTIK", "controlledPersonIdentity": "John Doe"}], "vehicleType": "VESSEL", "actionTargetType": "VEHICLE", "actionNumberOfControls": 1}', '2022-07-16 09:03:12.588693', '0104000020E610000001000000010100000047A07E6651E3DEBF044620AB65C54840', NULL, NULL, '2022-07-16 12:03:12.588693'); - -INSERT INTO public.env_actions VALUES ('4d9a3139-6c60-49a5-b443-0e6238a6a120', 41, 'CONTROL', '{"themes": [{"theme": "Police des mouillages", "subThemes": ["Contrôle administratif"], "protectedSpecies": []}], "infractions": [], "vehicleType": null, "observations": "", "actionTargetType": null, "actionNumberOfControls": null}','2022-07-01 02:44:16.588693', NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE); - - -INSERT INTO public.env_actions VALUES ('2cdcd429-19ab-45ed-a892-7c695bd256e2', 53, 'SURVEILLANCE', '{"themes": [{"theme": "Pêche de loisir", "subThemes": ["Pêche embarquée"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": true, "protectedSpecies": []}', '2022-11-21 14:29:55.588693', NULL, NULL, NULL, '2022-11-22 12:14:48.588693'); -INSERT INTO public.env_actions VALUES ('3480657f-7845-4eb4-aa06-07b174b1da45', 53, 'CONTROL', '{"themes": [{"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "observations": "RAS", "infractions": [], "vehicleType": "VESSEL", "actionTargetType": "VEHICLE", "actionNumberOfControls": 0}', '2022-11-22 10:14:48.588693', '0104000020E610000001000000010100000047A07E6651E3DEBF044620AB65C54840', NULL, NULL, NULL); -INSERT INTO public.env_actions VALUES ('9969413b-b394-4db4-985f-b00743ffb833', 53, 'SURVEILLANCE', '{"themes": [{"theme": "Police des espèces protégées et de leurs habitats (faune et flore)", "subThemes": ["Destruction, capture, arrachage", "Atteinte aux habitats d''espèces protégées"], "protectedSpecies": ["FLORA", "BIRDS"]}, {"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": true, "protectedSpecies": []}', '2022-11-21 15:29:55.588693', NULL, NULL, NULL, '2022-11-22 13:14:48.588693'); - - -UPDATE public.env_actions SET - action_start_datetime_utc = action_start_datetime_utc + (now() - '2022-06-01 23:00:00'), - action_end_datetime_utc = action_end_datetime_utc + (now() - '2022-06-01 23:00:00') - WHERE mission_id > 20; - ; \ No newline at end of file From 984a422ff00d4812ab21e219bb0a93bcc86398c8 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 11/53] fix test --- .../database/model/EnvActionModel.kt | 3 +- .../EnvActionsControlPlanSubThemeModel.kt | 2 +- .../database/model/MissionModel.kt | 133 +- .../JpaMissionRepositoryITests.kt | 1073 ++++++++--------- 4 files changed, 602 insertions(+), 609 deletions(-) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt index 61dcefdb0..229d067f1 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt @@ -94,12 +94,13 @@ class EnvActionModel( @JsonManagedReference val attachedReporting: List? = listOf(), + // @JoinColumn(name = "env_action_id") @OneToMany( fetch = FetchType.EAGER, cascade = [CascadeType.ALL], orphanRemoval = true, + mappedBy = "envAction", ) - @JoinColumn(name = "env_action_id") val controlPlanSubThemes: MutableList? = ArrayList(), ) { diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt index f6d43d472..32ae01d3f 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt @@ -27,7 +27,7 @@ class EnvActionsControlPlanSubThemeModel( @JoinColumn(name = "env_action_id") val envAction: EnvActionModel? = null, - @ManyToOne(fetch = FetchType.EAGER) + @ManyToOne(fetch = FetchType.LAZY) @MapsId("subthemeId") @JoinColumn(name = "subtheme_id") val controlPlanSubTheme: ControlPlanSubThemeModel? = null, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt index f1e77fb4c..4cccd42b3 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt @@ -40,24 +40,46 @@ class MissionModel( @Column(name = "id", unique = true, nullable = false) val id: Int? = null, - @Type( - ListArrayType::class, - parameters = [Parameter(name = SQL_ARRAY_TYPE, value = "text")], + @OneToMany(mappedBy = "mission") + @JsonManagedReference + @Fetch(value = FetchMode.SUBSELECT) + val attachedReportings: List? = listOf(), + + @OneToMany( + mappedBy = "mission", + cascade = [CascadeType.ALL], + orphanRemoval = true, + fetch = FetchType.EAGER, ) - @Column(name = "mission_types", columnDefinition = "text[]") - val missionTypes: List, + @JsonManagedReference + @Fetch(value = FetchMode.SUBSELECT) + val controlResources: MutableList? = ArrayList(), - @Column(name = "open_by") - val openBy: String? = null, + @OneToMany( + mappedBy = "mission", + cascade = [CascadeType.ALL], + orphanRemoval = true, + fetch = FetchType.EAGER, + ) + @JsonManagedReference + @Fetch(value = FetchMode.SUBSELECT) + val controlUnits: MutableList? = ArrayList(), @Column(name = "closed_by") val closedBy: String? = null, - @Column(name = "observations_cacem") - val observationsCacem: String? = null, + @OneToMany( + mappedBy = "mission", + cascade = [CascadeType.ALL], + orphanRemoval = true, + fetch = FetchType.EAGER, + ) + @JsonManagedReference + @Fetch(value = FetchMode.SUBSELECT) + val envActions: MutableList? = ArrayList(), - @Column(name = "observations_cnsp") - val observationsCnsp: String? = null, + @Column(name = "end_datetime_utc") + val endDateTimeUtc: Instant? = null, @Column(name = "facade") val facade: String? = null, @@ -67,11 +89,8 @@ class MissionModel( @Column(name = "geom") val geom: MultiPolygon? = null, - @Column(name = "start_datetime_utc") - val startDateTimeUtc: Instant, - - @Column(name = "end_datetime_utc") - val endDateTimeUtc: Instant? = null, + @Column(name = "has_mission_order", nullable = false) + val hasMissionOrder: Boolean, @Column(name = "closed", nullable = false) val isClosed: Boolean, @@ -79,54 +98,36 @@ class MissionModel( @Column(name = "deleted", nullable = false) val isDeleted: Boolean, - @Column(name = "mission_source", nullable = false, columnDefinition = "mission_source_type") - @Enumerated(EnumType.STRING) - @Type(PostgreSQLEnumType::class) - val missionSource: MissionSourceEnum, - - @Column(name = "has_mission_order", nullable = false) - val hasMissionOrder: Boolean, - @Column(name = "is_geometry_computed_from_controls", nullable = false) val isGeometryComputedFromControls: Boolean, @Column(name = "is_under_jdp", nullable = false) val isUnderJdp: Boolean, - @OneToMany( - mappedBy = "mission", - cascade = [CascadeType.ALL], - orphanRemoval = true, - fetch = FetchType.EAGER, - ) - @JsonManagedReference - @Fetch(value = FetchMode.SUBSELECT) - val envActions: MutableList? = ArrayList(), + @Column(name = "mission_source", nullable = false, columnDefinition = "mission_source_type") + @Enumerated(EnumType.STRING) + @Type(PostgreSQLEnumType::class) + val missionSource: MissionSourceEnum, - @OneToMany( - mappedBy = "mission", - cascade = [CascadeType.ALL], - orphanRemoval = true, - fetch = FetchType.EAGER, + @Type( + ListArrayType::class, + parameters = [Parameter(name = SQL_ARRAY_TYPE, value = "text")], ) - @JsonManagedReference - @Fetch(value = FetchMode.SUBSELECT) - val controlResources: MutableList? = ArrayList(), + @Column(name = "mission_types", columnDefinition = "text[]") + val missionTypes: List, - @OneToMany( - mappedBy = "mission", - cascade = [CascadeType.ALL], - orphanRemoval = true, - fetch = FetchType.EAGER, - ) - @JsonManagedReference - @Fetch(value = FetchMode.SUBSELECT) - val controlUnits: MutableList? = ArrayList(), + @Column(name = "observations_cacem") + val observationsCacem: String? = null, + + @Column(name = "observations_cnsp") + val observationsCnsp: String? = null, + + @Column(name = "open_by") + val openBy: String? = null, + + @Column(name = "start_datetime_utc") + val startDateTimeUtc: Instant, - @OneToMany(mappedBy = "mission") - @JsonManagedReference - @Fetch(value = FetchMode.SUBSELECT) - val attachedReportings: List? = listOf(), ) { fun toMissionEntity(objectMapper: ObjectMapper): MissionEntity { val controlUnits = @@ -242,21 +243,21 @@ class MissionModel( val missionModel = MissionModel( id = mission.id, - missionTypes = mission.missionTypes, - openBy = mission.openBy, closedBy = mission.closedBy, - observationsCacem = mission.observationsCacem, - observationsCnsp = mission.observationsCnsp, + endDateTimeUtc = mission.endDateTimeUtc?.toInstant(), facade = mission.facade, geom = mission.geom, - startDateTimeUtc = mission.startDateTimeUtc.toInstant(), - endDateTimeUtc = mission.endDateTimeUtc?.toInstant(), + hasMissionOrder = mission.hasMissionOrder, isClosed = mission.isClosed, isDeleted = false, - missionSource = mission.missionSource, - hasMissionOrder = mission.hasMissionOrder, - isUnderJdp = mission.isUnderJdp, isGeometryComputedFromControls = mission.isGeometryComputedFromControls, + isUnderJdp = mission.isUnderJdp, + missionSource = mission.missionSource, + missionTypes = mission.missionTypes, + observationsCacem = mission.observationsCacem, + observationsCnsp = mission.observationsCnsp, + openBy = mission.openBy, + startDateTimeUtc = mission.startDateTimeUtc.toInstant(), ) mission.envActions?.map { @@ -311,10 +312,4 @@ class MissionModel( } override fun hashCode(): Int = javaClass.hashCode() - - @Override - override fun toString(): String { - return this::class.simpleName + - "(id = $id , missionTypes = $missionTypes , openBy = $openBy , closedBy = $closedBy , observationsCacem = $observationsCacem, observationsCnsp = $observationsCnsp , facade = $facade , geom = $geom , startDateTimeUtc = $startDateTimeUtc , endDateTimeUtc = $endDateTimeUtc, isClosed = $isClosed, isDeleted = $isDeleted, missionSource = $missionSource )" - } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt index 14e2f591d..d6ff20e55 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt @@ -9,7 +9,6 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionNoteEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionSurveillanceEntity -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.ActionTargetTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.* @@ -32,8 +31,6 @@ import java.util.* class JpaMissionRepositoryITests : AbstractDBTests() { @Autowired private lateinit var jpaMissionRepository: JpaMissionRepository - @Autowired private lateinit var jpaReportingRepository: JpaReportingRepository - @Autowired private lateinit var jpaControlUnitRepository: JpaControlUnitRepository @Autowired @@ -41,25 +38,56 @@ class JpaMissionRepositoryITests : AbstractDBTests() { @Test @Transactional - fun `findByControlUnitId should find the matching missions`() { - val foundMissions = jpaMissionRepository.findByControlUnitId(10002) + fun `delete Should set the deleted flag as true`() { + // Given + val missionsList = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) + assertThat(missionsList).hasSize(21) - assertThat(foundMissions).hasSize(17) + // When + jpaMissionRepository.delete(3) + + // Then + val nextMissionList = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) + assertThat(nextMissionList).hasSize(20) } @Test @Transactional - fun `findByControlUnitResourceId should find the matching missions`() { - val foundMissions = jpaMissionRepository.findByControlUnitResourceId(8) - - assertThat(foundMissions).hasSize(4) + fun `findAll Should return all missions when only required startedAfter is set to a very old date`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(54) } @Test @Transactional - fun `save should create a new mission`() { - // Given - val existingMissions = + fun `findAll Should return filtered missions when startedAfter & startedBefore are set`() { + // When + val missions = jpaMissionRepository.findAllFullMissions( startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), @@ -68,421 +96,156 @@ class JpaMissionRepositoryITests : AbstractDBTests() { seaFronts = null, pageable = Pageable.unpaged(), ) + assertThat(missions).hasSize(21) + } - assertThat(existingMissions).hasSize(21) - - val wktReader = WKTReader() - - val multipolygonString = - "MULTIPOLYGON(((-2.7335 47.6078, -2.7335 47.8452, -3.6297 47.8452, -3.6297 47.6078, -2.7335 47.6078)))" - val polygon = wktReader.read(multipolygonString) as MultiPolygon - - val multipointString = "MULTIPOINT((49.354105 -0.427455))" - val point = wktReader.read(multipointString) as MultiPoint - - val noteObservations = "Quelqu'un aurait vu quelque chose quelque part à un certain moment." - - val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - envActions = - listOf( - EnvActionControlEntity( - id = - UUID.fromString( - "33310163-4e22-4d3d-b585-dac4431eb4b5", - ), - facade = "Facade 1", - controlPlanSubThemes = listOf( - EnvActionControlPlanSubThemeEntity( - subThemeId = 1, - subTheme = "Sub theme 1", - theme = "Theme 1", - tags = listOf("Tag 1", "Tag 2"), - ), - ), - department = "Department 1", - geom = point, - vehicleType = VehicleTypeEnum.VEHICLE_LAND, - isAdministrativeControl = true, - isComplianceWithWaterRegulationsControl = true, - isSafetyEquipmentAndStandardsComplianceControl = - true, - isSeafarersControl = true, - ), - EnvActionSurveillanceEntity( - id = - UUID.fromString( - "a6c4bd17-eb45-4504-ab15-7a18ea714a10", - ), - facade = "Facade 2", - department = "Department 2", - geom = polygon, - ), - EnvActionNoteEntity( - id = - UUID.fromString( - "126ded89-2dc0-4c77-9bf2-49f86b9a71a1", - ), - observations = noteObservations, - ), - ), - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10121, - name = "PAM Jeanne Barret", - administration = "DIRM / DM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 8, - controlUnitId = 10121, - name = "PAM Jeanne Barret", - ), - ), - ), - ), - isGeometryComputedFromControls = false, + @Test + @Transactional + fun `findAll Should return filtered missions when missionTypes is set`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = listOf("SEA"), + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), ) + assertThat(missions).hasSize(22) + } + @Test + @Transactional + fun `findAll Should return filtered missions when multiple missionTypes are set`() { // When - val newMissionCreated = jpaMissionRepository.save(newMission) - - // Then - assertThat(newMissionCreated.mission.controlUnits).hasSize(1) - assertThat(newMissionCreated.mission.controlUnits.first().id).isEqualTo(10121) - assertThat(newMissionCreated.mission.controlUnits.first().name) - .isEqualTo("PAM Jeanne Barret") - assertThat(newMissionCreated.mission.controlUnits.first().administration) - .isEqualTo("DIRM / DM") - assertThat(newMissionCreated.mission.controlUnits.first().resources).hasSize(1) - assertThat(newMissionCreated.mission.controlUnits.first().resources.first().id).isEqualTo(8) - assertThat(newMissionCreated.mission.controlUnits.first().resources.first().controlUnitId) - .isEqualTo(10121) - assertThat(newMissionCreated.mission.controlUnits.first().resources.first().name) - .isEqualTo("PAM Jeanne Barret") - assertThat(newMissionCreated.mission.envActions).hasSize(3) - assertThat(newMissionCreated.mission.envActions?.first()?.facade).isEqualTo("Facade 1") - assertThat(newMissionCreated.mission.envActions?.first()?.department) - .isEqualTo("Department 1") - assertThat(newMissionCreated.mission.envActions?.get(1)?.facade).isEqualTo("Facade 2") - assertThat(newMissionCreated.mission.envActions?.get(1)?.department) - .isEqualTo("Department 2") - assertThat( - (newMissionCreated.mission.envActions?.get(2) as EnvActionNoteEntity) - .observations, - ) - .isEqualTo( - noteObservations, + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = listOf("SEA", "LAND"), + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), ) + assertThat(missions).hasSize(45) + } + @Test + @Transactional + fun `findAll Should return filtered missions when seaFront is set to MEMN`() { + // When val missions = jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, missionTypes = null, missionStatuses = null, - seaFronts = null, + seaFronts = listOf("MEMN"), pageable = Pageable.unpaged(), ) - - assertThat(missions).hasSize(22) + assertThat(missions).hasSize(9) } @Test @Transactional - fun `save should update mission resources`() { - // Given - val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10004, - name = "DPM – DDTM 35", - administration = "DDTM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 8, - controlUnitId = 10004, - name = "PAM Jeanne Barret", - ), - ), - ), - ), - isGeometryComputedFromControls = false, + fun `findAll Should return filtered missions when seaFront is set to MEMN and NAMO`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = listOf("MEMN", "NAMO"), + pageable = Pageable.unpaged(), ) - jpaMissionRepository.save(newMission) + assertThat(missions).hasSize(27) + } - // When - val newMissionUpdated = - jpaMissionRepository.save( - newMission.copy( - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10002, - name = "DML 2A", - administration = "DIRM / DM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 3, - controlUnitId = - 10002, - name = - "Semi-rigide 1", - ), - LegacyControlUnitResourceEntity( - id = 5, - controlUnitId = - 10002, - name = "Voiture", - ), - ), - ), - ), - ), - ) - - // Then - assertThat(newMissionUpdated.mission.controlUnits).hasSize(1) - assertThat(newMissionUpdated.mission.controlUnits.first().id).isEqualTo(10002) - assertThat(newMissionUpdated.mission.controlUnits.first().name).isEqualTo("DML 2A") - assertThat(newMissionUpdated.mission.controlUnits.first().administration) - .isEqualTo("DIRM / DM") - assertThat(newMissionUpdated.mission.controlUnits.first().resources).hasSize(2) - assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().id).isEqualTo(3) - assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().controlUnitId) - .isEqualTo(10002) - assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().name) - .isEqualTo("Semi-rigide 1") - assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().id).isEqualTo(5) - assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().controlUnitId) - .isEqualTo(10002) - assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().name) - .isEqualTo("Voiture") - } - - @Test - @Transactional - fun `save should update existing mission with existing resources`() { - // Given - val mission = jpaMissionRepository.findById(25) - val newControlUnitResource = jpaControlUnitResourceRepository.findById(10) - val newControlUnit = - jpaControlUnitRepository.findById( - requireNotNull(newControlUnitResource.controlUnit.id), - ) - - val nextMission = - mission.copy( - controlUnits = - mission.controlUnits.plus( - LegacyControlUnitEntity( - id = requireNotNull(newControlUnit.controlUnit.id), - administration = newControlUnit.administration.name, - isArchived = newControlUnit.controlUnit.isArchived, - name = newControlUnit.controlUnit.name, - resources = - listOf( - newControlUnitResource - .toLegacyControlUnitResource(), - ), - contact = null, - ), - ), - ) - - val updatedMission = jpaMissionRepository.save(nextMission) - - assertThat(updatedMission.mission.controlUnits).hasSize(2) - assertThat(updatedMission.mission.controlUnits.first().id).isEqualTo(10002) - assertThat(updatedMission.mission.controlUnits.first().resources).hasSize(1) - assertThat(updatedMission.mission.controlUnits.first().resources.first().id).isEqualTo(3) - assertThat(updatedMission.mission.controlUnits.first().resources.first().controlUnitId) - .isEqualTo(10002) - assertThat(updatedMission.mission.controlUnits.last().id).isEqualTo(10018) - assertThat(updatedMission.mission.controlUnits.last().resources).hasSize(1) - assertThat(updatedMission.mission.controlUnits.last().resources.first().id).isEqualTo(10) - assertThat(updatedMission.mission.controlUnits.last().resources.first().controlUnitId) - .isEqualTo(10018) - } - - @Test - @Transactional - fun `save should throw an exception When the resource id is not found`() { - // Given - val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 5, - name = "DPM – DDTM 35", - administration = "DDTM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 123456, - controlUnitId = 5, - name = "PAM Jeanne Barret", - ), - ), - ), - ), - isGeometryComputedFromControls = false, - ) - - // When - val throwable = catchThrowable { jpaMissionRepository.save(newMission) } - - // Then - assertThat(throwable).isInstanceOf(InvalidDataAccessApiUsageException::class.java) - } - - @Test - @Transactional - fun `save should throw an exception When the unit id is not found`() { - // Given - val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 123456, - name = "PAM Jeanne Barret", - administration = "", - isArchived = false, - resources = listOf(), - ), - ), - isGeometryComputedFromControls = false, - ) - - // When - val throwable = catchThrowable { jpaMissionRepository.save(newMission) } - - // Then - assertThat(throwable).isInstanceOf(DataIntegrityViolationException::class.java) - } - - @Test - @Transactional - fun `findAll Should return all missions when only required startedAfter is set to a very old date`() { + @Test + @Transactional + fun `findAll Should return filtered missions when status is set to UPCOMING`() { // When val missions = jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T00:01:00Z").toInstant(), + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), startedBefore = null, missionTypes = null, - missionStatuses = null, seaFronts = null, + missionStatuses = listOf("UPCOMING"), pageable = Pageable.unpaged(), ) - assertThat(missions).hasSize(54) + assertThat(missions).hasSize(7) } @Test @Transactional - fun `findAll Should return filtered missions when startedAfter & startedBefore are set`() { + fun `findAll Should return filtered missions when status is set to PENDING`() { // When val missions = jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, missionTypes = null, - missionStatuses = null, seaFronts = null, + missionStatuses = listOf("PENDING"), pageable = Pageable.unpaged(), ) - assertThat(missions).hasSize(21) + assertThat(missions).hasSize(14) } @Test @Transactional - fun `findAll Should return filtered missions when missionTypes is set`() { + fun `findAll Should return filtered missions when status is set to ENDED`() { // When val missions = jpaMissionRepository.findAllFullMissions( startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), startedBefore = null, - missionTypes = listOf("SEA"), - missionStatuses = null, + missionTypes = null, seaFronts = null, + missionStatuses = listOf("ENDED"), pageable = Pageable.unpaged(), ) - assertThat(missions).hasSize(22) + assertThat(missions).hasSize(15) } @Test @Transactional - fun `findAll Should return filtered missions when multiple missionTypes are set`() { + fun `findAll Should return filtered missions when status is set to CLOSED`() { // When val missions = jpaMissionRepository.findAllFullMissions( startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), startedBefore = null, - missionTypes = listOf("SEA", "LAND"), - missionStatuses = null, + missionTypes = null, seaFronts = null, + missionStatuses = listOf("CLOSED"), pageable = Pageable.unpaged(), ) - assertThat(missions).hasSize(45) + assertThat(missions).hasSize(18) } @Test @Transactional - fun `findAll Should return filtered missions when seaFront is set to MEMN`() { + fun `findAll Should return filtered missions when status is set to CLOSED or UPCOMING`() { // When val missions = jpaMissionRepository.findAllFullMissions( startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), startedBefore = null, missionTypes = null, - missionStatuses = null, - seaFronts = listOf("MEMN"), + seaFronts = null, + missionStatuses = listOf("CLOSED", "UPCOMING"), pageable = Pageable.unpaged(), ) - assertThat(missions).hasSize(9) + assertThat(missions).hasSize(25) } @Test @Transactional - fun `findAll Should return filtered missions when seaFront is set to MEMN and NAMO`() { + fun `findAll with pagenumber and pagesize Should return subset of missions`() { // When val missions = jpaMissionRepository.findAllFullMissions( @@ -490,166 +253,329 @@ class JpaMissionRepositoryITests : AbstractDBTests() { startedBefore = null, missionTypes = null, missionStatuses = null, - seaFronts = listOf("MEMN", "NAMO"), - pageable = Pageable.unpaged(), + seaFronts = null, + pageable = PageRequest.of(1, 10), ) - assertThat(missions).hasSize(27) + assertThat(missions).hasSize(10) } @Test @Transactional - fun `findAll Should return filtered missions when status is set to UPCOMING`() { + fun `findAll should filter missions based on MissionSources`() { // When val missions = jpaMissionRepository.findAllFullMissions( startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), startedBefore = null, missionTypes = null, + missionStatuses = null, seaFronts = null, - missionStatuses = listOf("UPCOMING"), + missionSources = + listOf( + MissionSourceEnum.MONITORFISH, + MissionSourceEnum.POSEIDON_CACEM, + MissionSourceEnum.POSEIDON_CNSP, + ), pageable = Pageable.unpaged(), ) - assertThat(missions).hasSize(7) + assertThat(missions).hasSize(3) } @Test @Transactional - fun `findAll Should return filtered missions when status is set to PENDING`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("PENDING"), - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(14) + fun `findByControlUnitId should find the matching missions`() { + val foundMissions = jpaMissionRepository.findByControlUnitId(10002) + + assertThat(foundMissions).hasSize(17) } @Test @Transactional - fun `findAll Should return filtered missions when status is set to ENDED`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("ENDED"), - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(15) + fun `findByControlUnitResourceId should find the matching missions`() { + val foundMissions = jpaMissionRepository.findByControlUnitResourceId(8) + + assertThat(foundMissions).hasSize(4) } @Test @Transactional - fun `findAll Should return filtered missions when status is set to CLOSED`() { + fun `findById Should return specified mission`() { // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("CLOSED"), - pageable = Pageable.unpaged(), + val wktReader = WKTReader() + val multipolygonString = + "MULTIPOLYGON (((-4.99360539 48.42853215, -4.99359905 48.42848997, -4.99359291 48.42844777, -4.99358697 48.42840556, -4.99358123 48.42836334, -4.99357569 48.4283211, -4.99357035 48.42827886, -4.9935652 48.4282366, -4.99356026 48.42819434, -4.99355552 48.42815206, -4.99355097 48.42810977, -4.99354663 48.42806748, -4.99354249 48.42802517, -4.99353854 48.42798286, -4.9935348 48.42794054, -4.99353125 48.42789821, -4.99352791 48.42785587, -4.99352476 48.42781353, -4.99352182 48.42777118, -4.99351907 48.42772882, -4.99351653 48.42768646, -4.99351418 48.4276441, -4.99351203 48.42760173, -4.99351009 48.42755935, -4.99350834 48.42751697, -4.9935068 48.42747459, -4.99350545 48.42743221, -4.99350431 48.42738982, -4.99350336 48.42734743, -4.99350262 48.42730504, -4.99350207 48.42726264, -4.99350173 48.42722025, -4.99350158 48.42717785, -4.99350164 48.42713546, -4.99350189 48.42709307, -4.99350235 48.42705067, -4.99350301 48.42700828, -4.99350386 48.42696589, -4.99350492 48.4269235, -4.99350617 48.42688111, -4.99350763 48.42683873, -4.99350929 48.42679635, -4.99351114 48.42675397, -4.9935132 48.4267116, -4.99351545 48.42666923, -4.99351791 48.42662687, -4.99352057 48.42658451, -4.99352342 48.42654216, -4.99352648 48.42649981, -4.99352973 48.42645747, -4.99353319 48.42641514, -4.99353685 48.42637282, -4.9935407 48.4263305, -4.99354476 48.42628819, -4.99354901 48.42624589, -4.99355346 48.4262036, -4.99355812 48.42616132, -4.99356297 48.42611905, -4.99356802 48.42607679, -4.99357328 48.42603454, -4.99357873 48.4259923, -4.99358438 48.42595007, -4.99359023 48.42590785, -4.99359628 48.42586565, -4.99360253 48.42582346, -4.99360898 48.42578128, -4.99361562 48.42573912, -4.99362247 48.42569697, -4.99362951 48.42565484, -4.99363676 48.42561272, -4.9936442 48.42557061, -4.99365184 48.42552853, -4.99365968 48.42548645, -4.99366772 48.4254444, -4.99367596 48.42540236, -4.99368439 48.42536034, -4.99369302 48.42531833, -4.99370186 48.42527635, -4.99371089 48.42523438, -4.99372011 48.42519243, -4.99372954 48.42515051, -4.99373916 48.4251086, -4.99374898 48.42506671, -4.993759 48.42502484, -4.99376922 48.424983, -4.99377963 48.42494117, -4.99379024 48.42489937, -4.99380105 48.42485759, -4.99381206 48.42481583, -4.99382326 48.4247741, -4.99383466 48.42473239, -4.99384626 48.4246907, -4.99385805 48.42464904, -4.99387004 48.42460741, -4.99388223 48.42456579, -4.99389461 48.42452421, -4.99390719 48.42448265, -4.99391996 48.42444111, -4.99393293 48.42439961, -4.9939461 48.42435813, -4.99395946 48.42431668, -4.99397302 48.42427525, -4.99398677 48.42423386, -4.99400072 48.42419249, -4.99401487 48.42415116, -4.9940292 48.42410985, -4.99404374 48.42406857, -4.99405847 48.42402733, -4.99407339 48.42398611, -4.99408851 48.42394493, -4.99410382 48.42390378, -4.99411932 48.42386266, -4.99413502 48.42382157, -4.99415092 48.42378052, -4.994167 48.4237395, -4.99418328 48.42369851, -4.99419976 48.42365756, -4.99421643 48.42361664, -4.99423329 48.42357576, -4.99425034 48.42353491, -4.99426759 48.4234941, -4.99428502 48.42345333, -4.99430265 48.42341259, -4.99432048 48.42337189, -4.99433849 48.42333122, -4.9943567 48.4232906, -4.9943751 48.42325001, -4.99439369 48.42320946, -4.99441247 48.42316895, -4.99443144 48.42312848, -4.9944506 48.42308805, -4.99446996 48.42304766, -4.9944895 48.42300731, -4.99450924 48.422967, -4.99452916 48.42292673, -4.99454928 48.42288651, -4.99456958 48.42284633, -4.99459007 48.42280619, -4.99461076 48.42276609, -4.99463163 48.42272603, -4.99465269 48.42268602, -4.99467394 48.42264606, -4.99469538 48.42260614, -4.99471701 48.42256626, -4.99473882 48.42252643, -4.99476082 48.42248665, -4.99478301 48.42244691, -4.99480539 48.42240721, -4.99482796 48.42236757, -4.99485071 48.42232797, -4.99487365 48.42228842, -4.99489677 48.42224892, -4.99492008 48.42220947, -4.99494358 48.42217006, -4.99496727 48.42213071, -4.99499113 48.4220914, -4.99501519 48.42205215, -4.99503943 48.42201294, -4.99506385 48.42197379, -4.99508846 48.42193469, -4.99511326 48.42189563, -4.99513823 48.42185664, -4.99516339 48.42181769, -4.99518874 48.4217788, -4.99521427 48.42173995, -4.99523998 48.42170117, -4.99526587 48.42166243, -4.99529195 48.42162376, -4.99531821 48.42158513, -4.99534465 48.42154656, -4.99537128 48.42150805, -4.99539808 48.42146959, -4.99542507 48.42143119, -4.99545224 48.42139285, -4.99547959 48.42135456, -4.99550711 48.42131633, -4.99553482 48.42127816, -4.99556271 48.42124004, -4.99559078 48.42120199, -4.99561903 48.42116399, -4.99564746 48.42112605, -4.99567606 48.42108817, -4.99570485 48.42105035, -4.99573381 48.4210126, -4.99576295 48.4209749, -4.99579227 48.42093726, -4.99582177 48.42089969, -4.99585144 48.42086218, -4.99588129 48.42082473, -4.99591132 48.42078734, -4.99594152 48.42075001, -4.9959719 48.42071275, -4.99600246 48.42067555, -4.99603319 48.42063842, -4.9960641 48.42060135, -4.99609518 48.42056435, -4.99612643 48.42052741, -4.99615786 48.42049053, -4.99618946 48.42045372, -4.99622124 48.42041698, -4.99625319 48.42038031, -4.99628531 48.4203437, -4.9963176 48.42030716, -4.99635007 48.42027069, -4.99638271 48.42023428, -4.99641552 48.42019794, -4.9964485 48.42016168, -4.99648166 48.42012548, -4.99651498 48.42008935, -4.99654847 48.42005329, -4.99658214 48.4200173, -4.99661597 48.41998138, -4.99664997 48.41994553, -4.99668415 48.41990976, -4.99671849 48.41987405, -4.996753 48.41983842, -4.99678767 48.41980286, -4.99682252 48.41976737, -4.99685753 48.41973196, -4.99689271 48.41969662, -4.99692805 48.41966135, -4.99696356 48.41962616, -4.99699924 48.41959104, -4.99703508 48.41955599, -4.99707109 48.41952102, -4.99710726 48.41948613, -4.9971436 48.41945131, -4.9971801 48.41941657, -4.99721677 48.4193819, -4.9972536 48.41934732, -4.99729059 48.4193128, -4.99732774 48.41927837, -4.99736506 48.41924402, -4.99740254 48.41920974, -4.99744018 48.41917554, -4.99747798 48.41914142, -4.99751594 48.41910738, -4.99755406 48.41907342, -4.99759234 48.41903953, -4.99763079 48.41900573, -4.99766939 48.41897201, -4.99770815 48.41893837, -4.99774707 48.41890481, -4.99778614 48.41887133, -4.99782538 48.41883794, -4.99786477 48.41880463, -4.99790432 48.4187714, -4.99794402 48.41873825, -4.99798388 48.41870518, -4.9980239 48.4186722, -4.99806408 48.4186393, -4.9981044 48.41860649, -4.99814489 48.41857376, -4.99818552 48.41854112, -4.99822631 48.41850856, -4.99826726 48.41847609, -4.99830835 48.4184437, -4.9983496 48.4184114, -4.99839101 48.41837918, -4.99843256 48.41834705, -4.99847426 48.41831501, -4.99851612 48.41828306, -4.99855813 48.41825119, -4.99860028 48.41821941, -4.99864259 48.41818772, -4.99868504 48.41815612, -4.99872765 48.41812461, -4.9987704 48.41809319, -4.9988133 48.41806185, -4.99885635 48.41803061, -4.99889955 48.41799946, -4.99894289 48.41796839, -4.99898638 48.41793742, -4.99903001 48.41790654, -4.99907379 48.41787575, -4.99911772 48.41784505, -4.99916179 48.41781444, -4.999206 48.41778393, -4.99925036 48.41775351, -4.99929486 48.41772318, -4.99933951 48.41769294, -4.99938429 48.4176628, -4.99942922 48.41763276, -4.99947429 48.4176028, -4.9995195 48.41757294, -4.99956485 48.41754318, -4.99961035 48.41751351, -4.99965598 48.41748393, -4.99970175 48.41745445, -4.99974766 48.41742507, -4.99979371 48.41739578, -4.99983989 48.41736659, -4.99988622 48.4173375, -4.99993268 48.4173085, -4.99997927 48.4172796, -5.00002601 48.4172508, -5.00007288 48.4172221, -5.00011988 48.41719349, -5.00016702 48.41716498, -5.00021429 48.41713657, -5.0002617 48.41710826, -5.00030924 48.41708005, -5.00035691 48.41705194, -5.00040472 48.41702393, -5.00045266 48.41699602, -5.00050072 48.41696821, -5.00054892 48.4169405, -5.00059725 48.41691289, -5.00064571 48.41688538, -5.0006943 48.41685797, -5.00074302 48.41683067, -5.00079187 48.41680346, -5.00084085 48.41677636, -5.00088995 48.41674937, -5.00093918 48.41672247, -5.00098854 48.41669568, -5.00103802 48.41666899, -5.00108763 48.4166424, -5.00113736 48.41661592, -5.00118722 48.41658954, -5.0012372 48.41656327, -5.00128731 48.4165371, -5.00133754 48.41651104, -5.00138789 48.41648508, -5.00143837 48.41645923, -5.00148896 48.41643348, -5.00153968 48.41640784, -5.00159052 48.4163823, -5.00164148 48.41635688, -5.00169256 48.41633155, -5.00174375 48.41630634, -5.00179507 48.41628123, -5.0018465 48.41625623, -5.00189805 48.41623134, -5.00194972 48.41620655, -5.00200151 48.41618187, -5.00205341 48.41615731, -5.00210543 48.41613285, -5.00215756 48.4161085, -5.00220981 48.41608425, -5.00226217 48.41606012, -5.00231465 48.4160361, -5.00236723 48.41601219, -5.00241993 48.41598838, -5.00247275 48.41596469, -5.00252567 48.41594111, -5.00257871 48.41591764, -5.00263185 48.41589428, -5.00268511 48.41587103, -5.00273847 48.41584789, -5.00279195 48.41582486, -5.00284553 48.41580195, -5.00289922 48.41577915, -5.00295301 48.41575646, -5.00300692 48.41573388, -5.00306093 48.41571142, -5.00311504 48.41568907, -5.00316927 48.41566683, -5.00322359 48.4156447, -5.00327802 48.41562269, -5.00333255 48.4156008, -5.00338719 48.41557901, -5.00344193 48.41555735, -5.00349677 48.41553579, -5.00355171 48.41551435, -5.00360676 48.41549303, -5.0036619 48.41547182, -5.00371714 48.41545073, -5.00377249 48.41542975, -5.00382793 48.41540889, -5.00388347 48.41538814, -5.0039391 48.41536751, -5.00399484 48.415347, -5.00405067 48.4153266, -5.00410659 48.41530632, -5.00416261 48.41528616, -5.00421873 48.41526611, -5.00427494 48.41524619, -5.00433125 48.41522638, -5.00438764 48.41520668, -5.00444413 48.41518711, -5.00450072 48.41516765, -5.00455739 48.41514831, -5.00461416 48.41512909, -5.00467101 48.41510999, -5.00472796 48.41509101, -5.00478499 48.41507215, -5.00484211 48.41505341, -5.00489932 48.41503478, -5.00495662 48.41501628, -5.00501401 48.4149979, -5.00507148 48.41497963, -5.00512904 48.41496149, -5.00518668 48.41494347, -5.00524441 48.41492556, -5.00530222 48.41490778, -5.00536012 48.41489012, -5.0054181 48.41487258, -5.00547616 48.41485516, -5.0055343 48.41483786, -5.00559252 48.41482069, -5.00565083 48.41480364, -5.00570921 48.4147867, -5.00576768 48.4147699, -5.00582622 48.41475321, -5.00588485 48.41473664, -5.00594355 48.4147202, -5.00600232 48.41470388, -5.00606118 48.41468769, -5.00612011 48.41467161, -5.00617911 48.41465566, -5.00623819 48.41463984, -5.00629735 48.41462414, -5.00635658 48.41460856, -5.00641588 48.4145931, -5.00647525 48.41457777, -5.0065347 48.41456257, -5.00659422 48.41454748, -5.00665381 48.41453253, -5.00671347 48.41451769, -5.0067732 48.41450298, -5.00683299 48.4144884, -5.00689286 48.41447394, -5.00695279 48.41445961, -5.0070128 48.4144454, -5.00707286 48.41443132, -5.007133 48.41441736, -5.0071932 48.41440353, -5.00725346 48.41438983, -5.00731379 48.41437625, -5.00737419 48.4143628, -5.00743464 48.41434947, -5.00749516 48.41433627, -5.00755574 48.4143232, -5.00761638 48.41431025, -5.00767709 48.41429743, -5.00773785 48.41428474, -5.00779867 48.41427218, -5.00785955 48.41425974, -5.00792049 48.41424743, -5.00798149 48.41423525, -5.00804255 48.41422319, -5.00810366 48.41421126, -5.00816482 48.41419946, -5.00822605 48.41418779, -5.00828732 48.41417625, -5.00834866 48.41416483, -5.00841004 48.41415354, -5.00847148 48.41414238, -5.00853297 48.41413135, -5.00859451 48.41412045, -5.0086561 48.41410968, -5.00871775 48.41409903, -5.00877944 48.41408852, -5.00884119 48.41407813, -5.00890298 48.41406787, -5.00896482 48.41405775, -5.0090267 48.41404775, -5.00908864 48.41403788, -5.00915062 48.41402814, -5.00921264 48.41401853, -5.00927471 48.41400905, -5.00933683 48.4139997, -5.00939899 48.41399048, -5.00946119 48.41398139, -5.00952344 48.41397243, -5.00958572 48.4139636, -5.00964805 48.4139549, -5.00971042 48.41394633, -5.00977283 48.41393789, -5.00983528 48.41392958, -5.00989777 48.4139214, -5.00996029 48.41391335, -5.01002285 48.41390544, -5.01008545 48.41389765, -5.01014809 48.41389, -5.01021076 48.41388247, -5.01027347 48.41387508, -5.01033621 48.41386782, -5.01039899 48.41386069, -5.0104618 48.41385369, -5.01052464 48.41384682, -5.01058752 48.41384009, -5.01065042 48.41383348, -5.01071336 48.41382701, -5.01077633 48.41382067, -5.01083932 48.41381446, -5.01090235 48.41380838, -5.0109654 48.41380243, -5.01102848 48.41379662, -5.01109159 48.41379094, -5.01115473 48.41378539, -5.01121789 48.41377997, -5.01128107 48.41377468, -5.01134429 48.41376953, -5.01140752 48.41376451, -5.01147078 48.41375962, -5.01153406 48.41375486, -5.01159736 48.41375023, -5.01166069 48.41374574, -5.01172403 48.41374138, -5.0117874 48.41373715, -5.01185078 48.41373306, -5.01191419 48.41372909, -5.01197761 48.41372526, -5.01204105 48.41372157, -5.01210451 48.413718, -5.01216798 48.41371457, -5.01223147 48.41371127, -5.01229498 48.4137081, -5.0123585 48.41370507, -5.01242203 48.41370217, -5.01248558 48.4136994, -5.01254914 48.41369676, -5.01261271 48.41369426, -5.0126763 48.41369189, -5.01273989 48.41368965, -5.0128035 48.41368755, -5.01286711 48.41368558, -5.01293073 48.41368374, -5.01299437 48.41368204, -5.013058 48.41368047, -5.01312165 48.41367903, -5.0131853 48.41367772, -5.01324896 48.41367655, -5.01331263 48.41367551, -5.0133763 48.41367461, -5.01343997 48.41367383, -5.01350364 48.41367319, -5.01356732 48.41367269, -5.013631 48.41367231, -5.01369469 48.41367207, -5.01375837 48.41367197, -5.01382205 48.41367199, -5.01388573 48.41367215, -5.01394942 48.41367244, -5.0140131 48.41367287, -5.01407677 48.41367343, -5.01414045 48.41367412, -5.01420412 48.41367494, -5.01426779 48.4136759, -5.01433145 48.41367699, -5.01439511 48.41367822, -5.01445876 48.41367957, -5.0145224 48.41368106, -5.01458604 48.41368269, -5.01464966 48.41368444, -5.01471328 48.41368633, -5.0147769 48.41368836, -5.0148405 48.41369051, -5.01490409 48.4136928, -5.01496767 48.41369522, -5.01503123 48.41369778, -5.01509479 48.41370046, -5.01515833 48.41370328, -5.01522186 48.41370624, -5.01528537 48.41370932, -5.01534887 48.41371254, -5.01541236 48.41371589, -5.01547582 48.41371938, -5.01553928 48.41372299, -5.01560271 48.41372674, -5.01566613 48.41373062, -5.01572952 48.41373464, -5.0157929 48.41373879, -5.01585626 48.41374307, -5.0159196 48.41374748, -5.01598291 48.41375202, -5.01604621 48.4137567, -5.01610948 48.41376151, -5.01617273 48.41376645, -5.01623595 48.41377152, -5.01629915 48.41377673, -5.01636233 48.41378207, -5.01642548 48.41378754, -5.01648861 48.41379314, -5.01655171 48.41379887, -5.01661478 48.41380474, -5.01667782 48.41381074, -5.01674083 48.41381687, -5.01680382 48.41382313, -5.01686677 48.41382952, -5.0169297 48.41383605, -5.01699259 48.4138427, -5.01705545 48.41384949, -5.01711828 48.41385641, -5.01718108 48.41386346, -5.01724384 48.41387064, -5.01730657 48.41387795, -5.01736927 48.4138854, -5.01743192 48.41389297, -5.01749455 48.41390068, -5.01755713 48.41390851, -5.01761968 48.41391648, -5.01768219 48.41392458, -5.01774467 48.41393281, -5.0178071 48.41394117, -5.01786949 48.41394966, -5.01793185 48.41395828, -5.01799416 48.41396703, -5.01805643 48.41397591, -5.01811866 48.41398492, -5.01818084 48.41399406, -5.01824298 48.41400333, -5.01830508 48.41401274, -5.01836714 48.41402227, -5.01842914 48.41403193, -5.01849111 48.41404172, -5.01855302 48.41405164, -5.01861489 48.41406169, -5.01867671 48.41407186, -5.01873848 48.41408217, -5.01880021 48.41409261, -5.01886188 48.41410317, -5.01892351 48.41411387, -5.01898508 48.41412469, -5.0190466 48.41413565, -5.01910807 48.41414673, -5.01916949 48.41415794, -5.01923085 48.41416927, -5.01929216 48.41418074, -5.01935342 48.41419233, -5.01941462 48.41420405, -5.01947577 48.4142159, -5.01953686 48.41422788, -5.01959789 48.41423999, -5.01965886 48.41425222, -5.01971978 48.41426458, -5.01978064 48.41427707, -5.01984144 48.41428968, -5.01990218 48.41430242, -5.01996286 48.41431529, -5.02002348 48.41432829, -5.02008403 48.41434141, -5.02014453 48.41435466, -5.02020496 48.41436804, -5.02026533 48.41438154, -5.02032563 48.41439517, -5.02038587 48.41440892, -5.02044604 48.4144228, -5.02050615 48.4144368, -5.0205662 48.41445093, -5.02062617 48.41446519, -5.02068608 48.41447957, -5.02074592 48.41449408, -5.02080569 48.41450871, -5.02086539 48.41452347, -5.02092502 48.41453835, -5.02098458 48.41455336, -5.02104407 48.41456849, -5.02110349 48.41458374, -5.02116284 48.41459912, -5.02122211 48.41461463, -5.02128131 48.41463025, -5.02134044 48.414646, -5.02139949 48.41466188, -5.02145847 48.41467788, -5.02151737 48.414694, -5.02157619 48.41471024, -5.02163494 48.41472661, -5.02169361 48.4147431, -5.0217522 48.41475971, -5.02181071 48.41477644, -5.02186915 48.4147933, -5.0219275 48.41481028, -5.02198577 48.41482738, -5.02204397 48.4148446, -5.02210208 48.41486195, -5.02216011 48.41487941, -5.02221805 48.414897, -5.02227592 48.41491471, -5.0223337 48.41493254, -5.02239139 48.41495049, -5.022449 48.41496856, -5.02250653 48.41498675, -5.02256396 48.41500506, -5.02262132 48.41502349, -5.02267858 48.41504204, -5.02273576 48.41506071, -5.02279285 48.4150795, -5.02284984 48.41509841, -5.02290675 48.41511744, -5.02296357 48.41513659, -5.0230203 48.41515585, -5.02307694 48.41517524, -5.02313349 48.41519474, -5.02318994 48.41521436, -5.0232463 48.4152341, -5.02330257 48.41525395, -5.02335875 48.41527393, -5.02341483 48.41529402, -5.02347081 48.41531423, -5.0235267 48.41533455, -5.02358249 48.41535499, -5.02363819 48.41537555, -5.02369379 48.41539623, -5.02374929 48.41541702, -5.02380469 48.41543793, -5.02385999 48.41545895, -5.0239152 48.41548009, -5.0239703 48.41550134, -5.02402531 48.41552271, -5.02408021 48.41554419, -5.02413501 48.41556579, -5.02418971 48.41558751, -5.02424431 48.41560933, -5.0242988 48.41563127, -5.02435319 48.41565333, -5.02440747 48.4156755, -5.02446165 48.41569778, -5.02451573 48.41572017, -5.0245697 48.41574268, -5.02462356 48.4157653, -5.02467731 48.41578804, -5.02473096 48.41581088, -5.0247845 48.41583384, -5.02483793 48.41585691, -5.02489126 48.41588009, -5.02494447 48.41590338, -5.02499757 48.41592679, -5.02505056 48.4159503, -5.02510344 48.41597393, -5.02515621 48.41599766, -5.02520887 48.41602151, -5.02526141 48.41604547, -5.02531384 48.41606953, -5.02536616 48.41609371, -5.02541836 48.41611799, -5.02547045 48.41614238, -5.02552242 48.41616689, -5.02557428 48.4161915, -5.02562602 48.41621622, -5.02567764 48.41624104, -5.02572915 48.41626598, -5.02578054 48.41629102, -5.02583181 48.41631617, -5.02588296 48.41634143, -5.02593399 48.41636679, -5.0259849 48.41639226, -5.02603569 48.41641784, -5.02608636 48.41644352, -5.02613691 48.41646931, -5.02618734 48.4164952, -5.02623764 48.4165212, -5.02628782 48.41654731, -5.02633788 48.41657352, -5.02638782 48.41659983, -5.02643763 48.41662625, -5.02648731 48.41665277, -5.02653687 48.4166794, -5.02658631 48.41670613, -5.02663561 48.41673296, -5.02668479 48.41675989, -5.02673385 48.41678693, -5.02678277 48.41681407, -5.02683157 48.41684132, -5.02688024 48.41686866, -5.02692878 48.41689611, -5.02697719 48.41692366, -5.02702547 48.4169513, -5.02707362 48.41697905, -5.02712163 48.4170069, -5.02716952 48.41703485, -5.02721727 48.4170629, -5.02726489 48.41709105, -5.02731238 48.4171193, -5.02735974 48.41714765, -5.02740696 48.4171761, -5.02745404 48.41720465, -5.027501 48.41723329, -5.02754781 48.41726203, -5.02759449 48.41729087, -5.02764104 48.41731981, -5.02768744 48.41734885, -5.02773371 48.41737798, -5.02777985 48.41740721, -5.02782584 48.41743653, -5.02787169 48.41746595, -5.02791741 48.41749547, -5.02796299 48.41752508, -5.02800843 48.41755479, -5.02805372 48.41758459, -5.02809888 48.41761449, -5.02814389 48.41764448, -5.02818877 48.41767456, -5.0282335 48.41770474, -5.02827809 48.41773501, -5.02832253 48.41776538, -5.02836683 48.41779583, -5.02841099 48.41782638, -5.028455 48.41785703, -5.02849887 48.41788776, -5.0285426 48.41791859, -5.02858617 48.4179495, -5.02862961 48.41798051, -5.02867289 48.41801161, -5.02871603 48.4180428, -5.02875902 48.41807408, -5.02880186 48.41810545, -5.02884456 48.4181369, -5.02888711 48.41816845, -5.0289295 48.41820009, -5.02897175 48.41823181, -5.02901385 48.41826362, -5.0290558 48.41829552, -5.02909759 48.41832751, -5.02913924 48.41835959, -5.02918073 48.41839175, -5.02922208 48.418424, -5.02926327 48.41845633, -5.0293043 48.41848876, -5.02934519 48.41852126, -5.02938592 48.41855385, -5.02942649 48.41858653, -5.02946692 48.41861929, -5.02950718 48.41865214, -5.0295473 48.41868507, -5.02958725 48.41871808, -5.02962705 48.41875118, -5.0296667 48.41878436, -5.02970619 48.41881762, -5.02974552 48.41885097, -5.02978469 48.4188844, -5.0298237 48.41891791, -5.02986256 48.4189515, -5.02990126 48.41898517, -5.0299398 48.41901892, -5.02997818 48.41905275, -5.0300164 48.41908667, -5.03005446 48.41912066, -5.03009236 48.41915473, -5.0301301 48.41918888, -5.03016767 48.41922311, -5.03020509 48.41925742, -5.03024234 48.41929181, -5.03027943 48.41932627, -5.03031636 48.41936081, -5.03035312 48.41939543, -5.03038972 48.41943013, -5.03042616 48.4194649, -5.03046243 48.41949974, -5.03049854 48.41953467, -5.03053449 48.41956967, -5.03057026 48.41960474, -5.03060588 48.41963989, -5.03064132 48.41967511, -5.0306766 48.41971041, -5.03071172 48.41974578, -5.03074666 48.41978122, -5.03078144 48.41981674, -5.03081605 48.41985233, -5.0308505 48.41988799, -5.03088477 48.41992372, -5.03091888 48.41995952, -5.03095281 48.4199954, -5.03098658 48.42003134, -5.03102018 48.42006736, -5.03105361 48.42010345, -5.03108686 48.4201396, -5.03111995 48.42017583, -5.03115287 48.42021212, -5.03118561 48.42024849, -5.03121818 48.42028492, -5.03125058 48.42032142, -5.03128281 48.42035799, -5.03131486 48.42039462, -5.03134675 48.42043132, -5.03137845 48.42046809, -5.03140999 48.42050492, -5.03144135 48.42054182, -5.03147254 48.42057879, -5.03150355 48.42061582, -5.03153439 48.42065291, -5.03156505 48.42069007, -5.03159553 48.42072729, -5.03162584 48.42076458, -5.03165598 48.42080193, -5.03168594 48.42083934, -5.03171572 48.42087682, -5.03174532 48.42091435, -5.03177475 48.42095195, -5.031804 48.42098961, -5.03183307 48.42102733, -5.03186197 48.42106511, -5.03189068 48.42110295, -5.03191922 48.42114086, -5.03194758 48.42117882, -5.03197575 48.42121684, -5.03200375 48.42125492, -5.03203157 48.42129305, -5.03205921 48.42133125, -5.03208667 48.4213695, -5.03211395 48.42140781, -5.03214105 48.42144618, -5.03216796 48.4214846, -5.0321947 48.42152308, -5.03222125 48.42156162, -5.03224762 48.42160021, -5.03227381 48.42163885, -5.03229981 48.42167755, -5.03232564 48.42171631, -5.03235128 48.42175511, -5.03237673 48.42179398, -5.03240201 48.42183289, -5.0324271 48.42187186, -5.032452 48.42191088, -5.03247672 48.42194995, -5.03250126 48.42198907, -5.03252561 48.42202824, -5.03254978 48.42206747, -5.03257376 48.42210674, -5.03259756 48.42214607, -5.03262117 48.42218544, -5.0326446 48.42222487, -5.03266783 48.42226434, -5.03269089 48.42230386, -5.03271375 48.42234343, -5.03273643 48.42238304, -5.03275892 48.42242271, -5.03278123 48.42246242, -5.03280334 48.42250217, -5.03282527 48.42254198, -5.03284702 48.42258183, -5.03286857 48.42262172, -5.03288993 48.42266166, -5.03291111 48.42270164, -5.0329321 48.42274167, -5.0329529 48.42278174, -5.03297351 48.42282185, -5.03299393 48.42286201, -5.03301416 48.42290221, -5.0330342 48.42294245, -5.03305405 48.42298274, -5.03307371 48.42302306, -5.03309318 48.42306343, -5.03311246 48.42310383, -5.03313155 48.42314428, -5.03315044 48.42318476, -5.03316915 48.42322529, -5.03318766 48.42326585, -5.03320599 48.42330646, -5.03322412 48.4233471, -5.03324206 48.42338777, -5.03325981 48.42342849, -5.03327736 48.42346924, -5.03329473 48.42351003, -5.0333119 48.42355086, -5.03332888 48.42359172, -5.03334566 48.42363261, -5.03336225 48.42367355, -5.03337865 48.42371451, -5.03339486 48.42375551, -5.03341087 48.42379654, -5.03342669 48.42383761, -5.03344231 48.42387871, -5.03345774 48.42391984, -5.03347298 48.42396101, -5.03348802 48.4240022, -5.03350286 48.42404343, -5.03351752 48.42408469, -5.03353197 48.42412598, -5.03354624 48.42416729, -5.0335603 48.42420864, -5.03357418 48.42425002, -5.03358785 48.42429142, -5.03360133 48.42433286, -5.03361462 48.42437432, -5.03362771 48.42441581, -5.0336406 48.42445733, -5.0336533 48.42449887, -5.0336658 48.42454044, -5.03367811 48.42458204, -5.03369022 48.42462366, -5.03370213 48.42466531, -5.03371385 48.42470698, -5.03372537 48.42474867, -5.03373669 48.42479039, -5.03374782 48.42483214, -5.03375875 48.4248739, -5.03376948 48.42491569, -5.03378001 48.4249575, -5.03379035 48.42499933, -5.03380049 48.42504119, -5.03381043 48.42508306, -5.03382017 48.42512496, -5.03382972 48.42516687, -5.03383907 48.42520881, -5.03384822 48.42525077, -5.03385717 48.42529274, -5.03386593 48.42533473, -5.03387448 48.42537674, -5.03388284 48.42541877, -5.033891 48.42546082, -5.03389896 48.42550288, -5.03390672 48.42554496, -5.03391428 48.42558705, -5.03392165 48.42562916, -5.03392882 48.42567129, -5.03393578 48.42571343, -5.03394255 48.42575558, -5.03394912 48.42579775, -5.03395549 48.42583993, -5.03396166 48.42588213, -5.03396763 48.42592434, -5.03397341 48.42596656, -5.03397898 48.42600879, -5.03398435 48.42605103, -5.03398953 48.42609329, -5.0339945 48.42613555, -5.03399928 48.42617783, -5.03400385 48.42622011, -5.03400823 48.42626241, -5.03401241 48.42630471, -5.03401638 48.42634702, -5.03402016 48.42638934, -5.03402374 48.42643167, -5.03402712 48.42647401, -5.03403029 48.42651635, -5.03403327 48.4265587, -5.03403605 48.42660105, -5.03403863 48.42664341, -5.03404101 48.42668577, -5.03404318 48.42672814, -5.03404516 48.42677052, -5.03404694 48.4268129, -5.03404852 48.42685528, -5.0340499 48.42689766, -5.03405107 48.42694005, -5.03405205 48.42698244, -5.03405283 48.42702483, -5.03405341 48.42706722, -5.03405379 48.42710962, -5.03405396 48.42715201, -5.03405394 48.42719441, -5.03405372 48.4272368, -5.03405329 48.4272792, -5.03405267 48.42732159, -5.03405185 48.42736398, -5.03405082 48.42740637, -5.0340496 48.42744876, -5.03404818 48.42749114, -5.03404655 48.42753352, -5.03404473 48.4275759, -5.03404271 48.42761827, -5.03404048 48.42766064, -5.03403806 48.427703, -5.03403544 48.42774536, -5.03403261 48.42778772, -5.03402959 48.42783006, -5.03402637 48.4278724, -5.03402294 48.42791474, -5.03401932 48.42795706, -5.0340155 48.42799938, -5.03401148 48.42804169, -5.03400725 48.42808399, -5.03400283 48.42812628, -5.03399821 48.42816857, -5.03399339 48.42821084, -5.03398837 48.4282531, -5.03398315 48.42829535, -5.03397773 48.4283376, -5.03397211 48.42837982, -5.03396629 48.42842204, -5.03396027 48.42846425, -5.03395406 48.42850644, -5.03394764 48.42854862, -5.03394103 48.42859078, -5.03393421 48.42863294, -5.0339272 48.42867507, -5.03391999 48.42871719, -5.03391258 48.4287593, -5.03390497 48.42880139, -5.03389716 48.42884347, -5.03388915 48.42888552, -5.03388095 48.42892757, -5.03387254 48.42896959, -5.03386394 48.4290116, -5.03385514 48.42905358, -5.03384614 48.42909555, -5.03383695 48.4291375, -5.03382755 48.42917944, -5.03381796 48.42922135, -5.03380817 48.42926324, -5.03379818 48.42930511, -5.033788 48.42934696, -5.03377761 48.42938878, -5.03376703 48.42943059, -5.03375626 48.42947237, -5.03374528 48.42951413, -5.03373411 48.42955587, -5.03372274 48.42959759, -5.03371117 48.42963928, -5.03369941 48.42968094, -5.03368745 48.42972258, -5.0336753 48.4297642, -5.03366294 48.42980579, -5.0336504 48.42984735, -5.03363765 48.42988889, -5.03362471 48.4299304, -5.03361157 48.42997188, -5.03359824 48.43001334, -5.03358471 48.43005477, -5.03357099 48.43009617, -5.03355707 48.43013754, -5.03354296 48.43017888, -5.03352865 48.43022019, -5.03351414 48.43026147, -5.03349944 48.43030272, -5.03348455 48.43034394, -5.03346946 48.43038513, -5.03345418 48.43042628, -5.0334387 48.43046741, -5.03342303 48.4305085, -5.03340717 48.43054956, -5.03339111 48.43059058, -5.03337486 48.43063158, -5.03335841 48.43067253, -5.03334177 48.43071346, -5.03332494 48.43075434, -5.03330791 48.4307952, -5.0332907 48.43083601, -5.03327329 48.43087679, -5.03325568 48.43091754, -5.03323789 48.43095824, -5.0332199 48.43099891, -5.03320172 48.43103954, -5.03318335 48.43108014, -5.03316479 48.43112069, -5.03314603 48.43116121, -5.03312709 48.43120169, -5.03310795 48.43124212, -5.03308862 48.43128252, -5.03306911 48.43132287, -5.0330494 48.43136319, -5.0330295 48.43140346, -5.03300941 48.43144369, -5.03298913 48.43148388, -5.03296866 48.43152403, -5.03294801 48.43156413, -5.03292716 48.43160419, -5.03290612 48.43164421, -5.0328849 48.43168418, -5.03286349 48.43172411, -5.03284189 48.43176399, -5.0328201 48.43180383, -5.03279812 48.43184362, -5.03277595 48.43188337, -5.0327536 48.43192307, -5.03273106 48.43196272, -5.03270833 48.43200232, -5.03268542 48.43204188, -5.03266232 48.43208139, -5.03263903 48.43212085, -5.03261555 48.43216026, -5.03259189 48.43219962, -5.03256805 48.43223894, -5.03254402 48.4322782, -5.0325198 48.43231741, -5.0324954 48.43235657, -5.03247081 48.43239568, -5.03244604 48.43243474, -5.03242109 48.43247375, -5.03239595 48.4325127, -5.03237063 48.4325516, -5.03234512 48.43259045, -5.03231943 48.43262925, -5.03229356 48.43266799, -5.0322675 48.43270667, -5.03224126 48.4327453, -5.03221484 48.43278388, -5.03218824 48.4328224, -5.03216146 48.43286087, -5.03213449 48.43289928, -5.03210735 48.43293763, -5.03208002 48.43297593, -5.03205251 48.43301416, -5.03202482 48.43305235, -5.03199695 48.43309047, -5.0319689 48.43312853, -5.03194067 48.43316654, -5.03191227 48.43320448, -5.03188368 48.43324237, -5.03185491 48.4332802, -5.03182597 48.43331796, -5.03179685 48.43335567, -5.03176755 48.43339331, -5.03173807 48.4334309, -5.03170841 48.43346842, -5.03167858 48.43350588, -5.03164857 48.43354327, -5.03161839 48.43358061, -5.03158802 48.43361788, -5.03155749 48.43365508, -5.03152677 48.43369223, -5.03149589 48.4337293, -5.03146482 48.43376632, -5.03143358 48.43380327, -5.03140217 48.43384015, -5.03137059 48.43387697, -5.03133883 48.43391372, -5.03130689 48.4339504, -5.03127479 48.43398702, -5.03124251 48.43402357, -5.03121006 48.43406005, -5.03117743 48.43409646, -5.03114464 48.43413281, -5.03111167 48.43416909, -5.03107853 48.4342053, -5.03104522 48.43424143, -5.03101175 48.4342775, -5.0309781 48.4343135, -5.03094428 48.43434943, -5.03091029 48.43438529, -5.03087613 48.43442107, -5.0308418 48.43445679, -5.03080731 48.43449243, -5.03077264 48.434528, -5.03073781 48.43456349, -5.03070281 48.43459892, -5.03066765 48.43463427, -5.03063232 48.43466955, -5.03059682 48.43470475, -5.03056115 48.43473988, -5.03052532 48.43477493, -5.03048933 48.43480991, -5.03045316 48.43484482, -5.03041684 48.43487964, -5.03038035 48.4349144, -5.03034369 48.43494907, -5.03030688 48.43498367, -5.0302699 48.43501819, -5.03023275 48.43505263, -5.03019545 48.435087, -5.03015798 48.43512129, -5.03012035 48.4351555, -5.03008256 48.43518963, -5.0300446 48.43522368, -5.03000649 48.43525765, -5.02996822 48.43529154, -5.02992979 48.43532535, -5.02989119 48.43535908, -5.02985244 48.43539273, -5.02981353 48.4354263, -5.02977446 48.43545979, -5.02973524 48.4354932, -5.02969585 48.43552652, -5.02965631 48.43555976, -5.02961661 48.43559292, -5.02957676 48.43562599, -5.02953675 48.43565898, -5.02949658 48.43569189, -5.02945626 48.43572472, -5.02941578 48.43575745, -5.02937515 48.43579011, -5.02933437 48.43582268, -5.02929343 48.43585516, -5.02925234 48.43588756, -5.02921109 48.43591987, -5.0291697 48.4359521, -5.02912815 48.43598423, -5.02908645 48.43601629, -5.0290446 48.43604825, -5.02900259 48.43608013, -5.02896044 48.43611192, -5.02891814 48.43614362, -5.02887569 48.43617523, -5.02883309 48.43620675, -5.02879034 48.43623818, -5.02874744 48.43626953, -5.02870439 48.43630078, -5.0286612 48.43633195, -5.02861786 48.43636302, -5.02857437 48.436394, -5.02853074 48.4364249, -5.02848696 48.4364557, -5.02844304 48.4364864, -5.02839897 48.43651702, -5.02835476 48.43654755, -5.0283104 48.43657798, -5.0282659 48.43660832, -5.02822126 48.43663856, -5.02817647 48.43666871, -5.02813154 48.43669877, -5.02808647 48.43672874, -5.02804126 48.43675861, -5.02799591 48.43678838, -5.02795041 48.43681806, -5.02790478 48.43684765, -5.02785901 48.43687714, -5.0278131 48.43690653, -5.02776705 48.43693583, -5.02772086 48.43696503, -5.02767454 48.43699413, -5.02762807 48.43702314, -5.02758147 48.43705205, -5.02753474 48.43708086, -5.02748787 48.43710958, -5.02744086 48.4371382, -5.02739372 48.43716671, -5.02734644 48.43719513, -5.02729903 48.43722345, -5.02725149 48.43725167, -5.02720381 48.4372798, -5.027156 48.43730782, -5.02710806 48.43733574, -5.02705998 48.43736356, -5.02701178 48.43739128, -5.02696344 48.4374189, -5.02691498 48.43744642, -5.02686638 48.43747384, -5.02681766 48.43750115, -5.02676881 48.43752836, -5.02671983 48.43755548, -5.02667072 48.43758248, -5.02662148 48.43760939, -5.02657212 48.43763619, -5.02652263 48.43766289, -5.02647301 48.43768949, -5.02642327 48.43771598, -5.0263734 48.43774237, -5.02632341 48.43776865, -5.0262733 48.43779483, -5.02622306 48.4378209, -5.0261727 48.43784687, -5.02612222 48.43787273, -5.02607161 48.43789849, -5.02602089 48.43792414, -5.02597004 48.43794969, -5.02591907 48.43797513, -5.02586798 48.43800046, -5.02581678 48.43802568, -5.02576545 48.4380508, -5.02571401 48.43807581, -5.02566245 48.43810072, -5.02561077 48.43812551, -5.02555897 48.4381502, -5.02550706 48.43817478, -5.02545503 48.43819924, -5.02540289 48.43822361, -5.02535063 48.43824786, -5.02529825 48.438272, -5.02524577 48.43829603, -5.02519317 48.43831995, -5.02514045 48.43834377, -5.02508763 48.43836747, -5.02503469 48.43839106, -5.02498165 48.43841454, -5.02492849 48.43843791, -5.02487522 48.43846117, -5.02482184 48.43848432, -5.02476835 48.43850735, -5.02471476 48.43853028, -5.02466105 48.43855309, -5.02460724 48.43857579, -5.02455332 48.43859837, -5.0244993 48.43862085, -5.02444517 48.43864321, -5.02439093 48.43866546, -5.02433659 48.43868759, -5.02428215 48.43870961, -5.0242276 48.43873151, -5.02417295 48.43875331, -5.02411819 48.43877498, -5.02406334 48.43879655, -5.02400838 48.43881799, -5.02395332 48.43883933, -5.02389816 48.43886055, -5.0238429 48.43888165, -5.02378754 48.43890263, -5.02373208 48.43892351, -5.02367653 48.43894426, -5.02362087 48.4389649, -5.02356512 48.43898542, -5.02350927 48.43900583, -5.02345333 48.43902611, -5.02339729 48.43904629, -5.02334115 48.43906634, -5.02328493 48.43908628, -5.0232286 48.4391061, -5.02317219 48.4391258, -5.02311568 48.43914538, -5.02305908 48.43916485, -5.02300238 48.43918419, -5.0229456 48.43920342, -5.02288872 48.43922253, -5.02283176 48.43924152, -5.02277471 48.43926039, -5.02271756 48.43927914, -5.02266033 48.43929777, -5.02260301 48.43931628, -5.02254561 48.43933468, -5.02248811 48.43935295, -5.02243054 48.4393711, -5.02237287 48.43938913, -5.02231512 48.43940704, -5.02225729 48.43942483, -5.02219937 48.4394425, -5.02214137 48.43946005, -5.02208329 48.43947747, -5.02202512 48.43949478, -5.02196688 48.43951196, -5.02190855 48.43952902, -5.02185014 48.43954596, -5.02179166 48.43956278, -5.02173309 48.43957947, -5.02167444 48.43959605, -5.02161572 48.4396125, -5.02155692 48.43962882, -5.02149804 48.43964502, -5.02143909 48.43966111, -5.02138006 48.43967706, -5.02132096 48.4396929, -5.02126178 48.4397086, -5.02120253 48.43972419, -5.0211432 48.43973965, -5.0210838 48.43975499, -5.02102433 48.4397702, -5.02096479 48.43978529, -5.02090517 48.43980026, -5.02084549 48.4398151, -5.02078574 48.43982981, -5.02072591 48.4398444, -5.02066602 48.43985887, -5.02060606 48.43987321, -5.02054604 48.43988742, -5.02048594 48.43990151, -5.02042578 48.43991547, -5.02036556 48.43992931, -5.02030527 48.43994302, -5.02024491 48.43995661, -5.02018449 48.43997006, -5.02012401 48.4399834, -5.02006346 48.4399966, -5.02000286 48.44000968, -5.01994219 48.44002263, -5.01988146 48.44003546, -5.01982067 48.44004816, -5.01975982 48.44006073, -5.01969891 48.44007317, -5.01963794 48.44008549, -5.01957692 48.44009768, -5.01951584 48.44010974, -5.0194547 48.44012167, -5.0193935 48.44013348, -5.01933225 48.44014515, -5.01927095 48.4401567, -5.01920959 48.44016812, -5.01914817 48.44017942, -5.01908671 48.44019058, -5.01902519 48.44020162, -5.01896362 48.44021253, -5.018902 48.4402233, -5.01884032 48.44023395, -5.0187786 48.44024447, -5.01871683 48.44025486, -5.01865501 48.44026513, -5.01859314 48.44027526, -5.01853122 48.44028526, -5.01846926 48.44029514, -5.01840725 48.44030488, -5.0183452 48.4403145, -5.0182831 48.44032398, -5.01822095 48.44033334, -5.01815876 48.44034256, -5.01809653 48.44035166, -5.01803426 48.44036062, -5.01797194 48.44036945, -5.01790958 48.44037816, -5.01784718 48.44038673, -5.01778474 48.44039518, -5.01772226 48.44040349, -5.01765975 48.44041167, -5.01759719 48.44041972, -5.0175346 48.44042764, -5.01747197 48.44043543, -5.0174093 48.44044309, -5.0173466 48.44045062, -5.01728386 48.44045801, -5.01722108 48.44046528, -5.01715828 48.44047241, -5.01709544 48.44047941, -5.01703256 48.44048629, -5.01696966 48.44049302, -5.01690672 48.44049963, -5.01684375 48.44050611, -5.01678075 48.44051245, -5.01671773 48.44051867, -5.01665467 48.44052475, -5.01659158 48.4405307, -5.01652847 48.44053651, -5.01646533 48.4405422, -5.01640216 48.44054775, -5.01633897 48.44055317, -5.01627575 48.44055846, -5.01621251 48.44056362, -5.01614924 48.44056864, -5.01608595 48.44057354, -5.01602264 48.4405783, -5.01595931 48.44058292, -5.01589595 48.44058742, -5.01583257 48.44059178, -5.01576917 48.44059601, -5.01570576 48.44060011, -5.01564232 48.44060407, -5.01557886 48.4406079, -5.01551539 48.4406116, -5.0154519 48.44061517, -5.0153884 48.4406186, -5.01532487 48.44062191, -5.01526134 48.44062507, -5.01519778 48.44062811, -5.01513422 48.44063101, -5.01507064 48.44063378, -5.01500704 48.44063642, -5.01494344 48.44063892, -5.01487982 48.44064129, -5.0148162 48.44064353, -5.01475256 48.44064564, -5.01468891 48.44064761, -5.01462526 48.44064945, -5.01456159 48.44065115, -5.01449792 48.44065272, -5.01443424 48.44065416, -5.01437056 48.44065547, -5.01430686 48.44065664, -5.01424317 48.44065768, -5.01417947 48.44065859, -5.01411576 48.44065936, -5.01405205 48.44066, -5.01398834 48.44066051, -5.01392463 48.44066088, -5.01386091 48.44066112, -5.0137972 48.44066123, -5.01373348 48.4406612, -5.01366977 48.44066104, -5.01360605 48.44066075, -5.01354234 48.44066033, -5.01347863 48.44065977, -5.01341492 48.44065907, -5.01335122 48.44065825, -5.01328752 48.44065729, -5.01322382 48.4406562, -5.01316013 48.44065497, -5.01309645 48.44065362, -5.01303277 48.44065212, -5.0129691 48.4406505, -5.01290544 48.44064874, -5.01284179 48.44064685, -5.01277815 48.44064483, -5.01271451 48.44064267, -5.01265089 48.44064038, -5.01258728 48.44063796, -5.01252368 48.4406354, -5.01246009 48.44063272, -5.01239652 48.44062989, -5.01233296 48.44062694, -5.01226941 48.44062385, -5.01220588 48.44062063, -5.01214236 48.44061728, -5.01207886 48.44061379, -5.01201538 48.44061018, -5.01195191 48.44060642, -5.01188846 48.44060254, -5.01182504 48.44059852, -5.01176163 48.44059437, -5.01169824 48.44059009, -5.01163487 48.44058568, -5.01157152 48.44058113, -5.01150819 48.44057645, -5.01144489 48.44057164, -5.01138161 48.4405667, -5.01131835 48.44056162, -5.01125512 48.44055641, -5.01119191 48.44055107, -5.01112872 48.4405456, -5.01106557 48.44053999, -5.01100244 48.44053426, -5.01093934 48.44052839, -5.01087626 48.44052239, -5.01081322 48.44051626, -5.0107502 48.44050999, -5.01068721 48.4405036, -5.01062426 48.44049707, -5.01056133 48.44049041, -5.01049844 48.44048362, -5.01043558 48.4404767, -5.01037275 48.44046964, -5.01030996 48.44046246, -5.0102472 48.44045514, -5.01018447 48.44044769, -5.01012178 48.44044011, -5.01005913 48.44043241, -5.00999651 48.44042456, -5.00993394 48.44041659, -5.00987139 48.44040849, -5.00980889 48.44040026, -5.00974643 48.44039189, -5.00968401 48.4403834, -5.00962162 48.44037478, -5.00955928 48.44036602, -5.00949698 48.44035714, -5.00943472 48.44034812, -5.00937251 48.44033897, -5.00931033 48.4403297, -5.00924821 48.44032029, -5.00918612 48.44031076, -5.00912409 48.44030109, -5.00906209 48.4402913, -5.00900015 48.44028137, -5.00893825 48.44027132, -5.0088764 48.44026114, -5.0088146 48.44025082, -5.00875285 48.44024038, -5.00869115 48.44022981, -5.00862949 48.44021911, -5.00856789 48.44020828, -5.00850634 48.44019732, -5.00844484 48.44018624, -5.0083834 48.44017502, -5.008322 48.44016368, -5.00826067 48.44015221, -5.00819938 48.44014061, -5.00813815 48.44012888, -5.00807698 48.44011703, -5.00801586 48.44010504, -5.0079548 48.44009293, -5.0078938 48.44008069, -5.00783286 48.44006833, -5.00777197 48.44005583, -5.00771114 48.44004321, -5.00765038 48.44003047, -5.00758967 48.44001759, -5.00752903 48.44000459, -5.00746844 48.43999146, -5.00740792 48.43997821, -5.00734747 48.43996482, -5.00728707 48.43995132, -5.00722674 48.43993768, -5.00716648 48.43992392, -5.00710628 48.43991004, -5.00704614 48.43989602, -5.00698607 48.43988189, -5.00692607 48.43986762, -5.00686614 48.43985323, -5.00680628 48.43983872, -5.00674648 48.43982408, -5.00668675 48.43980932, -5.0066271 48.43979443, -5.00656751 48.43977942, -5.006508 48.43976428, -5.00644855 48.43974902, -5.00638918 48.43973363, -5.00632989 48.43971812, -5.00627066 48.43970249, -5.00621151 48.43968673, -5.00615244 48.43967085, -5.00609344 48.43965484, -5.00603451 48.43963871, -5.00597567 48.43962246, -5.0059169 48.43960609, -5.0058582 48.43958959, -5.00579959 48.43957297, -5.00574105 48.43955623, -5.0056826 48.43953936, -5.00562422 48.43952238, -5.00556593 48.43950527, -5.00550771 48.43948804, -5.00544958 48.43947068, -5.00539153 48.43945321, -5.00533356 48.43943562, -5.00527568 48.4394179, -5.00521787 48.43940006, -5.00516016 48.43938211, -5.00510253 48.43936403, -5.00504498 48.43934583, -5.00498752 48.43932751, -5.00493015 48.43930907, -5.00487287 48.43929051, -5.00481567 48.43927183, -5.00475856 48.43925304, -5.00470154 48.43923412, -5.00464461 48.43921508, -5.00458777 48.43919593, -5.00453103 48.43917665, -5.00447437 48.43915726, -5.0044178 48.43913775, -5.00436133 48.43911812, -5.00430495 48.43909837, -5.00424866 48.43907851, -5.00419247 48.43905852, -5.00413637 48.43903842, -5.00408037 48.43901821, -5.00402447 48.43899787, -5.00396866 48.43897742, -5.00391294 48.43895685, -5.00385733 48.43893617, -5.00380181 48.43891537, -5.00374639 48.43889445, -5.00369107 48.43887342, -5.00363585 48.43885227, -5.00358073 48.43883101, -5.00352571 48.43880963, -5.00347079 48.43878814, -5.00341597 48.43876653, -5.00336126 48.43874481, -5.00330665 48.43872297, -5.00325214 48.43870102, -5.00319773 48.43867896, -5.00314343 48.43865678, -5.00308924 48.43863449, -5.00303515 48.43861209, -5.00298117 48.43858957, -5.00292729 48.43856694, -5.00287352 48.4385442, -5.00281986 48.43852134, -5.00276631 48.43849837, -5.00271286 48.43847529, -5.00265953 48.4384521, -5.0026063 48.4384288, -5.00255318 48.43840539, -5.00250018 48.43838186, -5.00244729 48.43835823, -5.00239451 48.43833448, -5.00234184 48.43831063, -5.00228928 48.43828666, -5.00223684 48.43826259, -5.00218451 48.4382384, -5.0021323 48.43821411, -5.0020802 48.4381897, -5.00202822 48.43816519, -5.00197635 48.43814057, -5.0019246 48.43811584, -5.00187296 48.438091, -5.00182145 48.43806606, -5.00177005 48.43804101, -5.00171877 48.43801585, -5.00166761 48.43799058, -5.00161657 48.43796521, -5.00156565 48.43793973, -5.00151485 48.43791414, -5.00146417 48.43788845, -5.00141361 48.43786265, -5.00136318 48.43783674, -5.00131286 48.43781073, -5.00126267 48.43778462, -5.00121261 48.4377584, -5.00116267 48.43773208, -5.00111285 48.43770565, -5.00106316 48.43767912, -5.00101359 48.43765248, -5.00096415 48.43762574, -5.00091484 48.4375989, -5.00086565 48.43757195, -5.00081659 48.4375449, -5.00076766 48.43751775, -5.00071886 48.4374905, -5.00067018 48.43746314, -5.00062164 48.43743569, -5.00057322 48.43740813, -5.00052494 48.43738047, -5.00047678 48.43735271, -5.00042876 48.43732485, -5.00038087 48.43729689, -5.00033311 48.43726883, -5.00028549 48.43724067, -5.000238 48.43721241, -5.00019064 48.43718405, -5.00014342 48.43715559, -5.00009633 48.43712703, -5.00004937 48.43709838, -5.00000255 48.43706963, -4.99995587 48.43704078, -4.99990932 48.43701183, -4.99986292 48.43698278, -4.99981664 48.43695364, -4.99977051 48.4369244, -4.99972451 48.43689507, -4.99967866 48.43686563, -4.99963294 48.43683611, -4.99958736 48.43680649, -4.99954192 48.43677677, -4.99949663 48.43674696, -4.99945147 48.43671705, -4.99940646 48.43668705, -4.99936158 48.43665695, -4.99931685 48.43662676, -4.99927226 48.43659648, -4.99922782 48.43656611, -4.99918352 48.43653564, -4.99913936 48.43650508, -4.99909535 48.43647443, -4.99905148 48.43644368, -4.99900776 48.43641284, -4.99896419 48.43638192, -4.99892076 48.4363509, -4.99887747 48.43631979, -4.99883434 48.43628859, -4.99879135 48.4362573, -4.99874851 48.43622592, -4.99870582 48.43619445, -4.99866328 48.4361629, -4.99862088 48.43613125, -4.99857864 48.43609951, -4.99853654 48.43606769, -4.9984946 48.43603578, -4.99845281 48.43600378, -4.99841117 48.4359717, -4.99836968 48.43593952, -4.99832834 48.43590726, -4.99828716 48.43587492, -4.99824612 48.43584249, -4.99820525 48.43580997, -4.99816452 48.43577737, -4.99812395 48.43574468, -4.99808353 48.43571191, -4.99804327 48.43567905, -4.99800317 48.43564611, -4.99796322 48.43561309, -4.99792343 48.43557998, -4.99788379 48.43554679, -4.99784431 48.43551352, -4.99780499 48.43548016, -4.99776582 48.43544672, -4.99772681 48.43541321, -4.99768796 48.4353796, -4.99764928 48.43534592, -4.99761075 48.43531216, -4.99757237 48.43527832, -4.99753416 48.43524439, -4.99749611 48.43521039, -4.99745822 48.43517631, -4.9974205 48.43514215, -4.99738293 48.43510791, -4.99734552 48.43507359, -4.99730828 48.43503919, -4.9972712 48.43500472, -4.99723428 48.43497017, -4.99719753 48.43493554, -4.99716094 48.43490084, -4.99712451 48.43486605, -4.99708825 48.4348312, -4.99705216 48.43479626, -4.99701622 48.43476126, -4.99698046 48.43472617, -4.99694486 48.43469101, -4.99690942 48.43465578, -4.99687416 48.43462048, -4.99683906 48.4345851, -4.99680412 48.43454964, -4.99676936 48.43451412, -4.99673476 48.43447852, -4.99670033 48.43444285, -4.99666607 48.43440711, -4.99663198 48.43437129, -4.99659805 48.43433541, -4.9965643 48.43429945, -4.99653072 48.43426343, -4.99649731 48.43422733, -4.99646406 48.43419117, -4.99643099 48.43415493, -4.99639809 48.43411863, -4.99636536 48.43408225, -4.99633281 48.43404581, -4.99630042 48.43400931, -4.99626821 48.43397273, -4.99623617 48.43393609, -4.99620431 48.43389938, -4.99617262 48.4338626, -4.9961411 48.43382576, -4.99610975 48.43378885, -4.99607858 48.43375187, -4.99604759 48.43371484, -4.99601677 48.43367773, -4.99598612 48.43364056, -4.99595566 48.43360333, -4.99592536 48.43356604, -4.99589525 48.43352868, -4.99586531 48.43349126, -4.99583554 48.43345378, -4.99580596 48.43341623, -4.99577655 48.43337862, -4.99574732 48.43334095, -4.99571826 48.43330322, -4.99568939 48.43326544, -4.99566069 48.43322758, -4.99563218 48.43318967, -4.99560384 48.43315171, -4.99557568 48.43311368, -4.9955477 48.43307559, -4.9955199 48.43303744, -4.99549228 48.43299924, -4.99546485 48.43296098, -4.99543759 48.43292266, -4.99541051 48.43288429, -4.99538362 48.43284586, -4.99535691 48.43280737, -4.99533037 48.43276883, -4.99530402 48.43273023, -4.99527786 48.43269157, -4.99525187 48.43265287, -4.99522607 48.4326141, -4.99520045 48.43257529, -4.99517502 48.43253642, -4.99514977 48.4324975, -4.9951247 48.43245852, -4.99509982 48.4324195, -4.99507512 48.43238042, -4.99505061 48.43234129, -4.99502628 48.43230211, -4.99500213 48.43226287, -4.99497817 48.43222359, -4.9949544 48.43218426, -4.99493081 48.43214488, -4.99490741 48.43210545, -4.9948842 48.43206597, -4.99486117 48.43202644, -4.99483833 48.43198687, -4.99481567 48.43194724, -4.99479321 48.43190757, -4.99477093 48.43186785, -4.99474883 48.43182809, -4.99472693 48.43178828, -4.99470521 48.43174843, -4.99468369 48.43170853, -4.99466235 48.43166858, -4.99464119 48.43162859, -4.99462023 48.43158856, -4.99459946 48.43154848, -4.99457888 48.43150836, -4.99455848 48.4314682, -4.99453828 48.43142799, -4.99451826 48.43138774, -4.99449844 48.43134745, -4.99447881 48.43130712, -4.99445936 48.43126675, -4.99444011 48.43122634, -4.99442105 48.43118589, -4.99440218 48.43114539, -4.9943835 48.43110486, -4.99436501 48.43106429, -4.99434671 48.43102368, -4.99432861 48.43098304, -4.9943107 48.43094235, -4.99429298 48.43090163, -4.99427545 48.43086087, -4.99425811 48.43082008, -4.99424097 48.43077925, -4.99422402 48.43073838, -4.99420726 48.43069748, -4.9941907 48.43065655, -4.99417433 48.43061557, -4.99415815 48.43057457, -4.99414217 48.43053353, -4.99412638 48.43049246, -4.99411079 48.43045135, -4.99409539 48.43041022, -4.99408018 48.43036905, -4.99406517 48.43032785, -4.99405035 48.43028662, -4.99403573 48.43024535, -4.9940213 48.43020406, -4.99400706 48.43016274, -4.99399303 48.43012139, -4.99397918 48.43008, -4.99396554 48.43003859, -4.99395208 48.42999716, -4.99393883 48.42995569, -4.99392577 48.4299142, -4.9939129 48.42987267, -4.99390024 48.42983113, -4.99388776 48.42978955, -4.99387549 48.42974795, -4.99386341 48.42970633, -4.99385153 48.42966468, -4.99383984 48.429623, -4.99382835 48.4295813, -4.99381706 48.42953958, -4.99380597 48.42949783, -4.99379507 48.42945606, -4.99378437 48.42941427, -4.99377386 48.42937246, -4.99376356 48.42933062, -4.99375345 48.42928876, -4.99374354 48.42924688, -4.99373383 48.42920499, -4.99372431 48.42916307, -4.99371499 48.42912113, -4.99370587 48.42907917, -4.99369695 48.42903719, -4.99368823 48.4289952, -4.99367971 48.42895318, -4.99367138 48.42891115, -4.99366325 48.42886911, -4.99365532 48.42882704, -4.99364759 48.42878496, -4.99364006 48.42874286, -4.99363273 48.42870075, -4.99362559 48.42865862, -4.99361866 48.42861648, -4.99361192 48.42857432, -4.99360539 48.42853215)))" + val polygon = wktReader.read(multipolygonString) as MultiPolygon + val firstMission = + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + openBy = "KIM", + closedBy = "TRA", + facade = "NAMO", + observationsCacem = + "Remain vote several ok. Bring American play woman challenge. Throw low law positive seven.", + startDateTimeUtc = + ZonedDateTime.parse("2022-03-21T12:11:13Z"), + endDateTimeUtc = null, + geom = polygon, + isClosed = false, + isDeleted = false, + envActions = listOf(), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10002, + administration = "DDTM", + isArchived = false, + name = "DML 2A", + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 3, + controlUnitId = + 10002, + name = + "Semi-rigide 1", + ), + LegacyControlUnitResourceEntity( + id = 4, + controlUnitId = + 10002, + name = + "Semi-rigide 2", + ), + LegacyControlUnitResourceEntity( + id = 5, + controlUnitId = + 10002, + name = + "Voiture", + ), + ), + ), + ), + isGeometryComputedFromControls = false, + ), ) - assertThat(missions).hasSize(18) + val mission = jpaMissionRepository.findFullMissionById(10) + + assertThat(mission).isEqualTo(firstMission) } @Test @Transactional - fun `findAll Should return filtered missions when status is set to CLOSED or UPCOMING`() { + fun `findById Should return specified mission and associated env actions and associated envActionReportingIds`() { // When - val missions = + val missionDTO = jpaMissionRepository.findFullMissionById(34) + assertThat(missionDTO.mission.id).isEqualTo(34) + assertThat(missionDTO.mission.envActions).hasSize(2) + assertThat( + missionDTO.envActionsAttachedToReportingIds?.get(0)?.first, + ) + .isEqualTo(UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807")) + assertThat(missionDTO.envActionsAttachedToReportingIds?.get(0)?.second).isEqualTo(listOf(6)) + } + + @Test + @Transactional + fun `findByIds() should find the matching missions`() { + val foundMissions = jpaMissionRepository.findByIds(listOf(50, 51, 52)) + + assertThat(foundMissions).hasSize(3) + } + + @Test + @Transactional + fun `save should create a new mission`() { + // Given + val existingMissions = jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), missionTypes = null, + missionStatuses = null, seaFronts = null, - missionStatuses = listOf("CLOSED", "UPCOMING"), pageable = Pageable.unpaged(), ) - assertThat(missions).hasSize(25) - } - @Test - @Transactional - fun `findAll with pagenumber and pagesize Should return subset of missions`() { + assertThat(existingMissions).hasSize(21) + + val wktReader = WKTReader() + + val multipolygonString = + "MULTIPOLYGON(((-2.7335 47.6078, -2.7335 47.8452, -3.6297 47.8452, -3.6297 47.6078, -2.7335 47.6078)))" + val polygon = wktReader.read(multipolygonString) as MultiPolygon + + val multipointString = "MULTIPOINT((49.354105 -0.427455))" + val point = wktReader.read(multipointString) as MultiPoint + + val noteObservations = "Quelqu'un aurait vu quelque chose quelque part à un certain moment." + + val newMission = + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + envActions = + listOf( + EnvActionControlEntity( + id = + UUID.fromString( + "33310163-4e22-4d3d-b585-dac4431eb4b5", + ), + facade = "Facade 1", + controlPlanSubThemes = listOf( + EnvActionControlPlanSubThemeEntity( + subThemeId = 1, + subTheme = "Sub theme 1", + theme = "Theme 1", + tags = listOf("Tag 1", "Tag 2"), + ), + ), + department = "Department 1", + geom = point, + vehicleType = VehicleTypeEnum.VEHICLE_LAND, + isAdministrativeControl = true, + isComplianceWithWaterRegulationsControl = true, + isSafetyEquipmentAndStandardsComplianceControl = + true, + isSeafarersControl = true, + ), + EnvActionSurveillanceEntity( + id = + UUID.fromString( + "a6c4bd17-eb45-4504-ab15-7a18ea714a10", + ), + facade = "Facade 2", + department = "Department 2", + geom = polygon, + ), + EnvActionNoteEntity( + id = + UUID.fromString( + "126ded89-2dc0-4c77-9bf2-49f86b9a71a1", + ), + observations = noteObservations, + ), + ), + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10121, + name = "PAM Jeanne Barret", + administration = "DIRM / DM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 8, + controlUnitId = 10121, + name = "PAM Jeanne Barret", + ), + ), + ), + ), + isGeometryComputedFromControls = false, + ) + // When + val newMissionCreated = jpaMissionRepository.save(newMission) + + // Then + assertThat(newMissionCreated.mission.controlUnits).hasSize(1) + assertThat(newMissionCreated.mission.controlUnits.first().id).isEqualTo(10121) + assertThat(newMissionCreated.mission.controlUnits.first().name) + .isEqualTo("PAM Jeanne Barret") + assertThat(newMissionCreated.mission.controlUnits.first().administration) + .isEqualTo("DIRM / DM") + assertThat(newMissionCreated.mission.controlUnits.first().resources).hasSize(1) + assertThat(newMissionCreated.mission.controlUnits.first().resources.first().id).isEqualTo(8) + assertThat(newMissionCreated.mission.controlUnits.first().resources.first().controlUnitId) + .isEqualTo(10121) + assertThat(newMissionCreated.mission.controlUnits.first().resources.first().name) + .isEqualTo("PAM Jeanne Barret") + assertThat(newMissionCreated.mission.envActions).hasSize(3) + assertThat(newMissionCreated.mission.envActions?.first()?.facade).isEqualTo("Facade 1") + assertThat(newMissionCreated.mission.envActions?.first()?.department) + .isEqualTo("Department 1") + assertThat(newMissionCreated.mission.envActions?.get(1)?.facade).isEqualTo("Facade 2") + assertThat(newMissionCreated.mission.envActions?.get(1)?.department) + .isEqualTo("Department 2") + assertThat( + (newMissionCreated.mission.envActions?.get(2) as EnvActionNoteEntity) + .observations, + ) + .isEqualTo( + noteObservations, + ) + val missions = jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), missionTypes = null, missionStatuses = null, seaFronts = null, - pageable = PageRequest.of(1, 10), + pageable = Pageable.unpaged(), ) - assertThat(missions).hasSize(10) + + assertThat(missions).hasSize(22) } @Test @Transactional - fun `findAll should filter missions based on MissionSources`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = null, - missionSources = + fun `save should update mission resources`() { + // Given + val newMission = + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = listOf( - MissionSourceEnum.MONITORFISH, - MissionSourceEnum.POSEIDON_CACEM, - MissionSourceEnum.POSEIDON_CNSP, + LegacyControlUnitEntity( + id = 10004, + name = "DPM – DDTM 35", + administration = "DDTM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 8, + controlUnitId = 10004, + name = "PAM Jeanne Barret", + ), + ), + ), ), - pageable = Pageable.unpaged(), + isGeometryComputedFromControls = false, ) - assertThat(missions).hasSize(3) - } + jpaMissionRepository.save(newMission) - @Test - @Transactional - fun `findById Should return specified mission`() { // When - val wktReader = WKTReader() - val multipolygonString = - "MULTIPOLYGON (((-4.99360539 48.42853215, -4.99359905 48.42848997, -4.99359291 48.42844777, -4.99358697 48.42840556, -4.99358123 48.42836334, -4.99357569 48.4283211, -4.99357035 48.42827886, -4.9935652 48.4282366, -4.99356026 48.42819434, -4.99355552 48.42815206, -4.99355097 48.42810977, -4.99354663 48.42806748, -4.99354249 48.42802517, -4.99353854 48.42798286, -4.9935348 48.42794054, -4.99353125 48.42789821, -4.99352791 48.42785587, -4.99352476 48.42781353, -4.99352182 48.42777118, -4.99351907 48.42772882, -4.99351653 48.42768646, -4.99351418 48.4276441, -4.99351203 48.42760173, -4.99351009 48.42755935, -4.99350834 48.42751697, -4.9935068 48.42747459, -4.99350545 48.42743221, -4.99350431 48.42738982, -4.99350336 48.42734743, -4.99350262 48.42730504, -4.99350207 48.42726264, -4.99350173 48.42722025, -4.99350158 48.42717785, -4.99350164 48.42713546, -4.99350189 48.42709307, -4.99350235 48.42705067, -4.99350301 48.42700828, -4.99350386 48.42696589, -4.99350492 48.4269235, -4.99350617 48.42688111, -4.99350763 48.42683873, -4.99350929 48.42679635, -4.99351114 48.42675397, -4.9935132 48.4267116, -4.99351545 48.42666923, -4.99351791 48.42662687, -4.99352057 48.42658451, -4.99352342 48.42654216, -4.99352648 48.42649981, -4.99352973 48.42645747, -4.99353319 48.42641514, -4.99353685 48.42637282, -4.9935407 48.4263305, -4.99354476 48.42628819, -4.99354901 48.42624589, -4.99355346 48.4262036, -4.99355812 48.42616132, -4.99356297 48.42611905, -4.99356802 48.42607679, -4.99357328 48.42603454, -4.99357873 48.4259923, -4.99358438 48.42595007, -4.99359023 48.42590785, -4.99359628 48.42586565, -4.99360253 48.42582346, -4.99360898 48.42578128, -4.99361562 48.42573912, -4.99362247 48.42569697, -4.99362951 48.42565484, -4.99363676 48.42561272, -4.9936442 48.42557061, -4.99365184 48.42552853, -4.99365968 48.42548645, -4.99366772 48.4254444, -4.99367596 48.42540236, -4.99368439 48.42536034, -4.99369302 48.42531833, -4.99370186 48.42527635, -4.99371089 48.42523438, -4.99372011 48.42519243, -4.99372954 48.42515051, -4.99373916 48.4251086, -4.99374898 48.42506671, -4.993759 48.42502484, -4.99376922 48.424983, -4.99377963 48.42494117, -4.99379024 48.42489937, -4.99380105 48.42485759, -4.99381206 48.42481583, -4.99382326 48.4247741, -4.99383466 48.42473239, -4.99384626 48.4246907, -4.99385805 48.42464904, -4.99387004 48.42460741, -4.99388223 48.42456579, -4.99389461 48.42452421, -4.99390719 48.42448265, -4.99391996 48.42444111, -4.99393293 48.42439961, -4.9939461 48.42435813, -4.99395946 48.42431668, -4.99397302 48.42427525, -4.99398677 48.42423386, -4.99400072 48.42419249, -4.99401487 48.42415116, -4.9940292 48.42410985, -4.99404374 48.42406857, -4.99405847 48.42402733, -4.99407339 48.42398611, -4.99408851 48.42394493, -4.99410382 48.42390378, -4.99411932 48.42386266, -4.99413502 48.42382157, -4.99415092 48.42378052, -4.994167 48.4237395, -4.99418328 48.42369851, -4.99419976 48.42365756, -4.99421643 48.42361664, -4.99423329 48.42357576, -4.99425034 48.42353491, -4.99426759 48.4234941, -4.99428502 48.42345333, -4.99430265 48.42341259, -4.99432048 48.42337189, -4.99433849 48.42333122, -4.9943567 48.4232906, -4.9943751 48.42325001, -4.99439369 48.42320946, -4.99441247 48.42316895, -4.99443144 48.42312848, -4.9944506 48.42308805, -4.99446996 48.42304766, -4.9944895 48.42300731, -4.99450924 48.422967, -4.99452916 48.42292673, -4.99454928 48.42288651, -4.99456958 48.42284633, -4.99459007 48.42280619, -4.99461076 48.42276609, -4.99463163 48.42272603, -4.99465269 48.42268602, -4.99467394 48.42264606, -4.99469538 48.42260614, -4.99471701 48.42256626, -4.99473882 48.42252643, -4.99476082 48.42248665, -4.99478301 48.42244691, -4.99480539 48.42240721, -4.99482796 48.42236757, -4.99485071 48.42232797, -4.99487365 48.42228842, -4.99489677 48.42224892, -4.99492008 48.42220947, -4.99494358 48.42217006, -4.99496727 48.42213071, -4.99499113 48.4220914, -4.99501519 48.42205215, -4.99503943 48.42201294, -4.99506385 48.42197379, -4.99508846 48.42193469, -4.99511326 48.42189563, -4.99513823 48.42185664, -4.99516339 48.42181769, -4.99518874 48.4217788, -4.99521427 48.42173995, -4.99523998 48.42170117, -4.99526587 48.42166243, -4.99529195 48.42162376, -4.99531821 48.42158513, -4.99534465 48.42154656, -4.99537128 48.42150805, -4.99539808 48.42146959, -4.99542507 48.42143119, -4.99545224 48.42139285, -4.99547959 48.42135456, -4.99550711 48.42131633, -4.99553482 48.42127816, -4.99556271 48.42124004, -4.99559078 48.42120199, -4.99561903 48.42116399, -4.99564746 48.42112605, -4.99567606 48.42108817, -4.99570485 48.42105035, -4.99573381 48.4210126, -4.99576295 48.4209749, -4.99579227 48.42093726, -4.99582177 48.42089969, -4.99585144 48.42086218, -4.99588129 48.42082473, -4.99591132 48.42078734, -4.99594152 48.42075001, -4.9959719 48.42071275, -4.99600246 48.42067555, -4.99603319 48.42063842, -4.9960641 48.42060135, -4.99609518 48.42056435, -4.99612643 48.42052741, -4.99615786 48.42049053, -4.99618946 48.42045372, -4.99622124 48.42041698, -4.99625319 48.42038031, -4.99628531 48.4203437, -4.9963176 48.42030716, -4.99635007 48.42027069, -4.99638271 48.42023428, -4.99641552 48.42019794, -4.9964485 48.42016168, -4.99648166 48.42012548, -4.99651498 48.42008935, -4.99654847 48.42005329, -4.99658214 48.4200173, -4.99661597 48.41998138, -4.99664997 48.41994553, -4.99668415 48.41990976, -4.99671849 48.41987405, -4.996753 48.41983842, -4.99678767 48.41980286, -4.99682252 48.41976737, -4.99685753 48.41973196, -4.99689271 48.41969662, -4.99692805 48.41966135, -4.99696356 48.41962616, -4.99699924 48.41959104, -4.99703508 48.41955599, -4.99707109 48.41952102, -4.99710726 48.41948613, -4.9971436 48.41945131, -4.9971801 48.41941657, -4.99721677 48.4193819, -4.9972536 48.41934732, -4.99729059 48.4193128, -4.99732774 48.41927837, -4.99736506 48.41924402, -4.99740254 48.41920974, -4.99744018 48.41917554, -4.99747798 48.41914142, -4.99751594 48.41910738, -4.99755406 48.41907342, -4.99759234 48.41903953, -4.99763079 48.41900573, -4.99766939 48.41897201, -4.99770815 48.41893837, -4.99774707 48.41890481, -4.99778614 48.41887133, -4.99782538 48.41883794, -4.99786477 48.41880463, -4.99790432 48.4187714, -4.99794402 48.41873825, -4.99798388 48.41870518, -4.9980239 48.4186722, -4.99806408 48.4186393, -4.9981044 48.41860649, -4.99814489 48.41857376, -4.99818552 48.41854112, -4.99822631 48.41850856, -4.99826726 48.41847609, -4.99830835 48.4184437, -4.9983496 48.4184114, -4.99839101 48.41837918, -4.99843256 48.41834705, -4.99847426 48.41831501, -4.99851612 48.41828306, -4.99855813 48.41825119, -4.99860028 48.41821941, -4.99864259 48.41818772, -4.99868504 48.41815612, -4.99872765 48.41812461, -4.9987704 48.41809319, -4.9988133 48.41806185, -4.99885635 48.41803061, -4.99889955 48.41799946, -4.99894289 48.41796839, -4.99898638 48.41793742, -4.99903001 48.41790654, -4.99907379 48.41787575, -4.99911772 48.41784505, -4.99916179 48.41781444, -4.999206 48.41778393, -4.99925036 48.41775351, -4.99929486 48.41772318, -4.99933951 48.41769294, -4.99938429 48.4176628, -4.99942922 48.41763276, -4.99947429 48.4176028, -4.9995195 48.41757294, -4.99956485 48.41754318, -4.99961035 48.41751351, -4.99965598 48.41748393, -4.99970175 48.41745445, -4.99974766 48.41742507, -4.99979371 48.41739578, -4.99983989 48.41736659, -4.99988622 48.4173375, -4.99993268 48.4173085, -4.99997927 48.4172796, -5.00002601 48.4172508, -5.00007288 48.4172221, -5.00011988 48.41719349, -5.00016702 48.41716498, -5.00021429 48.41713657, -5.0002617 48.41710826, -5.00030924 48.41708005, -5.00035691 48.41705194, -5.00040472 48.41702393, -5.00045266 48.41699602, -5.00050072 48.41696821, -5.00054892 48.4169405, -5.00059725 48.41691289, -5.00064571 48.41688538, -5.0006943 48.41685797, -5.00074302 48.41683067, -5.00079187 48.41680346, -5.00084085 48.41677636, -5.00088995 48.41674937, -5.00093918 48.41672247, -5.00098854 48.41669568, -5.00103802 48.41666899, -5.00108763 48.4166424, -5.00113736 48.41661592, -5.00118722 48.41658954, -5.0012372 48.41656327, -5.00128731 48.4165371, -5.00133754 48.41651104, -5.00138789 48.41648508, -5.00143837 48.41645923, -5.00148896 48.41643348, -5.00153968 48.41640784, -5.00159052 48.4163823, -5.00164148 48.41635688, -5.00169256 48.41633155, -5.00174375 48.41630634, -5.00179507 48.41628123, -5.0018465 48.41625623, -5.00189805 48.41623134, -5.00194972 48.41620655, -5.00200151 48.41618187, -5.00205341 48.41615731, -5.00210543 48.41613285, -5.00215756 48.4161085, -5.00220981 48.41608425, -5.00226217 48.41606012, -5.00231465 48.4160361, -5.00236723 48.41601219, -5.00241993 48.41598838, -5.00247275 48.41596469, -5.00252567 48.41594111, -5.00257871 48.41591764, -5.00263185 48.41589428, -5.00268511 48.41587103, -5.00273847 48.41584789, -5.00279195 48.41582486, -5.00284553 48.41580195, -5.00289922 48.41577915, -5.00295301 48.41575646, -5.00300692 48.41573388, -5.00306093 48.41571142, -5.00311504 48.41568907, -5.00316927 48.41566683, -5.00322359 48.4156447, -5.00327802 48.41562269, -5.00333255 48.4156008, -5.00338719 48.41557901, -5.00344193 48.41555735, -5.00349677 48.41553579, -5.00355171 48.41551435, -5.00360676 48.41549303, -5.0036619 48.41547182, -5.00371714 48.41545073, -5.00377249 48.41542975, -5.00382793 48.41540889, -5.00388347 48.41538814, -5.0039391 48.41536751, -5.00399484 48.415347, -5.00405067 48.4153266, -5.00410659 48.41530632, -5.00416261 48.41528616, -5.00421873 48.41526611, -5.00427494 48.41524619, -5.00433125 48.41522638, -5.00438764 48.41520668, -5.00444413 48.41518711, -5.00450072 48.41516765, -5.00455739 48.41514831, -5.00461416 48.41512909, -5.00467101 48.41510999, -5.00472796 48.41509101, -5.00478499 48.41507215, -5.00484211 48.41505341, -5.00489932 48.41503478, -5.00495662 48.41501628, -5.00501401 48.4149979, -5.00507148 48.41497963, -5.00512904 48.41496149, -5.00518668 48.41494347, -5.00524441 48.41492556, -5.00530222 48.41490778, -5.00536012 48.41489012, -5.0054181 48.41487258, -5.00547616 48.41485516, -5.0055343 48.41483786, -5.00559252 48.41482069, -5.00565083 48.41480364, -5.00570921 48.4147867, -5.00576768 48.4147699, -5.00582622 48.41475321, -5.00588485 48.41473664, -5.00594355 48.4147202, -5.00600232 48.41470388, -5.00606118 48.41468769, -5.00612011 48.41467161, -5.00617911 48.41465566, -5.00623819 48.41463984, -5.00629735 48.41462414, -5.00635658 48.41460856, -5.00641588 48.4145931, -5.00647525 48.41457777, -5.0065347 48.41456257, -5.00659422 48.41454748, -5.00665381 48.41453253, -5.00671347 48.41451769, -5.0067732 48.41450298, -5.00683299 48.4144884, -5.00689286 48.41447394, -5.00695279 48.41445961, -5.0070128 48.4144454, -5.00707286 48.41443132, -5.007133 48.41441736, -5.0071932 48.41440353, -5.00725346 48.41438983, -5.00731379 48.41437625, -5.00737419 48.4143628, -5.00743464 48.41434947, -5.00749516 48.41433627, -5.00755574 48.4143232, -5.00761638 48.41431025, -5.00767709 48.41429743, -5.00773785 48.41428474, -5.00779867 48.41427218, -5.00785955 48.41425974, -5.00792049 48.41424743, -5.00798149 48.41423525, -5.00804255 48.41422319, -5.00810366 48.41421126, -5.00816482 48.41419946, -5.00822605 48.41418779, -5.00828732 48.41417625, -5.00834866 48.41416483, -5.00841004 48.41415354, -5.00847148 48.41414238, -5.00853297 48.41413135, -5.00859451 48.41412045, -5.0086561 48.41410968, -5.00871775 48.41409903, -5.00877944 48.41408852, -5.00884119 48.41407813, -5.00890298 48.41406787, -5.00896482 48.41405775, -5.0090267 48.41404775, -5.00908864 48.41403788, -5.00915062 48.41402814, -5.00921264 48.41401853, -5.00927471 48.41400905, -5.00933683 48.4139997, -5.00939899 48.41399048, -5.00946119 48.41398139, -5.00952344 48.41397243, -5.00958572 48.4139636, -5.00964805 48.4139549, -5.00971042 48.41394633, -5.00977283 48.41393789, -5.00983528 48.41392958, -5.00989777 48.4139214, -5.00996029 48.41391335, -5.01002285 48.41390544, -5.01008545 48.41389765, -5.01014809 48.41389, -5.01021076 48.41388247, -5.01027347 48.41387508, -5.01033621 48.41386782, -5.01039899 48.41386069, -5.0104618 48.41385369, -5.01052464 48.41384682, -5.01058752 48.41384009, -5.01065042 48.41383348, -5.01071336 48.41382701, -5.01077633 48.41382067, -5.01083932 48.41381446, -5.01090235 48.41380838, -5.0109654 48.41380243, -5.01102848 48.41379662, -5.01109159 48.41379094, -5.01115473 48.41378539, -5.01121789 48.41377997, -5.01128107 48.41377468, -5.01134429 48.41376953, -5.01140752 48.41376451, -5.01147078 48.41375962, -5.01153406 48.41375486, -5.01159736 48.41375023, -5.01166069 48.41374574, -5.01172403 48.41374138, -5.0117874 48.41373715, -5.01185078 48.41373306, -5.01191419 48.41372909, -5.01197761 48.41372526, -5.01204105 48.41372157, -5.01210451 48.413718, -5.01216798 48.41371457, -5.01223147 48.41371127, -5.01229498 48.4137081, -5.0123585 48.41370507, -5.01242203 48.41370217, -5.01248558 48.4136994, -5.01254914 48.41369676, -5.01261271 48.41369426, -5.0126763 48.41369189, -5.01273989 48.41368965, -5.0128035 48.41368755, -5.01286711 48.41368558, -5.01293073 48.41368374, -5.01299437 48.41368204, -5.013058 48.41368047, -5.01312165 48.41367903, -5.0131853 48.41367772, -5.01324896 48.41367655, -5.01331263 48.41367551, -5.0133763 48.41367461, -5.01343997 48.41367383, -5.01350364 48.41367319, -5.01356732 48.41367269, -5.013631 48.41367231, -5.01369469 48.41367207, -5.01375837 48.41367197, -5.01382205 48.41367199, -5.01388573 48.41367215, -5.01394942 48.41367244, -5.0140131 48.41367287, -5.01407677 48.41367343, -5.01414045 48.41367412, -5.01420412 48.41367494, -5.01426779 48.4136759, -5.01433145 48.41367699, -5.01439511 48.41367822, -5.01445876 48.41367957, -5.0145224 48.41368106, -5.01458604 48.41368269, -5.01464966 48.41368444, -5.01471328 48.41368633, -5.0147769 48.41368836, -5.0148405 48.41369051, -5.01490409 48.4136928, -5.01496767 48.41369522, -5.01503123 48.41369778, -5.01509479 48.41370046, -5.01515833 48.41370328, -5.01522186 48.41370624, -5.01528537 48.41370932, -5.01534887 48.41371254, -5.01541236 48.41371589, -5.01547582 48.41371938, -5.01553928 48.41372299, -5.01560271 48.41372674, -5.01566613 48.41373062, -5.01572952 48.41373464, -5.0157929 48.41373879, -5.01585626 48.41374307, -5.0159196 48.41374748, -5.01598291 48.41375202, -5.01604621 48.4137567, -5.01610948 48.41376151, -5.01617273 48.41376645, -5.01623595 48.41377152, -5.01629915 48.41377673, -5.01636233 48.41378207, -5.01642548 48.41378754, -5.01648861 48.41379314, -5.01655171 48.41379887, -5.01661478 48.41380474, -5.01667782 48.41381074, -5.01674083 48.41381687, -5.01680382 48.41382313, -5.01686677 48.41382952, -5.0169297 48.41383605, -5.01699259 48.4138427, -5.01705545 48.41384949, -5.01711828 48.41385641, -5.01718108 48.41386346, -5.01724384 48.41387064, -5.01730657 48.41387795, -5.01736927 48.4138854, -5.01743192 48.41389297, -5.01749455 48.41390068, -5.01755713 48.41390851, -5.01761968 48.41391648, -5.01768219 48.41392458, -5.01774467 48.41393281, -5.0178071 48.41394117, -5.01786949 48.41394966, -5.01793185 48.41395828, -5.01799416 48.41396703, -5.01805643 48.41397591, -5.01811866 48.41398492, -5.01818084 48.41399406, -5.01824298 48.41400333, -5.01830508 48.41401274, -5.01836714 48.41402227, -5.01842914 48.41403193, -5.01849111 48.41404172, -5.01855302 48.41405164, -5.01861489 48.41406169, -5.01867671 48.41407186, -5.01873848 48.41408217, -5.01880021 48.41409261, -5.01886188 48.41410317, -5.01892351 48.41411387, -5.01898508 48.41412469, -5.0190466 48.41413565, -5.01910807 48.41414673, -5.01916949 48.41415794, -5.01923085 48.41416927, -5.01929216 48.41418074, -5.01935342 48.41419233, -5.01941462 48.41420405, -5.01947577 48.4142159, -5.01953686 48.41422788, -5.01959789 48.41423999, -5.01965886 48.41425222, -5.01971978 48.41426458, -5.01978064 48.41427707, -5.01984144 48.41428968, -5.01990218 48.41430242, -5.01996286 48.41431529, -5.02002348 48.41432829, -5.02008403 48.41434141, -5.02014453 48.41435466, -5.02020496 48.41436804, -5.02026533 48.41438154, -5.02032563 48.41439517, -5.02038587 48.41440892, -5.02044604 48.4144228, -5.02050615 48.4144368, -5.0205662 48.41445093, -5.02062617 48.41446519, -5.02068608 48.41447957, -5.02074592 48.41449408, -5.02080569 48.41450871, -5.02086539 48.41452347, -5.02092502 48.41453835, -5.02098458 48.41455336, -5.02104407 48.41456849, -5.02110349 48.41458374, -5.02116284 48.41459912, -5.02122211 48.41461463, -5.02128131 48.41463025, -5.02134044 48.414646, -5.02139949 48.41466188, -5.02145847 48.41467788, -5.02151737 48.414694, -5.02157619 48.41471024, -5.02163494 48.41472661, -5.02169361 48.4147431, -5.0217522 48.41475971, -5.02181071 48.41477644, -5.02186915 48.4147933, -5.0219275 48.41481028, -5.02198577 48.41482738, -5.02204397 48.4148446, -5.02210208 48.41486195, -5.02216011 48.41487941, -5.02221805 48.414897, -5.02227592 48.41491471, -5.0223337 48.41493254, -5.02239139 48.41495049, -5.022449 48.41496856, -5.02250653 48.41498675, -5.02256396 48.41500506, -5.02262132 48.41502349, -5.02267858 48.41504204, -5.02273576 48.41506071, -5.02279285 48.4150795, -5.02284984 48.41509841, -5.02290675 48.41511744, -5.02296357 48.41513659, -5.0230203 48.41515585, -5.02307694 48.41517524, -5.02313349 48.41519474, -5.02318994 48.41521436, -5.0232463 48.4152341, -5.02330257 48.41525395, -5.02335875 48.41527393, -5.02341483 48.41529402, -5.02347081 48.41531423, -5.0235267 48.41533455, -5.02358249 48.41535499, -5.02363819 48.41537555, -5.02369379 48.41539623, -5.02374929 48.41541702, -5.02380469 48.41543793, -5.02385999 48.41545895, -5.0239152 48.41548009, -5.0239703 48.41550134, -5.02402531 48.41552271, -5.02408021 48.41554419, -5.02413501 48.41556579, -5.02418971 48.41558751, -5.02424431 48.41560933, -5.0242988 48.41563127, -5.02435319 48.41565333, -5.02440747 48.4156755, -5.02446165 48.41569778, -5.02451573 48.41572017, -5.0245697 48.41574268, -5.02462356 48.4157653, -5.02467731 48.41578804, -5.02473096 48.41581088, -5.0247845 48.41583384, -5.02483793 48.41585691, -5.02489126 48.41588009, -5.02494447 48.41590338, -5.02499757 48.41592679, -5.02505056 48.4159503, -5.02510344 48.41597393, -5.02515621 48.41599766, -5.02520887 48.41602151, -5.02526141 48.41604547, -5.02531384 48.41606953, -5.02536616 48.41609371, -5.02541836 48.41611799, -5.02547045 48.41614238, -5.02552242 48.41616689, -5.02557428 48.4161915, -5.02562602 48.41621622, -5.02567764 48.41624104, -5.02572915 48.41626598, -5.02578054 48.41629102, -5.02583181 48.41631617, -5.02588296 48.41634143, -5.02593399 48.41636679, -5.0259849 48.41639226, -5.02603569 48.41641784, -5.02608636 48.41644352, -5.02613691 48.41646931, -5.02618734 48.4164952, -5.02623764 48.4165212, -5.02628782 48.41654731, -5.02633788 48.41657352, -5.02638782 48.41659983, -5.02643763 48.41662625, -5.02648731 48.41665277, -5.02653687 48.4166794, -5.02658631 48.41670613, -5.02663561 48.41673296, -5.02668479 48.41675989, -5.02673385 48.41678693, -5.02678277 48.41681407, -5.02683157 48.41684132, -5.02688024 48.41686866, -5.02692878 48.41689611, -5.02697719 48.41692366, -5.02702547 48.4169513, -5.02707362 48.41697905, -5.02712163 48.4170069, -5.02716952 48.41703485, -5.02721727 48.4170629, -5.02726489 48.41709105, -5.02731238 48.4171193, -5.02735974 48.41714765, -5.02740696 48.4171761, -5.02745404 48.41720465, -5.027501 48.41723329, -5.02754781 48.41726203, -5.02759449 48.41729087, -5.02764104 48.41731981, -5.02768744 48.41734885, -5.02773371 48.41737798, -5.02777985 48.41740721, -5.02782584 48.41743653, -5.02787169 48.41746595, -5.02791741 48.41749547, -5.02796299 48.41752508, -5.02800843 48.41755479, -5.02805372 48.41758459, -5.02809888 48.41761449, -5.02814389 48.41764448, -5.02818877 48.41767456, -5.0282335 48.41770474, -5.02827809 48.41773501, -5.02832253 48.41776538, -5.02836683 48.41779583, -5.02841099 48.41782638, -5.028455 48.41785703, -5.02849887 48.41788776, -5.0285426 48.41791859, -5.02858617 48.4179495, -5.02862961 48.41798051, -5.02867289 48.41801161, -5.02871603 48.4180428, -5.02875902 48.41807408, -5.02880186 48.41810545, -5.02884456 48.4181369, -5.02888711 48.41816845, -5.0289295 48.41820009, -5.02897175 48.41823181, -5.02901385 48.41826362, -5.0290558 48.41829552, -5.02909759 48.41832751, -5.02913924 48.41835959, -5.02918073 48.41839175, -5.02922208 48.418424, -5.02926327 48.41845633, -5.0293043 48.41848876, -5.02934519 48.41852126, -5.02938592 48.41855385, -5.02942649 48.41858653, -5.02946692 48.41861929, -5.02950718 48.41865214, -5.0295473 48.41868507, -5.02958725 48.41871808, -5.02962705 48.41875118, -5.0296667 48.41878436, -5.02970619 48.41881762, -5.02974552 48.41885097, -5.02978469 48.4188844, -5.0298237 48.41891791, -5.02986256 48.4189515, -5.02990126 48.41898517, -5.0299398 48.41901892, -5.02997818 48.41905275, -5.0300164 48.41908667, -5.03005446 48.41912066, -5.03009236 48.41915473, -5.0301301 48.41918888, -5.03016767 48.41922311, -5.03020509 48.41925742, -5.03024234 48.41929181, -5.03027943 48.41932627, -5.03031636 48.41936081, -5.03035312 48.41939543, -5.03038972 48.41943013, -5.03042616 48.4194649, -5.03046243 48.41949974, -5.03049854 48.41953467, -5.03053449 48.41956967, -5.03057026 48.41960474, -5.03060588 48.41963989, -5.03064132 48.41967511, -5.0306766 48.41971041, -5.03071172 48.41974578, -5.03074666 48.41978122, -5.03078144 48.41981674, -5.03081605 48.41985233, -5.0308505 48.41988799, -5.03088477 48.41992372, -5.03091888 48.41995952, -5.03095281 48.4199954, -5.03098658 48.42003134, -5.03102018 48.42006736, -5.03105361 48.42010345, -5.03108686 48.4201396, -5.03111995 48.42017583, -5.03115287 48.42021212, -5.03118561 48.42024849, -5.03121818 48.42028492, -5.03125058 48.42032142, -5.03128281 48.42035799, -5.03131486 48.42039462, -5.03134675 48.42043132, -5.03137845 48.42046809, -5.03140999 48.42050492, -5.03144135 48.42054182, -5.03147254 48.42057879, -5.03150355 48.42061582, -5.03153439 48.42065291, -5.03156505 48.42069007, -5.03159553 48.42072729, -5.03162584 48.42076458, -5.03165598 48.42080193, -5.03168594 48.42083934, -5.03171572 48.42087682, -5.03174532 48.42091435, -5.03177475 48.42095195, -5.031804 48.42098961, -5.03183307 48.42102733, -5.03186197 48.42106511, -5.03189068 48.42110295, -5.03191922 48.42114086, -5.03194758 48.42117882, -5.03197575 48.42121684, -5.03200375 48.42125492, -5.03203157 48.42129305, -5.03205921 48.42133125, -5.03208667 48.4213695, -5.03211395 48.42140781, -5.03214105 48.42144618, -5.03216796 48.4214846, -5.0321947 48.42152308, -5.03222125 48.42156162, -5.03224762 48.42160021, -5.03227381 48.42163885, -5.03229981 48.42167755, -5.03232564 48.42171631, -5.03235128 48.42175511, -5.03237673 48.42179398, -5.03240201 48.42183289, -5.0324271 48.42187186, -5.032452 48.42191088, -5.03247672 48.42194995, -5.03250126 48.42198907, -5.03252561 48.42202824, -5.03254978 48.42206747, -5.03257376 48.42210674, -5.03259756 48.42214607, -5.03262117 48.42218544, -5.0326446 48.42222487, -5.03266783 48.42226434, -5.03269089 48.42230386, -5.03271375 48.42234343, -5.03273643 48.42238304, -5.03275892 48.42242271, -5.03278123 48.42246242, -5.03280334 48.42250217, -5.03282527 48.42254198, -5.03284702 48.42258183, -5.03286857 48.42262172, -5.03288993 48.42266166, -5.03291111 48.42270164, -5.0329321 48.42274167, -5.0329529 48.42278174, -5.03297351 48.42282185, -5.03299393 48.42286201, -5.03301416 48.42290221, -5.0330342 48.42294245, -5.03305405 48.42298274, -5.03307371 48.42302306, -5.03309318 48.42306343, -5.03311246 48.42310383, -5.03313155 48.42314428, -5.03315044 48.42318476, -5.03316915 48.42322529, -5.03318766 48.42326585, -5.03320599 48.42330646, -5.03322412 48.4233471, -5.03324206 48.42338777, -5.03325981 48.42342849, -5.03327736 48.42346924, -5.03329473 48.42351003, -5.0333119 48.42355086, -5.03332888 48.42359172, -5.03334566 48.42363261, -5.03336225 48.42367355, -5.03337865 48.42371451, -5.03339486 48.42375551, -5.03341087 48.42379654, -5.03342669 48.42383761, -5.03344231 48.42387871, -5.03345774 48.42391984, -5.03347298 48.42396101, -5.03348802 48.4240022, -5.03350286 48.42404343, -5.03351752 48.42408469, -5.03353197 48.42412598, -5.03354624 48.42416729, -5.0335603 48.42420864, -5.03357418 48.42425002, -5.03358785 48.42429142, -5.03360133 48.42433286, -5.03361462 48.42437432, -5.03362771 48.42441581, -5.0336406 48.42445733, -5.0336533 48.42449887, -5.0336658 48.42454044, -5.03367811 48.42458204, -5.03369022 48.42462366, -5.03370213 48.42466531, -5.03371385 48.42470698, -5.03372537 48.42474867, -5.03373669 48.42479039, -5.03374782 48.42483214, -5.03375875 48.4248739, -5.03376948 48.42491569, -5.03378001 48.4249575, -5.03379035 48.42499933, -5.03380049 48.42504119, -5.03381043 48.42508306, -5.03382017 48.42512496, -5.03382972 48.42516687, -5.03383907 48.42520881, -5.03384822 48.42525077, -5.03385717 48.42529274, -5.03386593 48.42533473, -5.03387448 48.42537674, -5.03388284 48.42541877, -5.033891 48.42546082, -5.03389896 48.42550288, -5.03390672 48.42554496, -5.03391428 48.42558705, -5.03392165 48.42562916, -5.03392882 48.42567129, -5.03393578 48.42571343, -5.03394255 48.42575558, -5.03394912 48.42579775, -5.03395549 48.42583993, -5.03396166 48.42588213, -5.03396763 48.42592434, -5.03397341 48.42596656, -5.03397898 48.42600879, -5.03398435 48.42605103, -5.03398953 48.42609329, -5.0339945 48.42613555, -5.03399928 48.42617783, -5.03400385 48.42622011, -5.03400823 48.42626241, -5.03401241 48.42630471, -5.03401638 48.42634702, -5.03402016 48.42638934, -5.03402374 48.42643167, -5.03402712 48.42647401, -5.03403029 48.42651635, -5.03403327 48.4265587, -5.03403605 48.42660105, -5.03403863 48.42664341, -5.03404101 48.42668577, -5.03404318 48.42672814, -5.03404516 48.42677052, -5.03404694 48.4268129, -5.03404852 48.42685528, -5.0340499 48.42689766, -5.03405107 48.42694005, -5.03405205 48.42698244, -5.03405283 48.42702483, -5.03405341 48.42706722, -5.03405379 48.42710962, -5.03405396 48.42715201, -5.03405394 48.42719441, -5.03405372 48.4272368, -5.03405329 48.4272792, -5.03405267 48.42732159, -5.03405185 48.42736398, -5.03405082 48.42740637, -5.0340496 48.42744876, -5.03404818 48.42749114, -5.03404655 48.42753352, -5.03404473 48.4275759, -5.03404271 48.42761827, -5.03404048 48.42766064, -5.03403806 48.427703, -5.03403544 48.42774536, -5.03403261 48.42778772, -5.03402959 48.42783006, -5.03402637 48.4278724, -5.03402294 48.42791474, -5.03401932 48.42795706, -5.0340155 48.42799938, -5.03401148 48.42804169, -5.03400725 48.42808399, -5.03400283 48.42812628, -5.03399821 48.42816857, -5.03399339 48.42821084, -5.03398837 48.4282531, -5.03398315 48.42829535, -5.03397773 48.4283376, -5.03397211 48.42837982, -5.03396629 48.42842204, -5.03396027 48.42846425, -5.03395406 48.42850644, -5.03394764 48.42854862, -5.03394103 48.42859078, -5.03393421 48.42863294, -5.0339272 48.42867507, -5.03391999 48.42871719, -5.03391258 48.4287593, -5.03390497 48.42880139, -5.03389716 48.42884347, -5.03388915 48.42888552, -5.03388095 48.42892757, -5.03387254 48.42896959, -5.03386394 48.4290116, -5.03385514 48.42905358, -5.03384614 48.42909555, -5.03383695 48.4291375, -5.03382755 48.42917944, -5.03381796 48.42922135, -5.03380817 48.42926324, -5.03379818 48.42930511, -5.033788 48.42934696, -5.03377761 48.42938878, -5.03376703 48.42943059, -5.03375626 48.42947237, -5.03374528 48.42951413, -5.03373411 48.42955587, -5.03372274 48.42959759, -5.03371117 48.42963928, -5.03369941 48.42968094, -5.03368745 48.42972258, -5.0336753 48.4297642, -5.03366294 48.42980579, -5.0336504 48.42984735, -5.03363765 48.42988889, -5.03362471 48.4299304, -5.03361157 48.42997188, -5.03359824 48.43001334, -5.03358471 48.43005477, -5.03357099 48.43009617, -5.03355707 48.43013754, -5.03354296 48.43017888, -5.03352865 48.43022019, -5.03351414 48.43026147, -5.03349944 48.43030272, -5.03348455 48.43034394, -5.03346946 48.43038513, -5.03345418 48.43042628, -5.0334387 48.43046741, -5.03342303 48.4305085, -5.03340717 48.43054956, -5.03339111 48.43059058, -5.03337486 48.43063158, -5.03335841 48.43067253, -5.03334177 48.43071346, -5.03332494 48.43075434, -5.03330791 48.4307952, -5.0332907 48.43083601, -5.03327329 48.43087679, -5.03325568 48.43091754, -5.03323789 48.43095824, -5.0332199 48.43099891, -5.03320172 48.43103954, -5.03318335 48.43108014, -5.03316479 48.43112069, -5.03314603 48.43116121, -5.03312709 48.43120169, -5.03310795 48.43124212, -5.03308862 48.43128252, -5.03306911 48.43132287, -5.0330494 48.43136319, -5.0330295 48.43140346, -5.03300941 48.43144369, -5.03298913 48.43148388, -5.03296866 48.43152403, -5.03294801 48.43156413, -5.03292716 48.43160419, -5.03290612 48.43164421, -5.0328849 48.43168418, -5.03286349 48.43172411, -5.03284189 48.43176399, -5.0328201 48.43180383, -5.03279812 48.43184362, -5.03277595 48.43188337, -5.0327536 48.43192307, -5.03273106 48.43196272, -5.03270833 48.43200232, -5.03268542 48.43204188, -5.03266232 48.43208139, -5.03263903 48.43212085, -5.03261555 48.43216026, -5.03259189 48.43219962, -5.03256805 48.43223894, -5.03254402 48.4322782, -5.0325198 48.43231741, -5.0324954 48.43235657, -5.03247081 48.43239568, -5.03244604 48.43243474, -5.03242109 48.43247375, -5.03239595 48.4325127, -5.03237063 48.4325516, -5.03234512 48.43259045, -5.03231943 48.43262925, -5.03229356 48.43266799, -5.0322675 48.43270667, -5.03224126 48.4327453, -5.03221484 48.43278388, -5.03218824 48.4328224, -5.03216146 48.43286087, -5.03213449 48.43289928, -5.03210735 48.43293763, -5.03208002 48.43297593, -5.03205251 48.43301416, -5.03202482 48.43305235, -5.03199695 48.43309047, -5.0319689 48.43312853, -5.03194067 48.43316654, -5.03191227 48.43320448, -5.03188368 48.43324237, -5.03185491 48.4332802, -5.03182597 48.43331796, -5.03179685 48.43335567, -5.03176755 48.43339331, -5.03173807 48.4334309, -5.03170841 48.43346842, -5.03167858 48.43350588, -5.03164857 48.43354327, -5.03161839 48.43358061, -5.03158802 48.43361788, -5.03155749 48.43365508, -5.03152677 48.43369223, -5.03149589 48.4337293, -5.03146482 48.43376632, -5.03143358 48.43380327, -5.03140217 48.43384015, -5.03137059 48.43387697, -5.03133883 48.43391372, -5.03130689 48.4339504, -5.03127479 48.43398702, -5.03124251 48.43402357, -5.03121006 48.43406005, -5.03117743 48.43409646, -5.03114464 48.43413281, -5.03111167 48.43416909, -5.03107853 48.4342053, -5.03104522 48.43424143, -5.03101175 48.4342775, -5.0309781 48.4343135, -5.03094428 48.43434943, -5.03091029 48.43438529, -5.03087613 48.43442107, -5.0308418 48.43445679, -5.03080731 48.43449243, -5.03077264 48.434528, -5.03073781 48.43456349, -5.03070281 48.43459892, -5.03066765 48.43463427, -5.03063232 48.43466955, -5.03059682 48.43470475, -5.03056115 48.43473988, -5.03052532 48.43477493, -5.03048933 48.43480991, -5.03045316 48.43484482, -5.03041684 48.43487964, -5.03038035 48.4349144, -5.03034369 48.43494907, -5.03030688 48.43498367, -5.0302699 48.43501819, -5.03023275 48.43505263, -5.03019545 48.435087, -5.03015798 48.43512129, -5.03012035 48.4351555, -5.03008256 48.43518963, -5.0300446 48.43522368, -5.03000649 48.43525765, -5.02996822 48.43529154, -5.02992979 48.43532535, -5.02989119 48.43535908, -5.02985244 48.43539273, -5.02981353 48.4354263, -5.02977446 48.43545979, -5.02973524 48.4354932, -5.02969585 48.43552652, -5.02965631 48.43555976, -5.02961661 48.43559292, -5.02957676 48.43562599, -5.02953675 48.43565898, -5.02949658 48.43569189, -5.02945626 48.43572472, -5.02941578 48.43575745, -5.02937515 48.43579011, -5.02933437 48.43582268, -5.02929343 48.43585516, -5.02925234 48.43588756, -5.02921109 48.43591987, -5.0291697 48.4359521, -5.02912815 48.43598423, -5.02908645 48.43601629, -5.0290446 48.43604825, -5.02900259 48.43608013, -5.02896044 48.43611192, -5.02891814 48.43614362, -5.02887569 48.43617523, -5.02883309 48.43620675, -5.02879034 48.43623818, -5.02874744 48.43626953, -5.02870439 48.43630078, -5.0286612 48.43633195, -5.02861786 48.43636302, -5.02857437 48.436394, -5.02853074 48.4364249, -5.02848696 48.4364557, -5.02844304 48.4364864, -5.02839897 48.43651702, -5.02835476 48.43654755, -5.0283104 48.43657798, -5.0282659 48.43660832, -5.02822126 48.43663856, -5.02817647 48.43666871, -5.02813154 48.43669877, -5.02808647 48.43672874, -5.02804126 48.43675861, -5.02799591 48.43678838, -5.02795041 48.43681806, -5.02790478 48.43684765, -5.02785901 48.43687714, -5.0278131 48.43690653, -5.02776705 48.43693583, -5.02772086 48.43696503, -5.02767454 48.43699413, -5.02762807 48.43702314, -5.02758147 48.43705205, -5.02753474 48.43708086, -5.02748787 48.43710958, -5.02744086 48.4371382, -5.02739372 48.43716671, -5.02734644 48.43719513, -5.02729903 48.43722345, -5.02725149 48.43725167, -5.02720381 48.4372798, -5.027156 48.43730782, -5.02710806 48.43733574, -5.02705998 48.43736356, -5.02701178 48.43739128, -5.02696344 48.4374189, -5.02691498 48.43744642, -5.02686638 48.43747384, -5.02681766 48.43750115, -5.02676881 48.43752836, -5.02671983 48.43755548, -5.02667072 48.43758248, -5.02662148 48.43760939, -5.02657212 48.43763619, -5.02652263 48.43766289, -5.02647301 48.43768949, -5.02642327 48.43771598, -5.0263734 48.43774237, -5.02632341 48.43776865, -5.0262733 48.43779483, -5.02622306 48.4378209, -5.0261727 48.43784687, -5.02612222 48.43787273, -5.02607161 48.43789849, -5.02602089 48.43792414, -5.02597004 48.43794969, -5.02591907 48.43797513, -5.02586798 48.43800046, -5.02581678 48.43802568, -5.02576545 48.4380508, -5.02571401 48.43807581, -5.02566245 48.43810072, -5.02561077 48.43812551, -5.02555897 48.4381502, -5.02550706 48.43817478, -5.02545503 48.43819924, -5.02540289 48.43822361, -5.02535063 48.43824786, -5.02529825 48.438272, -5.02524577 48.43829603, -5.02519317 48.43831995, -5.02514045 48.43834377, -5.02508763 48.43836747, -5.02503469 48.43839106, -5.02498165 48.43841454, -5.02492849 48.43843791, -5.02487522 48.43846117, -5.02482184 48.43848432, -5.02476835 48.43850735, -5.02471476 48.43853028, -5.02466105 48.43855309, -5.02460724 48.43857579, -5.02455332 48.43859837, -5.0244993 48.43862085, -5.02444517 48.43864321, -5.02439093 48.43866546, -5.02433659 48.43868759, -5.02428215 48.43870961, -5.0242276 48.43873151, -5.02417295 48.43875331, -5.02411819 48.43877498, -5.02406334 48.43879655, -5.02400838 48.43881799, -5.02395332 48.43883933, -5.02389816 48.43886055, -5.0238429 48.43888165, -5.02378754 48.43890263, -5.02373208 48.43892351, -5.02367653 48.43894426, -5.02362087 48.4389649, -5.02356512 48.43898542, -5.02350927 48.43900583, -5.02345333 48.43902611, -5.02339729 48.43904629, -5.02334115 48.43906634, -5.02328493 48.43908628, -5.0232286 48.4391061, -5.02317219 48.4391258, -5.02311568 48.43914538, -5.02305908 48.43916485, -5.02300238 48.43918419, -5.0229456 48.43920342, -5.02288872 48.43922253, -5.02283176 48.43924152, -5.02277471 48.43926039, -5.02271756 48.43927914, -5.02266033 48.43929777, -5.02260301 48.43931628, -5.02254561 48.43933468, -5.02248811 48.43935295, -5.02243054 48.4393711, -5.02237287 48.43938913, -5.02231512 48.43940704, -5.02225729 48.43942483, -5.02219937 48.4394425, -5.02214137 48.43946005, -5.02208329 48.43947747, -5.02202512 48.43949478, -5.02196688 48.43951196, -5.02190855 48.43952902, -5.02185014 48.43954596, -5.02179166 48.43956278, -5.02173309 48.43957947, -5.02167444 48.43959605, -5.02161572 48.4396125, -5.02155692 48.43962882, -5.02149804 48.43964502, -5.02143909 48.43966111, -5.02138006 48.43967706, -5.02132096 48.4396929, -5.02126178 48.4397086, -5.02120253 48.43972419, -5.0211432 48.43973965, -5.0210838 48.43975499, -5.02102433 48.4397702, -5.02096479 48.43978529, -5.02090517 48.43980026, -5.02084549 48.4398151, -5.02078574 48.43982981, -5.02072591 48.4398444, -5.02066602 48.43985887, -5.02060606 48.43987321, -5.02054604 48.43988742, -5.02048594 48.43990151, -5.02042578 48.43991547, -5.02036556 48.43992931, -5.02030527 48.43994302, -5.02024491 48.43995661, -5.02018449 48.43997006, -5.02012401 48.4399834, -5.02006346 48.4399966, -5.02000286 48.44000968, -5.01994219 48.44002263, -5.01988146 48.44003546, -5.01982067 48.44004816, -5.01975982 48.44006073, -5.01969891 48.44007317, -5.01963794 48.44008549, -5.01957692 48.44009768, -5.01951584 48.44010974, -5.0194547 48.44012167, -5.0193935 48.44013348, -5.01933225 48.44014515, -5.01927095 48.4401567, -5.01920959 48.44016812, -5.01914817 48.44017942, -5.01908671 48.44019058, -5.01902519 48.44020162, -5.01896362 48.44021253, -5.018902 48.4402233, -5.01884032 48.44023395, -5.0187786 48.44024447, -5.01871683 48.44025486, -5.01865501 48.44026513, -5.01859314 48.44027526, -5.01853122 48.44028526, -5.01846926 48.44029514, -5.01840725 48.44030488, -5.0183452 48.4403145, -5.0182831 48.44032398, -5.01822095 48.44033334, -5.01815876 48.44034256, -5.01809653 48.44035166, -5.01803426 48.44036062, -5.01797194 48.44036945, -5.01790958 48.44037816, -5.01784718 48.44038673, -5.01778474 48.44039518, -5.01772226 48.44040349, -5.01765975 48.44041167, -5.01759719 48.44041972, -5.0175346 48.44042764, -5.01747197 48.44043543, -5.0174093 48.44044309, -5.0173466 48.44045062, -5.01728386 48.44045801, -5.01722108 48.44046528, -5.01715828 48.44047241, -5.01709544 48.44047941, -5.01703256 48.44048629, -5.01696966 48.44049302, -5.01690672 48.44049963, -5.01684375 48.44050611, -5.01678075 48.44051245, -5.01671773 48.44051867, -5.01665467 48.44052475, -5.01659158 48.4405307, -5.01652847 48.44053651, -5.01646533 48.4405422, -5.01640216 48.44054775, -5.01633897 48.44055317, -5.01627575 48.44055846, -5.01621251 48.44056362, -5.01614924 48.44056864, -5.01608595 48.44057354, -5.01602264 48.4405783, -5.01595931 48.44058292, -5.01589595 48.44058742, -5.01583257 48.44059178, -5.01576917 48.44059601, -5.01570576 48.44060011, -5.01564232 48.44060407, -5.01557886 48.4406079, -5.01551539 48.4406116, -5.0154519 48.44061517, -5.0153884 48.4406186, -5.01532487 48.44062191, -5.01526134 48.44062507, -5.01519778 48.44062811, -5.01513422 48.44063101, -5.01507064 48.44063378, -5.01500704 48.44063642, -5.01494344 48.44063892, -5.01487982 48.44064129, -5.0148162 48.44064353, -5.01475256 48.44064564, -5.01468891 48.44064761, -5.01462526 48.44064945, -5.01456159 48.44065115, -5.01449792 48.44065272, -5.01443424 48.44065416, -5.01437056 48.44065547, -5.01430686 48.44065664, -5.01424317 48.44065768, -5.01417947 48.44065859, -5.01411576 48.44065936, -5.01405205 48.44066, -5.01398834 48.44066051, -5.01392463 48.44066088, -5.01386091 48.44066112, -5.0137972 48.44066123, -5.01373348 48.4406612, -5.01366977 48.44066104, -5.01360605 48.44066075, -5.01354234 48.44066033, -5.01347863 48.44065977, -5.01341492 48.44065907, -5.01335122 48.44065825, -5.01328752 48.44065729, -5.01322382 48.4406562, -5.01316013 48.44065497, -5.01309645 48.44065362, -5.01303277 48.44065212, -5.0129691 48.4406505, -5.01290544 48.44064874, -5.01284179 48.44064685, -5.01277815 48.44064483, -5.01271451 48.44064267, -5.01265089 48.44064038, -5.01258728 48.44063796, -5.01252368 48.4406354, -5.01246009 48.44063272, -5.01239652 48.44062989, -5.01233296 48.44062694, -5.01226941 48.44062385, -5.01220588 48.44062063, -5.01214236 48.44061728, -5.01207886 48.44061379, -5.01201538 48.44061018, -5.01195191 48.44060642, -5.01188846 48.44060254, -5.01182504 48.44059852, -5.01176163 48.44059437, -5.01169824 48.44059009, -5.01163487 48.44058568, -5.01157152 48.44058113, -5.01150819 48.44057645, -5.01144489 48.44057164, -5.01138161 48.4405667, -5.01131835 48.44056162, -5.01125512 48.44055641, -5.01119191 48.44055107, -5.01112872 48.4405456, -5.01106557 48.44053999, -5.01100244 48.44053426, -5.01093934 48.44052839, -5.01087626 48.44052239, -5.01081322 48.44051626, -5.0107502 48.44050999, -5.01068721 48.4405036, -5.01062426 48.44049707, -5.01056133 48.44049041, -5.01049844 48.44048362, -5.01043558 48.4404767, -5.01037275 48.44046964, -5.01030996 48.44046246, -5.0102472 48.44045514, -5.01018447 48.44044769, -5.01012178 48.44044011, -5.01005913 48.44043241, -5.00999651 48.44042456, -5.00993394 48.44041659, -5.00987139 48.44040849, -5.00980889 48.44040026, -5.00974643 48.44039189, -5.00968401 48.4403834, -5.00962162 48.44037478, -5.00955928 48.44036602, -5.00949698 48.44035714, -5.00943472 48.44034812, -5.00937251 48.44033897, -5.00931033 48.4403297, -5.00924821 48.44032029, -5.00918612 48.44031076, -5.00912409 48.44030109, -5.00906209 48.4402913, -5.00900015 48.44028137, -5.00893825 48.44027132, -5.0088764 48.44026114, -5.0088146 48.44025082, -5.00875285 48.44024038, -5.00869115 48.44022981, -5.00862949 48.44021911, -5.00856789 48.44020828, -5.00850634 48.44019732, -5.00844484 48.44018624, -5.0083834 48.44017502, -5.008322 48.44016368, -5.00826067 48.44015221, -5.00819938 48.44014061, -5.00813815 48.44012888, -5.00807698 48.44011703, -5.00801586 48.44010504, -5.0079548 48.44009293, -5.0078938 48.44008069, -5.00783286 48.44006833, -5.00777197 48.44005583, -5.00771114 48.44004321, -5.00765038 48.44003047, -5.00758967 48.44001759, -5.00752903 48.44000459, -5.00746844 48.43999146, -5.00740792 48.43997821, -5.00734747 48.43996482, -5.00728707 48.43995132, -5.00722674 48.43993768, -5.00716648 48.43992392, -5.00710628 48.43991004, -5.00704614 48.43989602, -5.00698607 48.43988189, -5.00692607 48.43986762, -5.00686614 48.43985323, -5.00680628 48.43983872, -5.00674648 48.43982408, -5.00668675 48.43980932, -5.0066271 48.43979443, -5.00656751 48.43977942, -5.006508 48.43976428, -5.00644855 48.43974902, -5.00638918 48.43973363, -5.00632989 48.43971812, -5.00627066 48.43970249, -5.00621151 48.43968673, -5.00615244 48.43967085, -5.00609344 48.43965484, -5.00603451 48.43963871, -5.00597567 48.43962246, -5.0059169 48.43960609, -5.0058582 48.43958959, -5.00579959 48.43957297, -5.00574105 48.43955623, -5.0056826 48.43953936, -5.00562422 48.43952238, -5.00556593 48.43950527, -5.00550771 48.43948804, -5.00544958 48.43947068, -5.00539153 48.43945321, -5.00533356 48.43943562, -5.00527568 48.4394179, -5.00521787 48.43940006, -5.00516016 48.43938211, -5.00510253 48.43936403, -5.00504498 48.43934583, -5.00498752 48.43932751, -5.00493015 48.43930907, -5.00487287 48.43929051, -5.00481567 48.43927183, -5.00475856 48.43925304, -5.00470154 48.43923412, -5.00464461 48.43921508, -5.00458777 48.43919593, -5.00453103 48.43917665, -5.00447437 48.43915726, -5.0044178 48.43913775, -5.00436133 48.43911812, -5.00430495 48.43909837, -5.00424866 48.43907851, -5.00419247 48.43905852, -5.00413637 48.43903842, -5.00408037 48.43901821, -5.00402447 48.43899787, -5.00396866 48.43897742, -5.00391294 48.43895685, -5.00385733 48.43893617, -5.00380181 48.43891537, -5.00374639 48.43889445, -5.00369107 48.43887342, -5.00363585 48.43885227, -5.00358073 48.43883101, -5.00352571 48.43880963, -5.00347079 48.43878814, -5.00341597 48.43876653, -5.00336126 48.43874481, -5.00330665 48.43872297, -5.00325214 48.43870102, -5.00319773 48.43867896, -5.00314343 48.43865678, -5.00308924 48.43863449, -5.00303515 48.43861209, -5.00298117 48.43858957, -5.00292729 48.43856694, -5.00287352 48.4385442, -5.00281986 48.43852134, -5.00276631 48.43849837, -5.00271286 48.43847529, -5.00265953 48.4384521, -5.0026063 48.4384288, -5.00255318 48.43840539, -5.00250018 48.43838186, -5.00244729 48.43835823, -5.00239451 48.43833448, -5.00234184 48.43831063, -5.00228928 48.43828666, -5.00223684 48.43826259, -5.00218451 48.4382384, -5.0021323 48.43821411, -5.0020802 48.4381897, -5.00202822 48.43816519, -5.00197635 48.43814057, -5.0019246 48.43811584, -5.00187296 48.438091, -5.00182145 48.43806606, -5.00177005 48.43804101, -5.00171877 48.43801585, -5.00166761 48.43799058, -5.00161657 48.43796521, -5.00156565 48.43793973, -5.00151485 48.43791414, -5.00146417 48.43788845, -5.00141361 48.43786265, -5.00136318 48.43783674, -5.00131286 48.43781073, -5.00126267 48.43778462, -5.00121261 48.4377584, -5.00116267 48.43773208, -5.00111285 48.43770565, -5.00106316 48.43767912, -5.00101359 48.43765248, -5.00096415 48.43762574, -5.00091484 48.4375989, -5.00086565 48.43757195, -5.00081659 48.4375449, -5.00076766 48.43751775, -5.00071886 48.4374905, -5.00067018 48.43746314, -5.00062164 48.43743569, -5.00057322 48.43740813, -5.00052494 48.43738047, -5.00047678 48.43735271, -5.00042876 48.43732485, -5.00038087 48.43729689, -5.00033311 48.43726883, -5.00028549 48.43724067, -5.000238 48.43721241, -5.00019064 48.43718405, -5.00014342 48.43715559, -5.00009633 48.43712703, -5.00004937 48.43709838, -5.00000255 48.43706963, -4.99995587 48.43704078, -4.99990932 48.43701183, -4.99986292 48.43698278, -4.99981664 48.43695364, -4.99977051 48.4369244, -4.99972451 48.43689507, -4.99967866 48.43686563, -4.99963294 48.43683611, -4.99958736 48.43680649, -4.99954192 48.43677677, -4.99949663 48.43674696, -4.99945147 48.43671705, -4.99940646 48.43668705, -4.99936158 48.43665695, -4.99931685 48.43662676, -4.99927226 48.43659648, -4.99922782 48.43656611, -4.99918352 48.43653564, -4.99913936 48.43650508, -4.99909535 48.43647443, -4.99905148 48.43644368, -4.99900776 48.43641284, -4.99896419 48.43638192, -4.99892076 48.4363509, -4.99887747 48.43631979, -4.99883434 48.43628859, -4.99879135 48.4362573, -4.99874851 48.43622592, -4.99870582 48.43619445, -4.99866328 48.4361629, -4.99862088 48.43613125, -4.99857864 48.43609951, -4.99853654 48.43606769, -4.9984946 48.43603578, -4.99845281 48.43600378, -4.99841117 48.4359717, -4.99836968 48.43593952, -4.99832834 48.43590726, -4.99828716 48.43587492, -4.99824612 48.43584249, -4.99820525 48.43580997, -4.99816452 48.43577737, -4.99812395 48.43574468, -4.99808353 48.43571191, -4.99804327 48.43567905, -4.99800317 48.43564611, -4.99796322 48.43561309, -4.99792343 48.43557998, -4.99788379 48.43554679, -4.99784431 48.43551352, -4.99780499 48.43548016, -4.99776582 48.43544672, -4.99772681 48.43541321, -4.99768796 48.4353796, -4.99764928 48.43534592, -4.99761075 48.43531216, -4.99757237 48.43527832, -4.99753416 48.43524439, -4.99749611 48.43521039, -4.99745822 48.43517631, -4.9974205 48.43514215, -4.99738293 48.43510791, -4.99734552 48.43507359, -4.99730828 48.43503919, -4.9972712 48.43500472, -4.99723428 48.43497017, -4.99719753 48.43493554, -4.99716094 48.43490084, -4.99712451 48.43486605, -4.99708825 48.4348312, -4.99705216 48.43479626, -4.99701622 48.43476126, -4.99698046 48.43472617, -4.99694486 48.43469101, -4.99690942 48.43465578, -4.99687416 48.43462048, -4.99683906 48.4345851, -4.99680412 48.43454964, -4.99676936 48.43451412, -4.99673476 48.43447852, -4.99670033 48.43444285, -4.99666607 48.43440711, -4.99663198 48.43437129, -4.99659805 48.43433541, -4.9965643 48.43429945, -4.99653072 48.43426343, -4.99649731 48.43422733, -4.99646406 48.43419117, -4.99643099 48.43415493, -4.99639809 48.43411863, -4.99636536 48.43408225, -4.99633281 48.43404581, -4.99630042 48.43400931, -4.99626821 48.43397273, -4.99623617 48.43393609, -4.99620431 48.43389938, -4.99617262 48.4338626, -4.9961411 48.43382576, -4.99610975 48.43378885, -4.99607858 48.43375187, -4.99604759 48.43371484, -4.99601677 48.43367773, -4.99598612 48.43364056, -4.99595566 48.43360333, -4.99592536 48.43356604, -4.99589525 48.43352868, -4.99586531 48.43349126, -4.99583554 48.43345378, -4.99580596 48.43341623, -4.99577655 48.43337862, -4.99574732 48.43334095, -4.99571826 48.43330322, -4.99568939 48.43326544, -4.99566069 48.43322758, -4.99563218 48.43318967, -4.99560384 48.43315171, -4.99557568 48.43311368, -4.9955477 48.43307559, -4.9955199 48.43303744, -4.99549228 48.43299924, -4.99546485 48.43296098, -4.99543759 48.43292266, -4.99541051 48.43288429, -4.99538362 48.43284586, -4.99535691 48.43280737, -4.99533037 48.43276883, -4.99530402 48.43273023, -4.99527786 48.43269157, -4.99525187 48.43265287, -4.99522607 48.4326141, -4.99520045 48.43257529, -4.99517502 48.43253642, -4.99514977 48.4324975, -4.9951247 48.43245852, -4.99509982 48.4324195, -4.99507512 48.43238042, -4.99505061 48.43234129, -4.99502628 48.43230211, -4.99500213 48.43226287, -4.99497817 48.43222359, -4.9949544 48.43218426, -4.99493081 48.43214488, -4.99490741 48.43210545, -4.9948842 48.43206597, -4.99486117 48.43202644, -4.99483833 48.43198687, -4.99481567 48.43194724, -4.99479321 48.43190757, -4.99477093 48.43186785, -4.99474883 48.43182809, -4.99472693 48.43178828, -4.99470521 48.43174843, -4.99468369 48.43170853, -4.99466235 48.43166858, -4.99464119 48.43162859, -4.99462023 48.43158856, -4.99459946 48.43154848, -4.99457888 48.43150836, -4.99455848 48.4314682, -4.99453828 48.43142799, -4.99451826 48.43138774, -4.99449844 48.43134745, -4.99447881 48.43130712, -4.99445936 48.43126675, -4.99444011 48.43122634, -4.99442105 48.43118589, -4.99440218 48.43114539, -4.9943835 48.43110486, -4.99436501 48.43106429, -4.99434671 48.43102368, -4.99432861 48.43098304, -4.9943107 48.43094235, -4.99429298 48.43090163, -4.99427545 48.43086087, -4.99425811 48.43082008, -4.99424097 48.43077925, -4.99422402 48.43073838, -4.99420726 48.43069748, -4.9941907 48.43065655, -4.99417433 48.43061557, -4.99415815 48.43057457, -4.99414217 48.43053353, -4.99412638 48.43049246, -4.99411079 48.43045135, -4.99409539 48.43041022, -4.99408018 48.43036905, -4.99406517 48.43032785, -4.99405035 48.43028662, -4.99403573 48.43024535, -4.9940213 48.43020406, -4.99400706 48.43016274, -4.99399303 48.43012139, -4.99397918 48.43008, -4.99396554 48.43003859, -4.99395208 48.42999716, -4.99393883 48.42995569, -4.99392577 48.4299142, -4.9939129 48.42987267, -4.99390024 48.42983113, -4.99388776 48.42978955, -4.99387549 48.42974795, -4.99386341 48.42970633, -4.99385153 48.42966468, -4.99383984 48.429623, -4.99382835 48.4295813, -4.99381706 48.42953958, -4.99380597 48.42949783, -4.99379507 48.42945606, -4.99378437 48.42941427, -4.99377386 48.42937246, -4.99376356 48.42933062, -4.99375345 48.42928876, -4.99374354 48.42924688, -4.99373383 48.42920499, -4.99372431 48.42916307, -4.99371499 48.42912113, -4.99370587 48.42907917, -4.99369695 48.42903719, -4.99368823 48.4289952, -4.99367971 48.42895318, -4.99367138 48.42891115, -4.99366325 48.42886911, -4.99365532 48.42882704, -4.99364759 48.42878496, -4.99364006 48.42874286, -4.99363273 48.42870075, -4.99362559 48.42865862, -4.99361866 48.42861648, -4.99361192 48.42857432, -4.99360539 48.42853215)))" - val polygon = wktReader.read(multipolygonString) as MultiPolygon - val firstMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - openBy = "KIM", - closedBy = "TRA", - facade = "NAMO", - observationsCacem = - "Remain vote several ok. Bring American play woman challenge. Throw low law positive seven.", - startDateTimeUtc = - ZonedDateTime.parse("2022-03-21T12:11:13Z"), - endDateTimeUtc = null, - geom = polygon, - isClosed = false, - isDeleted = false, - envActions = listOf(), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, + val newMissionUpdated = + jpaMissionRepository.save( + newMission.copy( controlUnits = listOf( LegacyControlUnitEntity( id = 10002, - administration = "DDTM", - isArchived = false, name = "DML 2A", + administration = "DIRM / DM", + isArchived = false, resources = listOf( LegacyControlUnitResourceEntity( @@ -659,64 +585,153 @@ class JpaMissionRepositoryITests : AbstractDBTests() { name = "Semi-rigide 1", ), - LegacyControlUnitResourceEntity( - id = 4, - controlUnitId = - 10002, - name = - "Semi-rigide 2", - ), LegacyControlUnitResourceEntity( id = 5, controlUnitId = 10002, - name = - "Voiture", + name = "Voiture", ), ), ), ), - isGeometryComputedFromControls = false, ), ) - val mission = jpaMissionRepository.findFullMissionById(10) - assertThat(mission).isEqualTo(firstMission) + // Then + assertThat(newMissionUpdated.mission.controlUnits).hasSize(1) + assertThat(newMissionUpdated.mission.controlUnits.first().id).isEqualTo(10002) + assertThat(newMissionUpdated.mission.controlUnits.first().name).isEqualTo("DML 2A") + assertThat(newMissionUpdated.mission.controlUnits.first().administration) + .isEqualTo("DIRM / DM") + assertThat(newMissionUpdated.mission.controlUnits.first().resources).hasSize(2) + assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().id).isEqualTo(3) + assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().controlUnitId) + .isEqualTo(10002) + assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().name) + .isEqualTo("Semi-rigide 1") + assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().id).isEqualTo(5) + assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().controlUnitId) + .isEqualTo(10002) + assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().name) + .isEqualTo("Voiture") + } + + @Test + @Transactional + fun `save should update existing mission with existing resources`() { + // Given + val mission = jpaMissionRepository.findById(25) + val newControlUnitResource = jpaControlUnitResourceRepository.findById(10) + val newControlUnit = + jpaControlUnitRepository.findById( + requireNotNull(newControlUnitResource.controlUnit.id), + ) + + val nextMission = + mission.copy( + controlUnits = + mission.controlUnits.plus( + LegacyControlUnitEntity( + id = requireNotNull(newControlUnit.controlUnit.id), + administration = newControlUnit.administration.name, + isArchived = newControlUnit.controlUnit.isArchived, + name = newControlUnit.controlUnit.name, + resources = + listOf( + newControlUnitResource + .toLegacyControlUnitResource(), + ), + contact = null, + ), + ), + ) + + val updatedMission = jpaMissionRepository.save(nextMission) + + assertThat(updatedMission.mission.controlUnits).hasSize(2) + assertThat(updatedMission.mission.controlUnits.first().id).isEqualTo(10002) + assertThat(updatedMission.mission.controlUnits.first().resources).hasSize(1) + assertThat(updatedMission.mission.controlUnits.first().resources.first().id).isEqualTo(3) + assertThat(updatedMission.mission.controlUnits.first().resources.first().controlUnitId) + .isEqualTo(10002) + assertThat(updatedMission.mission.controlUnits.last().id).isEqualTo(10018) + assertThat(updatedMission.mission.controlUnits.last().resources).hasSize(1) + assertThat(updatedMission.mission.controlUnits.last().resources.first().id).isEqualTo(10) + assertThat(updatedMission.mission.controlUnits.last().resources.first().controlUnitId) + .isEqualTo(10018) } @Test @Transactional - fun `findFullMissionById Should return specified mission and envActionReportingIds with multiple reportings attached`() { + fun `save should throw an exception When the resource id is not found`() { + // Given + val newMission = + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 5, + name = "DPM – DDTM 35", + administration = "DDTM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 123456, + controlUnitId = 5, + name = "PAM Jeanne Barret", + ), + ), + ), + ), + isGeometryComputedFromControls = false, + ) + // When - val missionDTO = jpaMissionRepository.findFullMissionById(53) - assertThat(missionDTO.mission.id).isEqualTo(53) - assertThat(missionDTO.mission.envActions).hasSize(3) - assertThat( - missionDTO.envActionsAttachedToReportingIds?.get(0)?.first, - ) - .isEqualTo(UUID.fromString("9969413b-b394-4db4-985f-b00743ffb833")) - assertThat(missionDTO.envActionsAttachedToReportingIds?.get(0)?.second) - .isEqualTo(listOf(11, 9)) - assertThat( - missionDTO.envActionsAttachedToReportingIds?.get(1)?.first, - ) - .isEqualTo(UUID.fromString("3480657f-7845-4eb4-aa06-07b174b1da45")) - assertThat(missionDTO.envActionsAttachedToReportingIds?.get(1)?.second) - .isEqualTo(listOf(10)) + val throwable = catchThrowable { jpaMissionRepository.save(newMission) } + + // Then + assertThat(throwable).isInstanceOf(InvalidDataAccessApiUsageException::class.java) } @Test @Transactional - fun `findById Should return specified mission and associated env actions and associated envActionReportingIds`() { + fun `save should throw an exception When the unit id is not found`() { + // Given + val newMission = + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 123456, + name = "PAM Jeanne Barret", + administration = "", + isArchived = false, + resources = listOf(), + ), + ), + isGeometryComputedFromControls = false, + ) + // When - val missionDTO = jpaMissionRepository.findFullMissionById(34) - assertThat(missionDTO.mission.id).isEqualTo(34) - assertThat(missionDTO.mission.envActions).hasSize(2) - assertThat( - missionDTO.envActionsAttachedToReportingIds?.get(0)?.first, - ) - .isEqualTo(UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807")) - assertThat(missionDTO.envActionsAttachedToReportingIds?.get(0)?.second).isEqualTo(listOf(6)) + val throwable = catchThrowable { jpaMissionRepository.save(newMission) } + + // Then + assertThat(throwable).isInstanceOf(DataIntegrityViolationException::class.java) } @Test @@ -745,14 +760,6 @@ class JpaMissionRepositoryITests : AbstractDBTests() { val controlAction = EnvActionControlEntity( id = UUID.randomUUID(), - themes = - listOf( - ThemeEntity( - theme = "5", - subThemes = listOf("4"), - protectedSpecies = listOf("5"), - ), - ), observations = "RAS", actionNumberOfControls = 12, actionTargetType = ActionTargetTypeEnum.VEHICLE, @@ -762,14 +769,6 @@ class JpaMissionRepositoryITests : AbstractDBTests() { val surveillanceAction = EnvActionSurveillanceEntity( id = UUID.randomUUID(), - themes = - listOf( - ThemeEntity( - theme = "6", - subThemes = listOf("7"), - protectedSpecies = listOf("8"), - ), - ), observations = "This is a surveillance action", ) val noteAction = @@ -898,40 +897,38 @@ class JpaMissionRepositoryITests : AbstractDBTests() { @Test @Transactional - fun `delete Should set the deleted flag as true`() { - // Given - val missionsList = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) - assertThat(missionsList).hasSize(21) - - // When - jpaMissionRepository.delete(3) - - // Then - val nextMissionList = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), + fun `save Should update subThemes of envActions`() { + val mission = jpaMissionRepository.findById(34) + val envAction = mission.envActions?.find { it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") } + assertThat(envAction?.controlPlanSubThemes?.size).isEqualTo(2) + val nextControlPlanSubThemes = listOf( + EnvActionControlPlanSubThemeEntity( + subThemeId = 7, + tags = listOf("Flore", "Oiseaux"), + ), + ) + val nextMission = mission.copy( + envActions = mission.envActions?.map { + if (it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") && it is EnvActionControlEntity) { + it.copy( + controlPlanSubThemes = nextControlPlanSubThemes, + ) + } else { + it + } + }, + ) + val updatedMission = jpaMissionRepository.save(nextMission) + val updatedControlPlanSubThemes = updatedMission.mission.envActions?.find { + it.id == UUID.fromString( + "b8007c8a-5135-4bc3-816f-c69c7b75d807", ) - assertThat(nextMissionList).hasSize(20) - } - - @Test - @Transactional - fun `findByIds() should find the matching missions`() { - val foundMissions = jpaMissionRepository.findByIds(listOf(50, 51, 52)) - - assertThat(foundMissions).hasSize(3) + }?.controlPlanSubThemes + assertThat( + updatedControlPlanSubThemes?.size, + ).isEqualTo(1) + assertThat( + updatedControlPlanSubThemes?.first()?.subThemeId, + ).isEqualTo(7) } } From 11d344a34711747001407bf681a946b0949cebce Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 12/53] add cache + optimize FetchType --- .../database/model/ControlPlanSubThemeModel.kt | 5 +++++ .../infrastructure/database/model/EnvActionModel.kt | 5 ++--- .../database/model/EnvActionsControlPlanSubThemeModel.kt | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt index 6545c8258..603ae73ec 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt @@ -12,10 +12,15 @@ import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne import jakarta.persistence.Table import org.hibernate.Hibernate +import org.hibernate.annotations.Cache +import org.hibernate.annotations.CacheConcurrencyStrategy import org.hibernate.annotations.Type @Entity @Table(name = "control_plan_subthemes") +@Cache( + usage = CacheConcurrencyStrategy.READ_WRITE, +) class ControlPlanSubThemeModel( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt index 229d067f1..1eae88521 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt @@ -70,7 +70,7 @@ class EnvActionModel( @Column(name = "department") val department: String? = null, - @ManyToOne(fetch = FetchType.EAGER, optional = false) + @ManyToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "mission_id") @JsonBackReference val mission: MissionModel, @@ -88,13 +88,12 @@ class EnvActionModel( val isSeafarersControl: Boolean? = null, @OneToMany( - fetch = FetchType.EAGER, + fetch = FetchType.LAZY, mappedBy = "attachedEnvAction", ) @JsonManagedReference val attachedReporting: List? = listOf(), - // @JoinColumn(name = "env_action_id") @OneToMany( fetch = FetchType.EAGER, cascade = [CascadeType.ALL], diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt index 32ae01d3f..f6d43d472 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt @@ -27,7 +27,7 @@ class EnvActionsControlPlanSubThemeModel( @JoinColumn(name = "env_action_id") val envAction: EnvActionModel? = null, - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.EAGER) @MapsId("subthemeId") @JoinColumn(name = "subtheme_id") val controlPlanSubTheme: ControlPlanSubThemeModel? = null, From 041480eb49cf92a801bcfa9d95d86b9d9aad58ba Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 13/53] add control_plan_tags & reportings_control_plan_sub_themes --- .../internal/V0.103__create_action_theme.sql | 120 +++++++++++++----- .../V666.10__insert_dummy_env_actions.sql | 4 +- 2 files changed, 87 insertions(+), 37 deletions(-) diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index 22bf84001..bb4f0cb25 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -8,28 +8,40 @@ CREATE TABLE control_plan_themes ( CREATE TABLE control_plan_subthemes ( id serial PRIMARY KEY, subtheme text, - allowed_tags text[], theme_id int REFERENCES control_plan_themes(id), year int ); CREATE INDEX idx_control_plan_subthemes_year ON control_plan_subthemes USING btree(year); + +CREATE TABLE control_plan_tags ( + id serial PRIMARY KEY, + tag text, + theme_id int REFERENCES control_plan_themes(id) +); + CREATE TABLE env_actions_control_plan_sub_themes ( env_action_id uuid, subtheme_id integer, - tags text[], foreign key (env_action_id) references env_actions(id), foreign key (subtheme_id) references control_plan_subthemes(id), primary key (env_action_id, subtheme_id) ); --- TODO: Décider s'il faut ajouter une contrainte sur les tags de env_actions_control_plan_sub_themes --- Si oui, il faudra probablement passer par un trigger --- (pas possible avec postgres de faire une contrainte "classique") + +CREATE TABLE env_actions_control_plan_tags ( + env_action_id uuid, + tag_id integer, + foreign key (env_action_id) references env_actions(id), + foreign key (tag_id) references control_plan_tags(id), + primary key (env_action_id, tag_id) +); COMMENT ON TABLE control_plan_themes IS 'Table des thèmes du plan de contrôle'; COMMENT ON TABLE control_plan_subthemes IS 'Table des sous-thèmes du plan de contrôle versionnés par année'; +COMMENT ON TABLE control_plan_tags IS 'Table des tags du plan de contrôle reliés aux thématiques'; COMMENT ON TABLE env_actions_control_plan_sub_themes IS 'Table de jointure entre les actions et les sous-thèmes du plan de contrôle'; +COMMENT ON TABLE env_actions_control_plan_tags IS 'Table de jointure entre les actions et les tags reliées aux thématiques du plan de contrôle'; -- Insertion des themes et sous-themes à partir de la table control_themes INSERT INTO control_plan_themes (theme) @@ -40,45 +52,83 @@ INSERT INTO control_plan_subthemes (subtheme, theme_id, year) SELECT distinct theme_level_2, t.id, 2023 FROM control_themes c JOIN control_plan_themes t ON t.theme = theme_level_1 WHERE theme_level_2 IS NOT NULL ORDER BY theme_level_2 - ; +; -UPDATE control_plan_subthemes - SET allowed_tags = '{"Oiseaux", "Habitat", "Flore", "Autres espèces protégées", "Reptiles", "Mammifères marins"}' - FROM control_plan_themes t - WHERE - t.id = control_plan_subthemes.theme_id - AND t.theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; +INSERT INTO control_plan_tags (theme_id, tag) + SELECT t.id, unnest(ARRAY['Oiseaux', 'Habitat', 'Flore', 'Autres espèces protégées', 'Reptiles', 'Mammifères marins']) + FROM control_plan_themes t + WHERE t.theme = 'Police des espèces protégées et de leurs habitats (faune et flore)' +; -- Insertion des données depuis les env actions dans la table env_actions_control_plan_sub_themes -INSERT INTO env_actions_control_plan_sub_themes (env_action_id, subtheme_id, tags) +INSERT INTO env_actions_control_plan_sub_themes (env_action_id, subtheme_id) WITH themes AS ( SELECT id as env_action_id, jsonb_array_elements(value->'themes')->>'theme' as theme, - jsonb_array_elements_text(jsonb_array_elements(value->'themes')->'subThemes') as subtheme, - jsonb_array_elements(value->'themes')->'protectedSpecies' as protectedspecies - FROM env_actions - ) - SELECT themes.env_action_id, sbt.id, CASE WHEN cardinality(d.tags) >0 THEN d.tags END + jsonb_array_elements_text(jsonb_array_elements(value->'themes')->'subThemes') as subtheme + FROM env_actions + ) + SELECT themes.env_action_id, sbt.id FROM themes, - LATERAL ( - SELECT ARRAY( - SELECT CASE species - WHEN 'BIRDS' THEN 'Oiseaux' - WHEN 'HABITAT' THEN 'Habitat' - WHEN 'FLORA' THEN 'Flore' - WHEN 'OTHER' THEN 'Autres espèces protégées' - WHEN 'REPTILES' THEN 'Reptiles' - WHEN 'MARINE_MAMMALS' THEN 'Mammifères marins' - ELSE 'Non défini' - END - FROM (SELECT jsonb_array_elements_text(protectedspecies) species) t - ) - ) d(tags), control_plan_subthemes sbt, - control_plan_themes t + control_plan_themes th WHERE sbt.subtheme = themes.subtheme - AND sbt.theme_id = t.id - AND t.theme = themes.theme + AND sbt.theme_id = th.id + AND th.theme = themes.theme AND sbt.year = 2023; +-- tags +INSERT INTO env_actions_control_plan_tags (env_action_id, tag_id) +WITH themes AS ( + SELECT + id as env_action_id, + jsonb_array_elements(value->'themes')->>'theme' as theme, + jsonb_array_elements(value->'themes')->'protectedSpecies' as protectedspecies + FROM env_actions +) + SELECT themes.env_action_id, control_plan_tags.id + FROM themes, + LATERAL ( + SELECT + CASE species + WHEN 'BIRDS' THEN 'Oiseaux' + WHEN 'HABITAT' THEN 'Habitat' + WHEN 'FLORA' THEN 'Flore' + WHEN 'OTHER' THEN 'Autres espèces protégées' + WHEN 'REPTILES' THEN 'Reptiles' + WHEN 'MARINE_MAMMALS' THEN 'Mammifères marins' + ELSE 'Non défini' + END + FROM (SELECT jsonb_array_elements_text(protectedspecies) species) t + ) d(tags), + control_plan_tags + WHERE control_plan_tags.tag = d.tags; + + +--- Signalements +CREATE TABLE reportings_control_plan_sub_themes ( + reporting_id uuid, + subtheme_id integer, + foreign key (reporting_id) references reportings(id), + foreign key (subtheme_id) references control_plan_subthemes(id), + primary key (reporting_id, subtheme_id) +); +COMMENT ON TABLE reportings_control_plan_sub_themes IS 'Table de jointure entre les signalements et les sous-thèmes du plan de contrôle'; +INSERT INTO reportings_control_plan_sub_themes (reporting_id, subtheme_id) + WITH reportingthemes AS ( + SELECT id, + theme, + unnest(sub_themes) as subtheme + FROM public.reportings r + WHERE r.sub_themes is not null + ) + SELECT rt.id, th.id + FROM reportingthemes rt, + public.control_plan_themes as th, + public.control_plan_subthemes as sbt + WHERE th.id = sbt.theme_id + AND rt.theme = th.theme + AND rt.subtheme = sbt.subtheme + AND sbt.year = 2023 +; diff --git a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql index 713ce207a..e5e0810d2 100644 --- a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql +++ b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql @@ -3,13 +3,13 @@ -- DELETE FROM public.env_actions; -INSERT INTO public.env_actions (id, mission_id, action_type, value, action_start_datetime_utc, geom, facade, department, action_end_datetime_utc, is_administrative_control, is_compliance_with_water_regulations_control, is_safety_equipment_and_standards_compliance_control, is_seafarers_control) VALUES +INSERT INTO public.env_actions (id, mission_id, action_type, value, action_start_datetime_utc, geom, facade, department, action_end_datetime_utc, is_administrative_control, is_compliance_with_water_regulations_control, is_safety_equipment_and_standards_compliance_control, is_seafarers_control) VALUES ('e2257638-ddef-4611-960c-7675a3254c38', 38, 'SURVEILLANCE', '{"themes": [{"theme": "Police des activités de cultures marines", "subThemes": ["Contrôle du schéma des structures"], "protectedSpecies": []}], "observations": "", "coverMissionZone": true}', '2022-07-30 08:53:31.588693', NULL, NULL, '56', '2022-07-30 10:53:31.588693', NULL, NULL, NULL,NULL), ('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 38, 'CONTROL' , '{"themes": [{"theme": "Police des épaves", "subThemes": ["Épave/navire abandonné", "Contrôle administratif"], "protectedSpecies": []}], "infractions": [{"id": "6670e718-3ecd-46c1-8149-8b963c6f72dd", "natinf": ["10041"], "toProcess": false, "vesselSize": null, "vesselType": null, "companyName": "MASOCIETE", "formalNotice": "YES", "observations": "RAS", "relevantCourt": "LOCAL_COURT", "infractionType": "WITH_REPORT", "registrationNumber": null, "controlledPersonIdentity": null}], "vehicleType": null, "observations": null, "actionTargetType": "COMPANY", "actionNumberOfControls": 1}', '2022-07-29 11:53:31.588693', '0104000020E6100000010000000101000000399291D4BE1805C09E1A585CD6154840', NULL, NULL, NULL, NULL, NULL, NULL, NULL), ('475d2887-5344-46cd-903b-8cb5e42f9a9c', 49, 'SURVEILLANCE', '{"themes": [{"theme": "Police du conservatoire du littoral", "subThemes": ["Réglementation du conservatoire du littoral"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": false, "protectedSpecies": []}', NULL, '0106000020E61000000100000001030000000100000005000000D56979C3E95203C0BC117648B972474084387273B24D02C00C726AA38C6E4740BFFBD6B9762002C0349A2D10497347407A8D399212A102C0546E1659817A4740D56979C3E95203C0BC117648B9724740', NULL, NULL, NULL, NULL, NULL, NULL, NULL), ('16eeb9e8-f30c-430e-b36b-32b4673f81ce', 49, 'NOTE' , '{"observations": "Note libre"}', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), ('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 49, 'CONTROL' , '{"themes": [{"theme": "AMP sans réglementation particulière", "subThemes": ["Contrôle dans une AMP sans réglementation particulière"], "protectedSpecies": []}], "infractions": [{"id": "e56648c1-6ca3-4d5e-a5d2-114aa7c17126", "natinf": ["10231", "10228"], "toProcess": true, "vesselSize": null, "vesselType": null, "companyName": null, "formalNotice": "PENDING", "observations": "RAS", "relevantCourt": "PRE", "infractionType": "WAITING", "registrationNumber": null, "controlledPersonIdentity": "M DURAND"}], "vehicleType": null, "actionTargetType": "INDIVIDUAL", "actionNumberOfControls": 1}', NULL, '0104000020E61000000100000001010000003B0DADC6D4BB01C0A8387A2964714740', NULL, NULL, NULL, NULL, NULL, NULL, NULL), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 34, 'SURVEILLANCE', '{"themes": [{"theme": "Police des espèces protégées et de leurs habitats (faune et flore),", "subThemes": ["Destruction, capture, arrachage", "Atteinte aux habitats d''espèces protégées"], "protectedSpecies": ["FLORA", "BIRDS"]}, {"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": true, "protectedSpecies": []}', '2022-07-16 10:03:12.588693', NULL, NULL, NULL, '2022-07-16 12:03:12.588693', NULL, NULL, NULL, NULL), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 34, 'SURVEILLANCE', '{"themes": [{"theme": "Police des espèces protégées et de leurs habitats (faune et flore)", "subThemes": ["Destruction, capture, arrachage", "Atteinte aux habitats d''espèces protégées"], "protectedSpecies": ["FLORA", "BIRDS"]}, {"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "duration": 0.0, "observations": "RAS", "coverMissionZone": true, "protectedSpecies": []}', '2022-07-16 10:03:12.588693', NULL, NULL, NULL, '2022-07-16 12:03:12.588693', NULL, NULL, NULL, NULL), ('b8007c8a-5135-4bc3-816f-c69c7b75d807', 34, 'CONTROL' , '{"themes": [{"theme": "Police des mouillages", "subThemes": ["Mouillage individuel", "ZMEL"], "protectedSpecies": []}], "observations": "RAS", "infractions": [{"id": "5d5b7829-68cd-4436-8c0b-1cc8db7788a0", "natinf": ["10038","10231"], "toProcess": false, "vesselSize": "FROM_24_TO_46m", "vesselType": "COMMERCIAL", "companyName": null, "formalNotice": "PENDING", "observations": "Pas d''observations", "relevantCourt": "LOCAL_COURT", "infractionType": "WITH_REPORT", "registrationNumber": "BALTIK", "controlledPersonIdentity": "John Doe"}], "vehicleType": "VESSEL", "actionTargetType": "VEHICLE", "actionNumberOfControls": 1}', '2022-07-16 09:03:12.588693', '0104000020E610000001000000010100000047A07E6651E3DEBF044620AB65C54840', NULL, NULL, '2022-07-16 12:03:12.588693', NULL, NULL, NULL, NULL), ('4d9a3139-6c60-49a5-b443-0e6238a6a120', 41, 'CONTROL' , '{"themes": [{"theme": "Police des mouillages", "subThemes": ["Contrôle administratif"], "protectedSpecies": []}], "infractions": [], "vehicleType": null, "observations": "", "actionTargetType": null, "actionNumberOfControls": null}','2022-07-01 02:44:16.588693', NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE) ; From 7245ee35a01df23f9accc12a3d76fa567ec39844 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 14/53] wip --- .../controlPlan/ControlPlanSubthemeEntity.kt | 8 ++ .../controlPlan/ControlPlanTagEntity.kt | 7 ++ .../controlPlan/ControlPlanThemeEntity.kt | 6 ++ .../ControlPlanSubthemeEntity.kt | 9 -- .../controlTheme/ControlThemeEntity.kt | 2 +- .../envAction/EnvActionControlPlanEntity.kt | 7 ++ .../EnvActionControlPlanSubthemeEntity.kt | 8 -- .../mission/envAction/EnvActionEntity.kt | 2 +- .../envAction/EnvActionSurveillanceEntity.kt | 4 +- .../EnvActionSurveillanceProperties.kt | 6 +- .../EnvActionControlEntity.kt | 6 +- .../EnvActionControlProperties.kt | 8 +- .../domain/mappers/EnvActionMapper.kt | 8 +- .../IControlPlanSubThemeRepository.kt | 2 +- .../repositories/IControlPlanTagRepository.kt | 7 ++ .../repositories/IControlThemeRepository.kt | 2 +- .../controlPlan/GetControlPlansByYear.kt | 29 +++++++ .../GetControlPlanSubThemesByYear.kt | 16 ---- .../controlThemes/GetAllControlThemes.kt | 2 +- .../missions/ControlPlanSubThemeDataInput.kt | 15 ---- .../CreateOrUpdateMissionDataInput.kt | 42 +++++----- .../MissionEnvActionControlPlanDataInput.kt | 17 ++++ .../missions/MissionEnvActionDataInput.kt | 8 +- .../bff/outputs/ControlPlanDataOutput.kt | 28 +++++++ .../outputs/ControlPlanSubThemeDataOutput.kt | 16 ++-- .../bff/outputs/ControlPlanTagDataOutput.kt | 18 ++++ .../bff/outputs/ControlPlanThemeDataOutput.kt | 19 +++++ .../MissionEnvActionControlDataOutput.kt | 7 +- .../MissionEnvActionControlPlanDataOutput.kt | 18 ++++ .../MissionEnvActionSubThemeDataOutput.kt | 22 ----- .../MissionEnvActionSurveillanceDataOutput.kt | 5 ++ .../bff/ControlPlanSubThemesController.kt | 30 ------- .../endpoints/bff/ControlPlansController.kt | 30 +++++++ .../model/ControlPlanSubThemeModel.kt | 9 +- .../database/model/ControlPlanTagModel.kt | 50 +++++++++++ .../database/model/EnvActionModel.kt | 22 ++++- .../EnvActionsControlPlanSubThemeModel.kt | 4 +- .../model/EnvActionsControlPlanTagModel.kt | 82 +++++++++++++++++++ .../database/model/MissionModel.kt | 36 ++++---- .../JpaControlPlanSubThemeRepository.kt | 2 +- .../repositories/JpaMissionRepository.kt | 36 ++++++-- .../interfaces/IDBControlPlanTagRepository.kt | 6 ++ .../internal/V0.103__create_action_theme.sql | 32 +++++--- .../GetControlPlanSubThemesByYearUTest.kt | 8 +- .../ControlPlanSubThemesControllerITests.kt | 8 +- .../endpoints/bff/MissionsControllerITests.kt | 20 ++--- 46 files changed, 502 insertions(+), 227 deletions(-) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanSubthemeEntity.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanTagEntity.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanThemeEntity.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubtheme/ControlPlanSubthemeEntity.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanEntity.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubthemeEntity.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionControlPlanDataInput.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanDataOutput.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanTagDataOutput.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlPlanDataOutput.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt rename backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/{controlPlanSubThemes => controlPlan}/GetControlPlanSubThemesByYearUTest.kt (83%) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanSubthemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanSubthemeEntity.kt new file mode 100644 index 000000000..f468e82fb --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanSubthemeEntity.kt @@ -0,0 +1,8 @@ +package fr.gouv.cacem.monitorenv.domain.entities.controlPlan + +data class ControlPlanSubThemeEntity( + val id: Int, + val themeId: Int, + val subTheme: String, + val year: Int, +) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanTagEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanTagEntity.kt new file mode 100644 index 000000000..ea4cead9d --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanTagEntity.kt @@ -0,0 +1,7 @@ +package fr.gouv.cacem.monitorenv.domain.entities.controlPlan + +data class ControlPlanTagEntity( + val id: Int, + val tag: String, + val themeId: Int, +) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanThemeEntity.kt new file mode 100644 index 000000000..613dcef66 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlan/ControlPlanThemeEntity.kt @@ -0,0 +1,6 @@ +package fr.gouv.cacem.monitorenv.domain.entities.controlPlan + +data class ControlPlanThemeEntity( + val id: Int, + val theme: String, +) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubtheme/ControlPlanSubthemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubtheme/ControlPlanSubthemeEntity.kt deleted file mode 100644 index 8633e1753..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlPlanSubtheme/ControlPlanSubthemeEntity.kt +++ /dev/null @@ -1,9 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme - -data class ControlPlanSubThemeEntity( - val id: Int, - val theme: String, - val subTheme: String, - val allowedTags: List ? = null, - val year: Int, -) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlTheme/ControlThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlTheme/ControlThemeEntity.kt index 325a5584e..c13754f5f 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlTheme/ControlThemeEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/controlTheme/ControlThemeEntity.kt @@ -1,6 +1,6 @@ package fr.gouv.cacem.monitorenv.domain.entities.controlTheme -@Deprecated("Use ThemeControlPlan instead") +@Deprecated("Use ControlPlanSubThemesEntity instead") data class ControlThemeEntity( val id: Int, val themeLevel1: String, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanEntity.kt new file mode 100644 index 000000000..f95890ad9 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanEntity.kt @@ -0,0 +1,7 @@ +package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction + +data class EnvActionControlPlanEntity( + val themeId: Int, + val subThemeIds: List? = emptyList(), + val tagIds: List? = emptyList(), +) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubthemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubthemeEntity.kt deleted file mode 100644 index c51b67af9..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubthemeEntity.kt +++ /dev/null @@ -1,8 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction - -data class EnvActionControlPlanSubThemeEntity( - val subThemeId: Int, - val tags: List? = null, - val theme: String? = null, - val subTheme: String? = null, -) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt index b577a922e..13219a9a5 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt @@ -23,7 +23,7 @@ abstract class EnvActionEntity( open val actionType: ActionTypeEnum, open val actionEndDateTimeUtc: ZonedDateTime? = null, open val actionStartDateTimeUtc: ZonedDateTime? = null, - open val controlPlanSubThemes: List? = listOf(), + open val controlPlans: List? = listOf(), open val department: String? = null, open val facade: String? = null, open val geom: Geometry? = null, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt index 8da15ce1f..c83fb749e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt @@ -8,13 +8,13 @@ data class EnvActionSurveillanceEntity( override val id: UUID, override val actionEndDateTimeUtc: ZonedDateTime? = null, override val actionStartDateTimeUtc: ZonedDateTime? = null, - override val controlPlanSubThemes: List? = listOf(), + override val controlPlans: List? = listOf(), override val geom: Geometry? = null, override val facade: String? = null, override val department: String? = null, val coverMissionZone: Boolean? = null, val observations: String? = null, - @Deprecated("Use ControlPlanSubThemes instead") + @Deprecated("Use controlPlan instead") val themes: List? = listOf(), ) : EnvActionEntity( diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt index 113178069..cfbf8e524 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt @@ -7,14 +7,14 @@ import java.util.* data class EnvActionSurveillanceProperties( val coverMissionZone: Boolean? = null, val observations: String? = null, - @Deprecated("Use ControlPlanSubThemes instead") + @Deprecated("Use controlPlans instead") val themes: List? = listOf(), ) { fun toEnvActionSurveillanceEntity( id: UUID, actionStartDateTimeUtc: ZonedDateTime?, actionEndDateTimeUtc: ZonedDateTime?, - controlPlanSubThemes: List?, + controlPlans: List?, department: String?, facade: String?, geom: Geometry?, @@ -23,7 +23,7 @@ data class EnvActionSurveillanceProperties( id = id, actionStartDateTimeUtc = actionStartDateTimeUtc, actionEndDateTimeUtc = actionEndDateTimeUtc, - controlPlanSubThemes = controlPlanSubThemes, + controlPlans = controlPlans, coverMissionZone = coverMissionZone, department = department, facade = facade, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt index bdd08cc0a..2a9fa4dec 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt @@ -2,7 +2,7 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionCont import fr.gouv.cacem.monitorenv.domain.entities.VehicleTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.InfractionEntity @@ -14,7 +14,7 @@ data class EnvActionControlEntity( override val id: UUID, override val actionEndDateTimeUtc: ZonedDateTime? = null, override val actionStartDateTimeUtc: ZonedDateTime? = null, - override val controlPlanSubThemes: List? = listOf(), + override val controlPlans: List? = listOf(), override val department: String? = null, override val facade: String? = null, override val geom: Geometry? = null, @@ -26,7 +26,7 @@ data class EnvActionControlEntity( val actionTargetType: ActionTargetTypeEnum? = null, val infractions: List? = listOf(), val observations: String? = null, - @Deprecated("Use ControlPlanSubThemes instead") + @Deprecated("Use controlPlan instead") val themes: List? = listOf(), val vehicleType: VehicleTypeEnum? = null, ) : diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt index 4d9af6c55..de2128807 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt @@ -1,7 +1,7 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl import fr.gouv.cacem.monitorenv.domain.entities.VehicleTypeEnum -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.InfractionEntity import org.locationtech.jts.geom.Geometry @@ -13,7 +13,7 @@ data class EnvActionControlProperties( val actionTargetType: ActionTargetTypeEnum? = null, val infractions: List? = listOf(), val observations: String? = null, - @Deprecated("Use ControlPlanSubThemes instead") + @Deprecated("Use controlPlans instead") val themes: List? = listOf(), val vehicleType: VehicleTypeEnum? = null, ) { @@ -21,7 +21,7 @@ data class EnvActionControlProperties( id: UUID, actionEndDateTimeUtc: ZonedDateTime?, actionStartDateTimeUtc: ZonedDateTime?, - controlPlanSubThemes: List?, + controlPlans: List?, department: String?, facade: String?, geom: Geometry?, @@ -36,7 +36,7 @@ data class EnvActionControlProperties( actionNumberOfControls = actionNumberOfControls, actionStartDateTimeUtc = actionStartDateTimeUtc, actionTargetType = actionTargetType, - controlPlanSubThemes = controlPlanSubThemes, + controlPlans = controlPlans, department = department, facade = facade, geom = geom, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt index d470150a7..dbed39f51 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt @@ -2,7 +2,7 @@ package fr.gouv.cacem.monitorenv.domain.mappers import com.fasterxml.jackson.databind.ObjectMapper import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionNoteEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionNoteProperties @@ -26,7 +26,7 @@ object EnvActionMapper { actionEndDateTimeUtc: ZonedDateTime?, actionType: ActionTypeEnum, actionStartDateTimeUtc: ZonedDateTime?, - controlPlanSubThemes: List?, + controlPlans: List?, department: String?, facade: String?, geom: Geometry?, @@ -48,7 +48,7 @@ object EnvActionMapper { id = id, actionEndDateTimeUtc = actionEndDateTimeUtc, actionStartDateTimeUtc = actionStartDateTimeUtc, - controlPlanSubThemes = controlPlanSubThemes, + controlPlans = controlPlans, department = department, facade = facade, geom = geom, @@ -62,7 +62,7 @@ object EnvActionMapper { id = id, actionEndDateTimeUtc = actionEndDateTimeUtc, actionStartDateTimeUtc = actionStartDateTimeUtc, - controlPlanSubThemes = controlPlanSubThemes, + controlPlans = controlPlans, department = department, facade = facade, geom = geom, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt index e8701a36a..b5833f821 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt @@ -1,6 +1,6 @@ package fr.gouv.cacem.monitorenv.domain.repositories -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity interface IControlPlanSubThemeRepository { fun findByYear(year: Int): List diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt new file mode 100644 index 000000000..dae4b69d0 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt @@ -0,0 +1,7 @@ +package fr.gouv.cacem.monitorenv.domain.repositories + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity + +interface IControlPlanTagRepository { + fun findAll(): List +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt index 655f12a3b..b6157c49d 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlThemeRepository.kt @@ -2,7 +2,7 @@ package fr.gouv.cacem.monitorenv.domain.repositories import fr.gouv.cacem.monitorenv.domain.entities.controlTheme.ControlThemeEntity -@Deprecated("Use ControlPlanSubThemeRepository instead") +@Deprecated("Use IControlPlanSubThemeRepository instead") interface IControlThemeRepository { fun findById(controlThemeId: Int): ControlThemeEntity fun findAll(): List diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt new file mode 100644 index 000000000..3cbf4304b --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt @@ -0,0 +1,29 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan + +import fr.gouv.cacem.monitorenv.config.UseCase +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository +import org.slf4j.LoggerFactory + +@UseCase +class GetControlPlansByYear( + private val controlPlanThemeRepository: IControlPlanThemeRepository, + private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository, + private val controlPlanTagRepository: IControlPlanTagRepository, +) { + private val logger = LoggerFactory.getLogger(GetControlPlansByYear::class.java) + fun execute(year: Int): ControlPlanByYear { + val controlPlanThemes = getControlPlanThemes(year) + val controlPlanSubThemes = controlPlanSubThemeRepository.findByYear(year) + val controlPlanTags = controlPlanSubThemes.map { it.allowedTags }.flatten().toSet() + logger.info("Found ${controlPlanSubThemes.size} control plan subthemes for year $year") + return Triple(controlPlanSubThemes, controlPlanTags, controlPlanThemes) + } +} + +typealias ControlPlanByYear = Triple< + List, + List, + List,> diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt deleted file mode 100644 index 8d2c485a9..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt +++ /dev/null @@ -1,16 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes - -import fr.gouv.cacem.monitorenv.config.UseCase -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity -import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository -import org.slf4j.LoggerFactory - -@UseCase -class GetControlPlanSubThemesByYear(private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository) { - private val logger = LoggerFactory.getLogger(GetControlPlanSubThemesByYear::class.java) - fun execute(year: Int): List { - val controlPlanSubThemes = controlPlanSubThemeRepository.findByYear(year) - logger.info("Found ${controlPlanSubThemes.size} control plan (sub)themes for year $year") - return controlPlanSubThemes - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt index 69b2e7dc4..5039efa86 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlThemes/GetAllControlThemes.kt @@ -7,7 +7,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlTheme.ControlThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlThemeRepository import org.slf4j.LoggerFactory -@Deprecated("Use GetControlPlanSubThemesByYear instead") +@Deprecated("Use GetControlPlansByYear instead") @UseCase class GetAllControlThemes(private val controlThemeRepository: IControlThemeRepository) { private val logger = LoggerFactory.getLogger(GetAllControlThemes::class.java) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt deleted file mode 100644 index bb227d4c1..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/ControlPlanSubThemeDataInput.kt +++ /dev/null @@ -1,15 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions - -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity - -data class ControlPlanSubThemeDataInput( - val subThemeId: Int, - val tags: List ? = null, -) { - fun toEnvActionControlPlanSubThemeEntity(): EnvActionControlPlanSubThemeEntity { - return EnvActionControlPlanSubThemeEntity( - subThemeId = this.subThemeId, - tags = this.tags, - ) - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/CreateOrUpdateMissionDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/CreateOrUpdateMissionDataInput.kt index dcd39b1eb..b6028afd1 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/CreateOrUpdateMissionDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/CreateOrUpdateMissionDataInput.kt @@ -11,22 +11,22 @@ import java.time.ZonedDateTime data class CreateOrUpdateMissionDataInput( val id: Int? = null, - val missionTypes: List, + val attachedReportingIds: List, val controlUnits: List = listOf(), - val openBy: String? = null, val closedBy: String? = null, - val observationsCacem: String? = null, - val observationsCnsp: String? = null, + val envActions: List? = null, val facade: String? = null, val geom: MultiPolygon? = null, - val startDateTimeUtc: ZonedDateTime, - val endDateTimeUtc: ZonedDateTime? = null, - val missionSource: MissionSourceEnum, - val isClosed: Boolean, - val envActions: List? = null, val hasMissionOrder: Boolean? = false, + val isClosed: Boolean, val isUnderJdp: Boolean? = false, - val attachedReportingIds: List, + val missionSource: MissionSourceEnum, + val missionTypes: List, + val observationsCacem: String? = null, + val observationsCnsp: String? = null, + val openBy: String? = null, + val startDateTimeUtc: ZonedDateTime, + val endDateTimeUtc: ZonedDateTime? = null, ) { fun toMissionEntity(): MissionEntity { val hasMissionOrder = this.hasMissionOrder ?: false @@ -34,23 +34,23 @@ data class CreateOrUpdateMissionDataInput( return MissionEntity( id = this.id, - missionTypes = this.missionTypes, - controlUnits = this.controlUnits, - openBy = this.openBy, closedBy = this.closedBy, - observationsCacem = this.observationsCacem, - observationsCnsp = this.observationsCnsp, + controlUnits = this.controlUnits, + endDateTimeUtc = this.endDateTimeUtc, + envActions = this.envActions?.map { it.toEnvActionEntity() }, facade = this.facade, geom = this.geom, - startDateTimeUtc = this.startDateTimeUtc, - endDateTimeUtc = this.endDateTimeUtc, + hasMissionOrder = hasMissionOrder, isClosed = this.isClosed, isDeleted = false, - missionSource = this.missionSource, - envActions = this.envActions?.map { it.toEnvActionEntity() }, - hasMissionOrder = hasMissionOrder, - isUnderJdp = isUnderJdp, isGeometryComputedFromControls = false, + isUnderJdp = isUnderJdp, + missionSource = this.missionSource, + missionTypes = this.missionTypes, + observationsCacem = this.observationsCacem, + observationsCnsp = this.observationsCnsp, + openBy = this.openBy, + startDateTimeUtc = this.startDateTimeUtc, ) } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionControlPlanDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionControlPlanDataInput.kt new file mode 100644 index 000000000..69b8280e2 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionControlPlanDataInput.kt @@ -0,0 +1,17 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions + +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity + +data class MissionEnvActionControlPlanDataInput( + val subThemeIds: List? = emptyList(), + val tagIds: List? = emptyList(), + val themeId: Int, +) { + fun toEnvActionControlPlanEntity(): EnvActionControlPlanEntity { + return EnvActionControlPlanEntity( + subThemeIds = this.subThemeIds, + tagIds = this.tagIds, + themeId = this.themeId, + ) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt index b0e4411c8..7ed1ddc0d 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt @@ -23,8 +23,9 @@ data class MissionEnvActionDataInput( // EnvActionControl + EnvSurveillance Properties val actionEndDateTimeUtc: ZonedDateTime? = null, - val controlPlanSubThemes: List? = null, - @Deprecated("Use controlPlanSubThemes instead") + val controlPlans: List? = null, + + @Deprecated("Use controlPlans instead") val themes: List? = null, val department: String? = null, val facade: String? = null, @@ -74,7 +75,7 @@ data class MissionEnvActionDataInput( actionNumberOfControls = this.actionNumberOfControls, actionTargetType = this.actionTargetType, actionStartDateTimeUtc = this.actionStartDateTimeUtc, - controlPlanSubThemes = this.controlPlanSubThemes?.map { it.toEnvActionControlPlanSubThemeEntity() }, + controlPlans = this.controlPlans?.map { it.toEnvActionControlPlanEntity() }, department = this.department, facade = this.facade, geom = this.geom, @@ -94,6 +95,7 @@ data class MissionEnvActionDataInput( id = this.id, actionStartDateTimeUtc = this.actionStartDateTimeUtc, actionEndDateTimeUtc = this.actionEndDateTimeUtc, + controlPlans = this.controlPlans?.map { it.toEnvActionControlPlanEntity() }, department = this.department, facade = this.facade, geom = this.geom, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanDataOutput.kt new file mode 100644 index 000000000..90d9dbe6f --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanDataOutput.kt @@ -0,0 +1,28 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity + +data class ControlPlanDataOutput( + val themes: Map, + val subThemes: Map, + val tags: Map, +) { + companion object { + fun fromControlPlanEntities( + themes: List, + subThemes: List, + tags: List, + ): ControlPlanDataOutput { + return ControlPlanDataOutput( + themes = themes.associateBy({ it.id }, { ControlPlanThemeDataOutput.fromControlPlanThemeEntity(it) }), + subThemes = subThemes.associateBy( + { it.id }, + { ControlPlanSubThemeDataOutput.fromControlPlanSubThemeEntity(it) }, + ), + tags = tags.associateBy({ it.id }, { ControlPlanTagDataOutput.fromControlPlanTagEntity(it) }), + ) + } + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt index 7155b12a6..b653690e2 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt @@ -1,22 +1,18 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity data class ControlPlanSubThemeDataOutput( val id: Int, - val theme: String, + val themeId: Int, val subTheme: String, - val allowedTags: List? = null, - val year: Int, ) { companion object { - fun fromControlPlanSubThemeEntity(ControlPlanSubTheme: ControlPlanSubThemeEntity) = + fun fromControlPlanSubThemeEntity(controlPlanSubTheme: ControlPlanSubThemeEntity) = ControlPlanSubThemeDataOutput( - id = ControlPlanSubTheme.id, - theme = ControlPlanSubTheme.theme, - subTheme = ControlPlanSubTheme.subTheme, - allowedTags = ControlPlanSubTheme.allowedTags, - year = ControlPlanSubTheme.year, + id = controlPlanSubTheme.id, + themeId = controlPlanSubTheme.themeId, + subTheme = controlPlanSubTheme.subTheme, ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanTagDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanTagDataOutput.kt new file mode 100644 index 000000000..eb5435419 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanTagDataOutput.kt @@ -0,0 +1,18 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity + +data class ControlPlanTagDataOutput( + val id: Int, + val tag: String, + val themeId: Int, +) { + companion object { + fun fromControlPlanTagEntity(controlPlanTag: ControlPlanTagEntity) = + ControlPlanTagDataOutput( + id = controlPlanTag.id, + tag = controlPlanTag.tag, + themeId = controlPlanTag.themeId, + ) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt new file mode 100644 index 000000000..53a22bfc0 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt @@ -0,0 +1,19 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity + +data class ControlPlanThemeDataOutput( + val id: Int, + val theme: String, +) { + companion object { + fun fromControlPlanThemeEntity( + controlPlanThemeEntity: ControlPlanThemeEntity, + ): ControlPlanThemeDataOutput { + return ControlPlanThemeDataOutput( + id = controlPlanThemeEntity.id, + theme = controlPlanThemeEntity.theme, + ) + } + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt index cc0bf8527..b5a2286b7 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt @@ -28,9 +28,8 @@ data class MissionEnvActionControlDataOutput( val isSeafarersControl: Boolean? = null, val observations: String? = null, val reportingIds: List, - @Deprecated("Use ControlPlanSubThemes instead") + @Deprecated("Use controlPlans instead") val themes: List? = listOf(), - val controlPlanSubThemes: List? = listOf(), val vehicleType: VehicleTypeEnum? = null, ) : MissionEnvActionDataOutput( @@ -49,8 +48,8 @@ data class MissionEnvActionControlDataOutput( actionStartDateTimeUtc = envActionControlEntity.actionStartDateTimeUtc, actionEndDateTimeUtc = envActionControlEntity.actionEndDateTimeUtc, actionTargetType = envActionControlEntity.actionTargetType, - controlPlanSubThemes = envActionControlEntity.controlPlanSubThemes?.map { - MissionEnvActionSubThemeDataOutput.fromEnvActionControlPlanSubThemeEntity(it) + controlPlans = envActionControlEntity.controlPlans?.map { + MissionEnvActionControlPlanDataOutput.fromEnvActionControlPlanEntity(it) }, department = envActionControlEntity.department, facade = envActionControlEntity.facade, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlPlanDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlPlanDataOutput.kt new file mode 100644 index 000000000..96f577960 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlPlanDataOutput.kt @@ -0,0 +1,18 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.missions + +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity + +data class MissionEnvActionControlPlanDataOutput( + val themeId: Int, + val subThemeIds: List? = emptyList(), + val tagIds: List? = emptyList(), +) { + companion object { + fun fromEnvActionControlPlanEntity(envActionControlPlanEntity: EnvActionControlPlanEntity) = + MissionEnvActionControlPlanDataOutput( + subThemeIds = envActionControlPlanEntity.subThemeIds, + tagIds = envActionControlPlanEntity.tagIds, + themeId = envActionControlPlanEntity.themeId, + ) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt deleted file mode 100644 index 1da3192e2..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt +++ /dev/null @@ -1,22 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.missions - -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity - -data class MissionEnvActionSubThemeDataOutput( - val id: Int, - val subTheme: String? = null, - val theme: String? = null, - val tags: List? = null, -) { - companion object { - fun fromEnvActionControlPlanSubThemeEntity( - envActionControlPlanSubThemeEntity: EnvActionControlPlanSubThemeEntity, - ) = - MissionEnvActionSubThemeDataOutput( - id = envActionControlPlanSubThemeEntity.subThemeId, - theme = envActionControlPlanSubThemeEntity.theme, - subTheme = envActionControlPlanSubThemeEntity.subTheme, - tags = envActionControlPlanSubThemeEntity.tags, - ) - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSurveillanceDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSurveillanceDataOutput.kt index 6c9c7487e..1832937a5 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSurveillanceDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSurveillanceDataOutput.kt @@ -12,12 +12,14 @@ data class MissionEnvActionSurveillanceDataOutput( val actionEndDateTimeUtc: ZonedDateTime? = null, override val actionStartDateTimeUtc: ZonedDateTime? = null, override val actionType: ActionTypeEnum = ActionTypeEnum.SURVEILLANCE, + val controlPlans: List? = null, val coverMissionZone: Boolean? = null, val department: String? = null, val facade: String? = null, val geom: Geometry? = null, val observations: String? = null, val reportingIds: List, + @Deprecated("Use controlPlans instead") val themes: List? = listOf(), ) : MissionEnvActionDataOutput( @@ -34,6 +36,9 @@ data class MissionEnvActionSurveillanceDataOutput( id = envActionSurveillanceEntity.id, actionEndDateTimeUtc = envActionSurveillanceEntity.actionEndDateTimeUtc, actionStartDateTimeUtc = envActionSurveillanceEntity.actionStartDateTimeUtc, + controlPlans = envActionSurveillanceEntity.controlPlans?.map { + MissionEnvActionControlPlanDataOutput.fromEnvActionControlPlanEntity(it) + }, department = envActionSurveillanceEntity.department, facade = envActionSurveillanceEntity.facade, geom = envActionSurveillanceEntity.geom, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt deleted file mode 100644 index b4f801711..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesController.kt +++ /dev/null @@ -1,30 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff - -import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes.GetControlPlanSubThemesByYear -import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.ControlPlanSubThemeDataOutput -import io.swagger.v3.oas.annotations.Operation -import io.swagger.v3.oas.annotations.tags.Tag -import jakarta.websocket.server.PathParam -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -@RestController -@RequestMapping("/bff/v1/controlPlanSubThemes") -@Tag(name = "Control Plan Sub Themes", description = "API des sous thématiques des plan de contrôle") -class ControlPlanSubThemesController( - private val getControlPlanSubThemesByYear: GetControlPlanSubThemesByYear, -) { - - @GetMapping("/{year}") - @Operation(summary = "Get control plan (sub)themes and allowed tags for a given year") - fun getAll( - @PathParam("validity year of the control plan themes") - @PathVariable(name = "year") - year: Int, - ): List { - val ControlPlanSubThemes = getControlPlanSubThemesByYear.execute(year) - return ControlPlanSubThemes.map { ControlPlanSubThemeDataOutput.fromControlPlanSubThemeEntity(it) } - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt new file mode 100644 index 000000000..63a118281 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt @@ -0,0 +1,30 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff + +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlansByYear +import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.ControlPlanDataOutput +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import jakarta.websocket.server.PathParam +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/bff/v1/control_plans") +@Tag(name = "Control Plan Themes, SubThemes and tags", description = "API des sous thématiques des plan de contrôle") +class ControlPlansController( + private val getControlPlansByYear: GetControlPlansByYear, +) { + + @GetMapping("/{year}") + @Operation(summary = "Get control plan themes, subthemes and tags and allowed tags for a given year") + fun getAll( + @PathParam("validity year of the control plan themes") + @PathVariable(name = "year") + year: Int, + ): List { + val controlPlanSubThemes = getControlPlansByYear.execute(year) + return controlPlanSubThemes.map { ControlPlanDataOutput.fromControlPlanEntity(it) } + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt index 603ae73ec..733bb2578 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt @@ -1,7 +1,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.model -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity -import io.hypersistence.utils.hibernate.type.array.ListArrayType +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity import jakarta.persistence.Column import jakarta.persistence.Entity import jakarta.persistence.FetchType @@ -14,7 +13,6 @@ import jakarta.persistence.Table import org.hibernate.Hibernate import org.hibernate.annotations.Cache import org.hibernate.annotations.CacheConcurrencyStrategy -import org.hibernate.annotations.Type @Entity @Table(name = "control_plan_subthemes") @@ -27,10 +25,6 @@ class ControlPlanSubThemeModel( @Column(name = "id", nullable = false, updatable = false) val id: Int, - @Column(name = "allowed_tags") - @Type(ListArrayType::class) - val allowedTags: List? = null, - @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "theme_id") val controlPlanTheme: ControlPlanThemeModel, @@ -47,7 +41,6 @@ class ControlPlanSubThemeModel( subTheme = subTheme, theme = controlPlanTheme.theme, year = year, - allowedTags = allowedTags, ) override fun equals(other: Any?): Boolean { diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt new file mode 100644 index 000000000..dd0e20ab4 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt @@ -0,0 +1,50 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.model + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.FetchType +import jakarta.persistence.GeneratedValue +import jakarta.persistence.GenerationType +import jakarta.persistence.Id +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne +import jakarta.persistence.Table +import org.hibernate.Hibernate +import org.hibernate.annotations.Cache +import org.hibernate.annotations.CacheConcurrencyStrategy + +@Entity +@Table(name = "control_plan_tags") +@Cache( + usage = CacheConcurrencyStrategy.READ_WRITE, +) +class ControlPlanTagModel( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false, updatable = false) + val id: Int, + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "theme_id") + val controlPlanTheme: ControlPlanThemeModel, + + @Column(name = "tag") + val tag: String, + +) { + fun toControlPlanTag() = ControlPlanTagEntity( + id = id, + tag = tag, + ) + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false + other as ControlPlanTagModel + + return id == other.id + } + + override fun hashCode(): Int = javaClass.hashCode() +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt index 1eae88521..006505d1d 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt @@ -101,6 +101,14 @@ class EnvActionModel( mappedBy = "envAction", ) val controlPlanSubThemes: MutableList? = ArrayList(), + + @OneToMany( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + orphanRemoval = true, + mappedBy = "envAction", + ) + val controlPlanTags: MutableList? = ArrayList(), ) { fun toActionEntity(mapper: ObjectMapper): EnvActionEntity { @@ -111,6 +119,7 @@ class EnvActionModel( actionType = actionType, actionStartDateTimeUtc = actionStartDateTime?.atZone(UTC), controlPlanSubThemes = controlPlanSubThemes?.map { it.toEnvActionControlPlanSubThemeEntity() }, + controlPlanTags = controlPlanTags?.map { it.toEnvActionControlPlanTagEntity() }, department = department, facade = facade, geom = geom, @@ -126,7 +135,9 @@ class EnvActionModel( fun fromEnvActionEntity( action: EnvActionEntity, mission: MissionModel, + controlPlanThemesReferenceModelMap: Map, controlPlanSubThemesReferenceModelMap: Map, + controlPlanTagsReferenceModelMap: Map, mapper: ObjectMapper, ): EnvActionModel { var envActionModel = EnvActionModel( @@ -134,7 +145,6 @@ class EnvActionModel( actionEndDateTime = action.actionEndDateTimeUtc?.toInstant(), actionType = action.actionType, actionStartDateTime = action.actionStartDateTimeUtc?.toInstant(), - department = action.department, facade = action.facade, isAdministrativeControl = action.isAdministrativeControl, @@ -147,15 +157,21 @@ class EnvActionModel( geom = action.geom, value = EnvActionMapper.envActionEntityToJSON(mapper, action), ) - action.controlPlanSubThemes?.map { + action.controlPlans?.map { val envActionControlPlanSubThemeModel = EnvActionsControlPlanSubThemeModel.fromEnvActionControlPlanSubThemeEntity( envAction = envActionModel, controlPlanSubTheme = controlPlanSubThemesReferenceModelMap[it.subThemeId]!!, - tags = it.tags, ) envActionModel.controlPlanSubThemes?.add( envActionControlPlanSubThemeModel, ) + val envActionControlPlanTagModel = EnvActionsControlPlanTagModel.fromEnvActionControlPlanTagEntity( + envAction = envActionModel, + controlPlanTag = controlPlanTagsReferenceModelMap[it.subThemeId]!!, + ) + envActionModel.controlPlanTags?.add( + envActionControlPlanTagModel, + ) } return envActionModel } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt index f6d43d472..11612e7c3 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt @@ -56,9 +56,9 @@ class EnvActionsControlPlanSubThemeModel( require(controlPlanSubTheme != null) { "controlPlanSubTheme must not be null when converting to Entity" } return EnvActionControlPlanSubThemeEntity( subThemeId = controlPlanSubTheme.id, - theme = controlPlanSubTheme.controlPlanTheme.theme, subTheme = controlPlanSubTheme.subTheme, - tags = tags ?: emptyList(), + theme = controlPlanSubTheme.controlPlanTheme.theme, + themeId = controlPlanSubTheme.controlPlanTheme.id, ) } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt new file mode 100644 index 000000000..60d5582ac --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt @@ -0,0 +1,82 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.model + +import jakarta.persistence.Column +import jakarta.persistence.Embeddable +import jakarta.persistence.EmbeddedId +import jakarta.persistence.Entity +import jakarta.persistence.FetchType +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne +import jakarta.persistence.MapsId +import jakarta.persistence.Table +import org.hibernate.Hibernate +import java.io.Serializable +import java.util.UUID + +@Entity +@Table(name = "env_actions_control_plan_tags") +class EnvActionsControlPlanTagModel( + @EmbeddedId + val id: EnvActionsTagPk, + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("envActionId") + @JoinColumn(name = "env_action_id") + val envAction: EnvActionModel? = null, + + @ManyToOne(fetch = FetchType.EAGER) + @MapsId("tagId") + @JoinColumn(name = "tag_id") + val controlPlanTag: ControlPlanTagModel? = null, + +) { + companion object { + fun fromEnvActionControlPlanTagEntity( + envAction: EnvActionModel, + controlPlanTag: ControlPlanTagModel, + ) = EnvActionsControlPlanTagModel( + id = EnvActionsTagPk( + envActionId = envAction.id!!, + tagId = controlPlanTag.id!!, + ), + envAction = envAction, + controlPlanTag = controlPlanTag, + ) + } + + fun toEnvActionControlPlanTagEntity() { + require(controlPlanTag != null) { "controlPlanTag must not be null when converting to Entity" } + return + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false + other as EnvActionsControlPlanTagModel + + return id == other.id + } + + override fun hashCode(): Int = javaClass.hashCode() +} + +@Embeddable +data class EnvActionsTagPk( + @Column(name = "env_action_id") + val envActionId: UUID, + + @Column(name = "subtheme_id") + val tagId: Int, +) : Serializable { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is EnvActionsTagPk) return false + + return envActionId == other.envActionId && + tagId == other.tagId + } + + override fun hashCode(): Int { + return listOf(envActionId, tagId).hashCode() + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt index 4cccd42b3..ab90aabae 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/MissionModel.kt @@ -147,24 +147,24 @@ class MissionModel( } return MissionEntity( - id, - missionTypes, - controlUnits, - openBy, - closedBy, - observationsCacem, - observationsCnsp, - facade, - geom, - startDateTimeUtc = startDateTimeUtc.atZone(UTC), + id = id, + closedBy = closedBy, + controlUnits = controlUnits, endDateTimeUtc = endDateTimeUtc?.atZone(UTC), envActions = envActions!!.map { it.toActionEntity(objectMapper) }, - isClosed, - isDeleted, - isGeometryComputedFromControls, - missionSource, - hasMissionOrder, - isUnderJdp, + facade = facade, + geom = geom, + hasMissionOrder = hasMissionOrder, + isClosed = isClosed, + isDeleted = isDeleted, + isGeometryComputedFromControls = isGeometryComputedFromControls, + isUnderJdp = isUnderJdp, + missionSource = missionSource, + missionTypes = missionTypes, + observationsCacem = observationsCacem, + observationsCnsp = observationsCnsp, + openBy = openBy, + startDateTimeUtc = startDateTimeUtc.atZone(UTC), ) } @@ -237,7 +237,9 @@ class MissionModel( fun fromMissionEntity( mission: MissionEntity, controlUnitResourceModelMap: Map, + controlPlanThemesReferenceModelMap: Map, controlPlanSubThemesReferenceModelMap: Map, + controlPlanTagsReferenceModelMap: Map, mapper: ObjectMapper, ): MissionModel { val missionModel = @@ -265,7 +267,9 @@ class MissionModel( EnvActionModel.fromEnvActionEntity( action = it, mission = missionModel, + controlPlanThemesReferenceModelMap = controlPlanThemesReferenceModelMap, controlPlanSubThemesReferenceModelMap = controlPlanSubThemesReferenceModelMap, + controlPlanTagsReferenceModelMap = controlPlanTagsReferenceModelMap, mapper = mapper, ), ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt index cd3a9c474..08ff75418 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt @@ -1,6 +1,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanSubThemeRepository import org.springframework.stereotype.Repository diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt index 3709ce0b6..9f610cea7 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt @@ -7,6 +7,7 @@ import fr.gouv.cacem.monitorenv.domain.repositories.IMissionRepository import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO import fr.gouv.cacem.monitorenv.infrastructure.database.model.MissionModel import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanSubThemeRepository +import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanTagRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlUnitResourceRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBMissionRepository import org.springframework.data.domain.Pageable @@ -18,6 +19,7 @@ import java.time.Instant @Repository class JpaMissionRepository( private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, + private val dbControlPlanTagRepository: IDBControlPlanTagRepository, private val dbControlUnitResourceRepository: IDBControlUnitResourceRepository, private val dbMissionRepository: IDBMissionRepository, private val mapper: ObjectMapper, @@ -112,20 +114,40 @@ class JpaMissionRepository( // Create an `[id] → ControlUnitResourceModel` map val controlUnitResourceModelMap = controlUnitResourceModels.associateBy { requireNotNull(it.id) } - // get a list of all controlPlanSubThemes ids used in the mission - val controlPlanSubThemes = mission.envActions?.flatMap { it.controlPlanSubThemes?.map { id -> id.subThemeId } ?: emptyList() }?.distinct() - // Create a map from controlPlanSubThemes maping each id to a reference to the model - val controlPlanSubThemesReferenceModelMap = controlPlanSubThemes?.associateWith { id -> - dbControlPlanSubThemeRepository.getReferenceById( - id, - ) + val controlPlanThemes = MutableList() + val controlPlanSubThemes = MutableList() + val controlPlanTags = MutableList() + for (envAction in mission.envActions ?: emptyList()) { + for (controlPlan in envAction.controlPlans ?: emptyList()) { + // get a list of all controlPlanTheme ids used in the mission's envActions + controlPlanThemes.add(controlPlan.themeId ?: continue) + // get a list of all controlPlanSubThemes ids used in the mission's envActions + controlPlanSubThemes.addAll(controlPlan.subThemeIds ?: emptyList()) + // get a list of all controlPlanTags ids used in the mission's envActions + controlPlanTags.addAll(controlPlan.tagIds ?: emptyList()) + } + } + + // Create a map from controlPlanThemes mapping each id to a reference to the model + val controlPlanThemesReferenceModelMap = controlPlanThemes?.distinct()?.associateWith { id -> + dbControlPlanThemeRepository.getReferenceById(id) + } + // Create a map from controlPlanSubThemes mapping each id to a reference to the model + val controlPlanSubThemesReferenceModelMap = controlPlanSubThemes?.distinct()?.associateWith { id -> + dbControlPlanSubThemeRepository.getReferenceById(id) + } + // Create a map from controlPlanTags mapping each id to a reference to the model + val controlPlanTagsReferenceModelMap = controlPlanTags?.distinct()?.associateWith { id -> + dbControlPlanTagRepository.getReferenceById(id) } val missionModel = MissionModel.fromMissionEntity( mission = mission, mapper = mapper, controlUnitResourceModelMap = controlUnitResourceModelMap, + controlPlanThemesReferenceModelMap = controlPlanThemesReferenceModelMap ?: emptyMap(), controlPlanSubThemesReferenceModelMap = controlPlanSubThemesReferenceModelMap ?: emptyMap(), + controlPlanTagsReferenceModelMap = controlPlanTagsReferenceModelMap ?: emptyMap(), ) return dbMissionRepository.saveAndFlush(missionModel).toMissionDTO(mapper) } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt new file mode 100644 index 000000000..66fb3fb5f --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt @@ -0,0 +1,6 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces + +import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanTagModel +import org.springframework.data.jpa.repository.JpaRepository + +interface IDBControlPlanTagRepository : JpaRepository diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index bb4f0cb25..ffecc3ecd 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -21,11 +21,14 @@ CREATE TABLE control_plan_tags ( ); CREATE TABLE env_actions_control_plan_sub_themes ( - env_action_id uuid, - subtheme_id integer, - foreign key (env_action_id) references env_actions(id), - foreign key (subtheme_id) references control_plan_subthemes(id), - primary key (env_action_id, subtheme_id) + id serial PRIMARY KEY, + env_action_id uuid, + theme_id integer NOT NULL, + subtheme_id integer, + foreign key (env_action_id) references env_actions(id), + foreign key (theme_id) references control_plan_themes(id), + foreign key (subtheme_id) references control_plan_subthemes(id), + unique (env_action_id, theme_id, subtheme_id) ); CREATE TABLE env_actions_control_plan_tags ( @@ -36,7 +39,18 @@ CREATE TABLE env_actions_control_plan_tags ( primary key (env_action_id, tag_id) ); +CREATE TABLE reportings_control_plan_sub_themes ( + id serial PRIMARY KEY, + reporting_id id, + theme_id integer NOT NULL, + subtheme_id integer, + foreign key (reporting_id) references reportings(id), + foreign key (theme_id) references control_plan_themes(id), + foreign key (subtheme_id) references control_plan_subthemes(id), + unique (reporting_id, theme_id, subtheme_id) +); +COMMENT ON TABLE reportings_control_plan_sub_themes IS 'Table de jointure entre les signalements et les sous-thèmes du plan de contrôle'; COMMENT ON TABLE control_plan_themes IS 'Table des thèmes du plan de contrôle'; COMMENT ON TABLE control_plan_subthemes IS 'Table des sous-thèmes du plan de contrôle versionnés par année'; COMMENT ON TABLE control_plan_tags IS 'Table des tags du plan de contrôle reliés aux thématiques'; @@ -107,14 +121,6 @@ WITH themes AS ( --- Signalements -CREATE TABLE reportings_control_plan_sub_themes ( - reporting_id uuid, - subtheme_id integer, - foreign key (reporting_id) references reportings(id), - foreign key (subtheme_id) references control_plan_subthemes(id), - primary key (reporting_id, subtheme_id) -); -COMMENT ON TABLE reportings_control_plan_sub_themes IS 'Table de jointure entre les signalements et les sous-thèmes du plan de contrôle'; INSERT INTO reportings_control_plan_sub_themes (reporting_id, subtheme_id) WITH reportingthemes AS ( SELECT id, diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt similarity index 83% rename from backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt rename to backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt index 3b457c9d5..ab966d9f3 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt @@ -1,4 +1,4 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan import com.nhaarman.mockitokotlin2.given import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity @@ -17,14 +17,14 @@ class GetControlPlanSubThemesByYearUTest { val controlPlanSubThemes = listOf( ControlPlanSubThemeEntity( id = 1, - theme = "ControlPlanTheme Name", + theme = "ControlPlanThemeEntity Name", subTheme = "ControlPlanSubTheme Name", allowedTags = listOf("tag1", "tag2"), year = 2023, ), ControlPlanSubThemeEntity( id = 2, - theme = "ControlPlanTheme Name 2", + theme = "ControlPlanThemeEntity Name 2", subTheme = "ControlPlanSubTheme Name 2", allowedTags = null, year = 2023, @@ -33,7 +33,7 @@ class GetControlPlanSubThemesByYearUTest { given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) - val result = GetControlPlanSubThemesByYear(controlPlanSubThemeRepository).execute(2023) + val result = GetControlPlansByYear(controlPlanSubThemeRepository).execute(2023) assertThat(result.size).isEqualTo(2) assertThat(result).isEqualTo(controlPlanSubThemes) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt index 59d8cae7a..9d46374d2 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt @@ -3,7 +3,7 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff import com.nhaarman.mockitokotlin2.verify import fr.gouv.cacem.monitorenv.config.WebSecurityConfig import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity -import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes.GetControlPlanSubThemesByYear +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlansByYear import org.junit.jupiter.api.Test import org.mockito.BDDMockito import org.springframework.beans.factory.annotation.Autowired @@ -22,7 +22,7 @@ class ControlPlanSubThemesControllerITests { private lateinit var mockMvc: MockMvc @MockBean - private lateinit var getControlPlanSubThemesByYear: GetControlPlanSubThemesByYear + private lateinit var getControlPlansByYear: GetControlPlansByYear @Test fun `Should get all control plan themes`() { @@ -34,7 +34,7 @@ class ControlPlanSubThemesControllerITests { allowedTags = listOf("tag1", "tag2"), year = 2024, ) - BDDMockito.given(getControlPlanSubThemesByYear.execute(2024)).willReturn(listOf(ControlPlanSubTheme)) + BDDMockito.given(getControlPlansByYear.execute(2024)).willReturn(listOf(ControlPlanSubTheme)) // When mockMvc.perform(get("/bff/v1/controlPlanSubThemes/2024")) // Then @@ -46,6 +46,6 @@ class ControlPlanSubThemesControllerITests { .andExpect(jsonPath("$[0].allowedTags[0]").value(ControlPlanSubTheme.allowedTags?.get(0))) .andExpect(jsonPath("$[0].allowedTags[1]").value(ControlPlanSubTheme.allowedTags?.get(1))) - verify(getControlPlanSubThemesByYear).execute(2024) + verify(getControlPlansByYear).execute(2024) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt index 257947f1a..bd5b1d16d 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt @@ -344,11 +344,11 @@ class MissionsControllerITests { equalTo("2022-01-23T20:29:03Z"), ), ) - .andExpect(jsonPath("$[0].envActions[0].controlPlanSubThemes[0].id", equalTo(1))) - .andExpect(jsonPath("$[0].envActions[0].controlPlanSubThemes[0].theme", equalTo("Theme 1"))) - .andExpect(jsonPath("$[0].envActions[0].controlPlanSubThemes[0].subTheme", equalTo("sous theme 1"))) - .andExpect(jsonPath("$[0].envActions[0].controlPlanSubThemes[0].tags[0]", equalTo("tag 1"))) - .andExpect(jsonPath("$[0].envActions[0].controlPlanSubThemes[0].tags[1]", equalTo("tag 2"))) + .andExpect(jsonPath("$[0].envActions[0].controlPlan[0].id", equalTo(1))) + .andExpect(jsonPath("$[0].envActions[0].controlPlan[0].theme", equalTo("Theme 1"))) + .andExpect(jsonPath("$[0].envActions[0].controlPlan[0].subTheme", equalTo("sous theme 1"))) + .andExpect(jsonPath("$[0].envActions[0].controlPlan[0].tags[0]", equalTo("tag 1"))) + .andExpect(jsonPath("$[0].envActions[0].controlPlan[0].tags[1]", equalTo("tag 2"))) .andExpect(jsonPath("$[0].envActions[0].geom.type", equalTo("Point"))) .andExpect(jsonPath("$[0].envActions[0].facade", equalTo("Outre-Mer"))) .andExpect(jsonPath("$[0].envActions[0].department", equalTo("29"))) @@ -668,11 +668,11 @@ class MissionsControllerITests { equalTo("2022-01-23T20:29:03Z"), ), ) - .andExpect(jsonPath("$.envActions[0].controlPlanSubThemes[0].id", equalTo(1))) - .andExpect(jsonPath("$.envActions[0].controlPlanSubThemes[0].subTheme", equalTo("sous theme 1"))) - .andExpect(jsonPath("$.envActions[0].controlPlanSubThemes[0].tags[0]", equalTo("tag 1"))) - .andExpect(jsonPath("$.envActions[0].controlPlanSubThemes[0].tags[1]", equalTo("tag 2"))) - .andExpect(jsonPath("$.envActions[0].controlPlanSubThemes[0].theme", equalTo("Theme 1"))) + .andExpect(jsonPath("$.envActions[0].controlPlan[0].id", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlan[0].subTheme", equalTo("sous theme 1"))) + .andExpect(jsonPath("$.envActions[0].controlPlan[0].tags[0]", equalTo("tag 1"))) + .andExpect(jsonPath("$.envActions[0].controlPlan[0].tags[1]", equalTo("tag 2"))) + .andExpect(jsonPath("$.envActions[0].controlPlan[0].theme", equalTo("Theme 1"))) .andExpect(jsonPath("$.envActions[0].geom.type", equalTo("Point"))) .andExpect(jsonPath("$.envActions[0].facade", equalTo("Outre-Mer"))) .andExpect(jsonPath("$.envActions[0].department", equalTo("29"))) From 213d3662dc3050f778321bdcba1acfabd4ff7a1b Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:50 +0100 Subject: [PATCH 15/53] backend for control_plans api & envActions.controlPlans --- .../repositories/IControlPlanTagRepository.kt | 2 +- .../IControlPlanThemeRepository.kt | 7 ++ .../controlPlan/GetControlPlansByYear.kt | 8 +- .../endpoints/bff/ControlPlansController.kt | 10 ++- .../model/ControlPlanSubThemeModel.kt | 4 +- .../database/model/ControlPlanTagModel.kt | 7 +- .../database/model/ControlPlanThemeModel.kt | 19 ++++- .../database/model/EnvActionModel.kt | 58 +++++++++---- .../EnvActionsControlPlanSubThemeModel.kt | 18 ---- .../model/EnvActionsControlPlanTagModel.kt | 7 +- .../model/EnvActionsControlPlanThemeModel.kt | 77 +++++++++++++++++ .../JpaControlPlanSubThemeRepository.kt | 2 +- .../JpaControlPlanTagRepository.kt | 15 ++++ .../JpaControlPlanThemeRepository.kt | 15 ++++ .../repositories/JpaMissionRepository.kt | 8 +- .../interfaces/IDBControlPlanTagRepository.kt | 16 +++- .../IDBControlPlanThemeRepository.kt | 19 +++++ .../internal/V0.103__create_action_theme.sql | 32 ++++++-- ...6.08__insert_dummy_control_plan_themes.sql | 25 ++---- .../V666.09__insert_dummy_missions.sql | 2 +- .../V666.10__insert_dummy_env_actions.sql | 38 ++++++--- .../GetControlPlanSubThemesByYearUTest.kt | 41 ---------- .../controlPlan/GetControlPlansByYearUTest.kt | 73 +++++++++++++++++ .../ControlPlanSubThemesControllerITests.kt | 51 ------------ .../bff/ControlPlansControllerITests.kt | 72 ++++++++++++++++ .../endpoints/bff/MissionsControllerITests.kt | 63 ++++++-------- .../JpaControlPlanSubThemeRepositoryITests.kt | 18 ++-- .../JpaMissionRepositoryITests.kt | 82 ++++++++----------- 28 files changed, 502 insertions(+), 287 deletions(-) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanThemeModel.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt delete mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt delete mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt index dae4b69d0..f4c54a1c5 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt @@ -3,5 +3,5 @@ package fr.gouv.cacem.monitorenv.domain.repositories import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity interface IControlPlanTagRepository { - fun findAll(): List + fun findByYear(year: Int): List } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt new file mode 100644 index 000000000..4724bc020 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt @@ -0,0 +1,7 @@ +package fr.gouv.cacem.monitorenv.domain.repositories + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity + +interface IControlPlanThemeRepository { + fun findByYear(year: Int): List +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt index 3cbf4304b..86d65775e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt @@ -5,6 +5,8 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeE import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanTagRepository +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository import org.slf4j.LoggerFactory @UseCase @@ -15,11 +17,11 @@ class GetControlPlansByYear( ) { private val logger = LoggerFactory.getLogger(GetControlPlansByYear::class.java) fun execute(year: Int): ControlPlanByYear { - val controlPlanThemes = getControlPlanThemes(year) + val controlPlanThemes = controlPlanThemeRepository.findByYear(year) val controlPlanSubThemes = controlPlanSubThemeRepository.findByYear(year) - val controlPlanTags = controlPlanSubThemes.map { it.allowedTags }.flatten().toSet() + val controlPlanTags = controlPlanTagRepository.findByYear(year) logger.info("Found ${controlPlanSubThemes.size} control plan subthemes for year $year") - return Triple(controlPlanSubThemes, controlPlanTags, controlPlanThemes) + return Triple(controlPlanThemes, controlPlanSubThemes, controlPlanTags) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt index 63a118281..480e8fb4b 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt @@ -23,8 +23,12 @@ class ControlPlansController( @PathParam("validity year of the control plan themes") @PathVariable(name = "year") year: Int, - ): List { - val controlPlanSubThemes = getControlPlansByYear.execute(year) - return controlPlanSubThemes.map { ControlPlanDataOutput.fromControlPlanEntity(it) } + ): ControlPlanDataOutput { + val controlPlan = getControlPlansByYear.execute(year) + return ControlPlanDataOutput.fromControlPlanEntities( + themes = controlPlan.first, + subThemes = controlPlan.second, + tags = controlPlan.third, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt index 733bb2578..5458bae6b 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt @@ -36,10 +36,10 @@ class ControlPlanSubThemeModel( val year: Int, ) { - fun toControlPlanSubTheme() = ControlPlanSubThemeEntity( + fun toControlPlanSubThemeEntity() = ControlPlanSubThemeEntity( id = id, + themeId = controlPlanTheme.id, subTheme = subTheme, - theme = controlPlanTheme.theme, year = year, ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt index dd0e20ab4..bd5c9b9cb 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt @@ -33,9 +33,10 @@ class ControlPlanTagModel( val tag: String, ) { - fun toControlPlanTag() = ControlPlanTagEntity( - id = id, - tag = tag, + fun toControlPlanTagEntity() = ControlPlanTagEntity( + id = this.id, + tag = this.tag, + themeId = this.controlPlanTheme.id, ) override fun equals(other: Any?): Boolean { diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanThemeModel.kt index fb8073108..6016cc6a1 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanThemeModel.kt @@ -1,9 +1,11 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.model +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity import jakarta.persistence.Column import jakarta.persistence.Entity import jakarta.persistence.Id import jakarta.persistence.Table +import org.hibernate.Hibernate @Entity @Table(name = "control_plan_themes") @@ -13,4 +15,19 @@ data class ControlPlanThemeModel( val id: Int, @Column(name = "theme") val theme: String, -) +) { + fun toControlPlanThemeEntity() = ControlPlanThemeEntity( + id = id, + theme = theme, + ) + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false + other as ControlPlanThemeModel + + return id == other.id + } + + override fun hashCode(): Int = javaClass.hashCode() +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt index 006505d1d..e027bca8c 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt @@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.annotation.JsonSerialize import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionEntity import fr.gouv.cacem.monitorenv.domain.mappers.EnvActionMapper import io.hypersistence.utils.hibernate.type.json.JsonBinaryType @@ -94,6 +95,14 @@ class EnvActionModel( @JsonManagedReference val attachedReporting: List? = listOf(), + @OneToMany( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + orphanRemoval = true, + mappedBy = "envAction", + ) + val controlPlanThemes: MutableList? = ArrayList(), + @OneToMany( fetch = FetchType.EAGER, cascade = [CascadeType.ALL], @@ -112,14 +121,21 @@ class EnvActionModel( ) { fun toActionEntity(mapper: ObjectMapper): EnvActionEntity { + val controlPlans = controlPlanThemes?.map { it -> + EnvActionControlPlanEntity( + themeId = it.id.themeId, + subThemeIds = controlPlanSubThemes?.filter { subTheme -> it.id.themeId == subTheme.controlPlanSubTheme?.controlPlanTheme?.id }?.map { it.id.subthemeId }, + tagIds = controlPlanTags?.filter { tag -> it.id.themeId == tag.controlPlanTag?.controlPlanTheme?.id }?.map { it.id.tagId }, + ) + } + return EnvActionMapper.getEnvActionEntityFromJSON( mapper = mapper, id = id, actionEndDateTimeUtc = actionEndDateTime?.atZone(UTC), actionType = actionType, actionStartDateTimeUtc = actionStartDateTime?.atZone(UTC), - controlPlanSubThemes = controlPlanSubThemes?.map { it.toEnvActionControlPlanSubThemeEntity() }, - controlPlanTags = controlPlanTags?.map { it.toEnvActionControlPlanTagEntity() }, + controlPlans = controlPlans, department = department, facade = facade, geom = geom, @@ -140,7 +156,7 @@ class EnvActionModel( controlPlanTagsReferenceModelMap: Map, mapper: ObjectMapper, ): EnvActionModel { - var envActionModel = EnvActionModel( + val envActionModel = EnvActionModel( id = action.id, actionEndDateTime = action.actionEndDateTimeUtc?.toInstant(), actionType = action.actionType, @@ -157,21 +173,29 @@ class EnvActionModel( geom = action.geom, value = EnvActionMapper.envActionEntityToJSON(mapper, action), ) - action.controlPlans?.map { - val envActionControlPlanSubThemeModel = EnvActionsControlPlanSubThemeModel.fromEnvActionControlPlanSubThemeEntity( - envAction = envActionModel, - controlPlanSubTheme = controlPlanSubThemesReferenceModelMap[it.subThemeId]!!, - ) - envActionModel.controlPlanSubThemes?.add( - envActionControlPlanSubThemeModel, - ) - val envActionControlPlanTagModel = EnvActionsControlPlanTagModel.fromEnvActionControlPlanTagEntity( - envAction = envActionModel, - controlPlanTag = controlPlanTagsReferenceModelMap[it.subThemeId]!!, - ) - envActionModel.controlPlanTags?.add( - envActionControlPlanTagModel, + action.controlPlans?.forEach { + envActionModel.controlPlanThemes?.add( + EnvActionsControlPlanThemeModel.fromEnvActionControlPlanThemeEntity( + envAction = envActionModel, + controlPlanTheme = controlPlanThemesReferenceModelMap[it.themeId]!!, + ), ) + it.subThemeIds?.forEach { subThemeId -> + envActionModel.controlPlanSubThemes?.add( + EnvActionsControlPlanSubThemeModel.fromEnvActionControlPlanSubThemeEntity( + envAction = envActionModel, + controlPlanSubTheme = controlPlanSubThemesReferenceModelMap[subThemeId]!!, + ), + ) + } + it.tagIds?.forEach { tagId -> + envActionModel.controlPlanTags?.add( + EnvActionsControlPlanTagModel.fromEnvActionControlPlanTagEntity( + envAction = envActionModel, + controlPlanTag = controlPlanTagsReferenceModelMap[tagId]!!, + ), + ) + } } return envActionModel } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt index 11612e7c3..b4797dbb7 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt @@ -1,7 +1,5 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.model -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity -import io.hypersistence.utils.hibernate.type.array.ListArrayType import jakarta.persistence.Column import jakarta.persistence.Embeddable import jakarta.persistence.EmbeddedId @@ -12,7 +10,6 @@ import jakarta.persistence.ManyToOne import jakarta.persistence.MapsId import jakarta.persistence.Table import org.hibernate.Hibernate -import org.hibernate.annotations.Type import java.io.Serializable import java.util.UUID @@ -32,15 +29,11 @@ class EnvActionsControlPlanSubThemeModel( @JoinColumn(name = "subtheme_id") val controlPlanSubTheme: ControlPlanSubThemeModel? = null, - @Column(name = "tags") - @Type(ListArrayType::class) - val tags: List? = null, ) { companion object { fun fromEnvActionControlPlanSubThemeEntity( envAction: EnvActionModel, controlPlanSubTheme: ControlPlanSubThemeModel, - tags: List? = null, ) = EnvActionsControlPlanSubThemeModel( id = EnvActionsSubThemePk( envActionId = envAction.id!!, @@ -48,17 +41,6 @@ class EnvActionsControlPlanSubThemeModel( ), envAction = envAction, controlPlanSubTheme = controlPlanSubTheme, - tags = tags, - ) - } - - fun toEnvActionControlPlanSubThemeEntity(): EnvActionControlPlanSubThemeEntity { - require(controlPlanSubTheme != null) { "controlPlanSubTheme must not be null when converting to Entity" } - return EnvActionControlPlanSubThemeEntity( - subThemeId = controlPlanSubTheme.id, - subTheme = controlPlanSubTheme.subTheme, - theme = controlPlanSubTheme.controlPlanTheme.theme, - themeId = controlPlanSubTheme.controlPlanTheme.id, ) } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt index 60d5582ac..a3cdf267a 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt @@ -44,11 +44,6 @@ class EnvActionsControlPlanTagModel( ) } - fun toEnvActionControlPlanTagEntity() { - require(controlPlanTag != null) { "controlPlanTag must not be null when converting to Entity" } - return - } - override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false @@ -65,7 +60,7 @@ data class EnvActionsTagPk( @Column(name = "env_action_id") val envActionId: UUID, - @Column(name = "subtheme_id") + @Column(name = "tag_id") val tagId: Int, ) : Serializable { override fun equals(other: Any?): Boolean { diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanThemeModel.kt new file mode 100644 index 000000000..a505117f3 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanThemeModel.kt @@ -0,0 +1,77 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.model + +import jakarta.persistence.Column +import jakarta.persistence.Embeddable +import jakarta.persistence.EmbeddedId +import jakarta.persistence.Entity +import jakarta.persistence.FetchType +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne +import jakarta.persistence.MapsId +import jakarta.persistence.Table +import org.hibernate.Hibernate +import java.io.Serializable +import java.util.UUID + +@Entity +@Table(name = "env_actions_control_plan_themes") +class EnvActionsControlPlanThemeModel( + @EmbeddedId + val id: EnvActionsThemePk, + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("envActionId") + @JoinColumn(name = "env_action_id") + val envAction: EnvActionModel? = null, + + @ManyToOne(fetch = FetchType.EAGER) + @MapsId("themeId") + @JoinColumn(name = "theme_id") + val controlPlanTheme: ControlPlanThemeModel? = null, + +) { + companion object { + fun fromEnvActionControlPlanThemeEntity( + envAction: EnvActionModel, + controlPlanTheme: ControlPlanThemeModel, + ) = EnvActionsControlPlanThemeModel( + id = EnvActionsThemePk( + envActionId = envAction.id!!, + themeId = controlPlanTheme.id!!, + ), + envAction = envAction, + controlPlanTheme = controlPlanTheme, + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false + other as EnvActionsControlPlanThemeModel + + return id == other.id + } + + override fun hashCode(): Int = javaClass.hashCode() +} + +@Embeddable +data class EnvActionsThemePk( + @Column(name = "env_action_id") + val envActionId: UUID, + + @Column(name = "theme_id") + val themeId: Int, +) : Serializable { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is EnvActionsThemePk) return false + + return envActionId == other.envActionId && + themeId == other.themeId + } + + override fun hashCode(): Int { + return listOf(envActionId, themeId).hashCode() + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt index 08ff75418..47ce1b298 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt @@ -10,6 +10,6 @@ class JpaControlPlanSubThemeRepository( private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, ) : IControlPlanSubThemeRepository { override fun findByYear(year: Int): List { - return dbControlPlanSubThemeRepository.findByYearOrderById(year).map { it.toControlPlanSubTheme() } + return dbControlPlanSubThemeRepository.findByYearOrderById(year).map { it.toControlPlanSubThemeEntity() } } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt new file mode 100644 index 000000000..6192c7586 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt @@ -0,0 +1,15 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanTagRepository +import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanTagRepository +import org.springframework.stereotype.Repository + +@Repository +class JpaControlPlanTagRepository( + private val dbControlPlanTagRepository: IDBControlPlanTagRepository, +) : IControlPlanTagRepository { + override fun findByYear(year: Int): List { + return dbControlPlanTagRepository.findByYearOrderById(year).map { it.toControlPlanTagEntity() } + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt new file mode 100644 index 000000000..ee9ef244b --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt @@ -0,0 +1,15 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository +import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanThemeRepository +import org.springframework.stereotype.Repository + +@Repository +class JpaControlPlanThemeRepository( + private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, +) : IControlPlanThemeRepository { + override fun findByYear(year: Int): List { + return dbControlPlanThemeRepository.findByYearOrderById(year).map { it.toControlPlanThemeEntity() } + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt index 9f610cea7..92c4d8abf 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt @@ -8,6 +8,7 @@ import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO import fr.gouv.cacem.monitorenv.infrastructure.database.model.MissionModel import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanSubThemeRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanTagRepository +import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanThemeRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlUnitResourceRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBMissionRepository import org.springframework.data.domain.Pageable @@ -18,6 +19,7 @@ import java.time.Instant @Repository class JpaMissionRepository( + private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, private val dbControlPlanTagRepository: IDBControlPlanTagRepository, private val dbControlUnitResourceRepository: IDBControlUnitResourceRepository, @@ -114,9 +116,9 @@ class JpaMissionRepository( // Create an `[id] → ControlUnitResourceModel` map val controlUnitResourceModelMap = controlUnitResourceModels.associateBy { requireNotNull(it.id) } - val controlPlanThemes = MutableList() - val controlPlanSubThemes = MutableList() - val controlPlanTags = MutableList() + val controlPlanThemes = ArrayList() + val controlPlanSubThemes = ArrayList() + val controlPlanTags = ArrayList() for (envAction in mission.envActions ?: emptyList()) { for (controlPlan in envAction.controlPlans ?: emptyList()) { // get a list of all controlPlanTheme ids used in the mission's envActions diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt index 66fb3fb5f..64edcc252 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt @@ -2,5 +2,19 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanTagModel import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Query -interface IDBControlPlanTagRepository : JpaRepository +interface IDBControlPlanTagRepository : JpaRepository { + @Query( + value = """ + SELECT tags.* + FROM control_plan_tags tags, control_plan_sub_themes s, control_plan_themes th + WHERE tags.theme_id = th.id + AND th.id = s.theme_id + AND s.year = :year + ORDER BY tags.id ASC + """, + nativeQuery = true, + ) + fun findByYearOrderById(year: Int): List +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt new file mode 100644 index 000000000..f3bd070af --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt @@ -0,0 +1,19 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces + +import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanThemeModel +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Query + +interface IDBControlPlanThemeRepository : JpaRepository { + @Query( + value = """ + SELECT th.* + FROM control_plan_themes th, control_plan_sub_themes s + WHERE th.id = s.theme_id + AND s.year = :year + ORDER BY th.id ASC + """, + nativeQuery = true, + ) + fun findByYearOrderById(year: Int): List +} diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index ffecc3ecd..2de08e4f2 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -20,15 +20,20 @@ CREATE TABLE control_plan_tags ( theme_id int REFERENCES control_plan_themes(id) ); +CREATE TABLE env_actions_control_plan_themes ( + env_action_id uuid, + theme_id integer NOT NULL, + foreign key (env_action_id) references env_actions(id), + foreign key (theme_id) references control_plan_themes(id), + primary key (env_action_id, theme_id) +); + CREATE TABLE env_actions_control_plan_sub_themes ( - id serial PRIMARY KEY, env_action_id uuid, - theme_id integer NOT NULL, subtheme_id integer, foreign key (env_action_id) references env_actions(id), - foreign key (theme_id) references control_plan_themes(id), foreign key (subtheme_id) references control_plan_subthemes(id), - unique (env_action_id, theme_id, subtheme_id) + primary key (env_action_id, subtheme_id) ); CREATE TABLE env_actions_control_plan_tags ( @@ -41,7 +46,7 @@ CREATE TABLE env_actions_control_plan_tags ( CREATE TABLE reportings_control_plan_sub_themes ( id serial PRIMARY KEY, - reporting_id id, + reporting_id integer, theme_id integer NOT NULL, subtheme_id integer, foreign key (reporting_id) references reportings(id), @@ -74,7 +79,20 @@ INSERT INTO control_plan_tags (theme_id, tag) WHERE t.theme = 'Police des espèces protégées et de leurs habitats (faune et flore)' ; --- Insertion des données depuis les env actions dans la table env_actions_control_plan_sub_themes +-- EnvActions: Insertion des données depuis les env actions dans la table env_actions_control_plan_themes +INSERT INTO env_actions_control_plan_themes (env_action_id, theme_id) +WITH themes AS ( + SELECT + id as env_action_id, + jsonb_array_elements(value->'themes')->>'theme' as theme +FROM env_actions + ) +SELECT themes.env_action_id, th.id +FROM themes, + control_plan_themes th +WHERE th.theme = themes.theme +; +-- EnvActions: Insertion des données depuis les env actions dans la table env_actions_control_plan_sub_themes INSERT INTO env_actions_control_plan_sub_themes (env_action_id, subtheme_id) WITH themes AS ( SELECT @@ -92,7 +110,7 @@ INSERT INTO env_actions_control_plan_sub_themes (env_action_id, subtheme_id) AND th.theme = themes.theme AND sbt.year = 2023; --- tags +-- EnvActions: Insertion des données depuis les env actions dans la table env_actions_control_plan_tags INSERT INTO env_actions_control_plan_tags (env_action_id, tag_id) WITH themes AS ( SELECT diff --git a/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql b/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql index d06a6fdb2..0eb8fb447 100644 --- a/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql +++ b/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql @@ -2,22 +2,13 @@ INSERT INTO control_plan_themes (id, theme) VALUES (100001, 'Mouillage Individuel'); INSERT INTO control_plan_themes (id, theme) VALUES (100002, 'Rejet'); -INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage réglementé par arrêté', null, 100001, 2024); -INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage réglementé par AMP', null, 100001, 2024); -INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) VALUES ('Mouillage avec AOT individuelle', null, 100001, 2024); -INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) VALUES ('Autre mouillage', null, 100001, 2024); -INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) VALUES ('Jet de déchet (macro déchet)', null, 100002, 2024); - -INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) - SELECT 'Destruction, capture, arrachage', null, id, 2024 +INSERT INTO control_plan_subthemes (subtheme, theme_id, year) VALUES ('Mouillage réglementé par arrêté', 100001, 2024); +INSERT INTO control_plan_subthemes (subtheme, theme_id, year) VALUES ('Mouillage réglementé par AMP', 100001, 2024); +INSERT INTO control_plan_subthemes (subtheme, theme_id, year) VALUES ('Mouillage avec AOT individuelle', 100001, 2024); +INSERT INTO control_plan_subthemes (subtheme, theme_id, year) VALUES ('Autre mouillage', 100001, 2024); +INSERT INTO control_plan_subthemes (subtheme, theme_id, year) VALUES ('Jet de déchet (macro déchet)', 100002, 2024); + +INSERT INTO control_plan_subthemes (subtheme, theme_id, year) + SELECT 'Destruction, capture, arrachage', id, 2024 FROM control_plan_themes WHERE theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; - -INSERT INTO control_plan_subthemes (subtheme, allowed_tags, theme_id, year) - SELECT 'Atteinte aux habitats d’espèces protégées', - '{"Oiseaux", "Faune", "Flore", "Autres espèces protégées", "Reptiles", "Mammifères marins"}', - id, - 2024 - FROM control_plan_themes - WHERE theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; - diff --git a/backend/src/main/resources/db/testdata/V666.09__insert_dummy_missions.sql b/backend/src/main/resources/db/testdata/V666.09__insert_dummy_missions.sql index 105989439..cf7ff7ffc 100644 --- a/backend/src/main/resources/db/testdata/V666.09__insert_dummy_missions.sql +++ b/backend/src/main/resources/db/testdata/V666.09__insert_dummy_missions.sql @@ -7,7 +7,7 @@ INSERT INTO public.missions (id, open_by, observations_cacem, facade, start_date INSERT INTO public.missions (id, open_by, observations_cacem, facade, start_datetime_utc, end_datetime_utc, geom, closed_by, deleted, observations_cnsp, mission_source, closed, mission_order, mission_types) VALUES (13, 'TYL', 'Receive hit themselves. Example community suggest seek to technology.', 'NAMO', '2022-02-07 04:16:43', '2022-07-10 19:55:50', NULL, 'ROB', false, NULL, 'MONITORENV', false, NULL, '{LAND}'); INSERT INTO public.missions (id, open_by, observations_cacem, facade, start_datetime_utc, end_datetime_utc, geom, closed_by, deleted, observations_cnsp, mission_source, closed, mission_order, mission_types) VALUES (19, 'SCO', 'Difficult ahead let really old around. Cover operation seven surface use show. Manage beautiful reason account prepare evening sure.', 'NAMO', '2022-06-21 13:24:04', '2022-07-18 02:49:08', NULL, 'EDW', false, NULL, 'MONITORENV', false, NULL, '{SEA}'); INSERT INTO public.missions (id, open_by, observations_cacem, facade, start_datetime_utc, end_datetime_utc, geom, closed_by, deleted, observations_cnsp, mission_source, closed, mission_order, mission_types) VALUES (20, 'CAS', 'South add memory sing population. Entire particularly deep yard avoid. According cell reason entire group accept.', 'MED', '2022-06-18 08:08:01', '2022-08-09 02:29:02', NULL, 'SAR', false, NULL, 'MONITORENV', false, NULL, '{LAND}'); -INSERT INTO public.missions (id, open_by, observations_cacem, facade, start_datetime_utc, end_datetime_utc, geom, closed_by, deleted, observations_cnsp, mission_source, closed, mission_order, mission_types) VALUES (10, 'KIM', 'Remain vote several ok. Bring American play woman challenge. Throw low law positive seven.', 'NAMO', '2022-03-21 12:11:13', NULL, '0106000020E610000001000000010300000001000000D1070000A1B7FCB073F913C06DC43824DA364840C058840772F913C032E863C2D83648402CF3776B70F913C0D9186460D7364840E586D7DC6EF913C0F2CF4EFED5364840EC13A35B6DF913C07B0D249CD4364840409ADAE76BF913C0E757CE39D3364840E1197E816AF913C053A278D7D136484059C6E12769F913C0A1F9F774D036484095385DDC67F913C0EF507712CF3648401FA4449E66F913C020B5CBAFCD3648407F3CEC6C65F913C0C19F0A4DCC364840A39AAB4964F913C0638A49EACA36484015F2D63363F913C0E6815D87C93648405D76C22A62F913C06A797124C836484069C0C52F61F913C05FF76FC1C63648404C37894160F913C0C5FB585EC5364840F37364615FF913C09C862CFBC336484070DDFF8D5EF913C073110098C2364840B20CB3C85DF913C0BB22BE34C1364840CA6826105DF913C074BA66D1BF364840A78AB1655CF913C02D520F6EBE3648405AD9FCC75BF913C0E7E9B70ABD3648405A21B4375BF913C011084BA7BB3648401F2F83B55AF913C0ADACC843BA364840BA6912405AF913C0485146E0B8364840196AB9D859F913C0E4F5C37CB73648404F97207E59F913C07F9A4119B6364840498A9F3159F913C08CC5A9B5B43648401AAADEF158F913C098F01152B3364840AF8F35C058F913C0A51B7AEEB13648401AA24C9B58F913C023CDCC8AB03648404A7A7B8458F913C02FF83427AF364840507F6A7A58F913C0ADA987C3AD3648401A4A717E58F913C0BAD4EF5FAC364840BB41388F58F913C0C6FF57FCAA36484020FF16AE58F913C044B1AA98A9364840D3B561DA58F913C051DC1235A83648405B996C1359F913C05D077BD1A6364840A9428F5A59F913C06A32E36DA5364840CC1872AE59F913C0765D4B0AA4364840B4B46C105AF913C01202C9A6A2364840EA49D37F5AF913C0ADA64643A1364840F50BFAFB5AF913C0494BC4DF9F364840C59338865BF913C07369577C9E3648406C48371D5CF913C09E87EA189D364840D6C24DC25CF913C0571F93B59B3648408F36D0745DF913C010B73B529A3648401DD712345EF913C058C8F9EE98364840703D6D015FF913C0A1D9B78B9736484099D087DB5FF913C078648B28963648408729BAC360F913C0DE6874C594364840C27B58B961F913C0D2E6726293364840D3FAB6BB62F913C0C76471FF91364840A93F2DCC63F913C04B5C859C9036484055B163E964F913C05DCDAE398F3648404F1C061466F913C0FFB7EDD68D3648400D4DC04C67F913C02F1C42748C364840A1AA3A9268F913C0EEF9AB118B364840820121E569F913C03D512BAF89364840281E1F466BF913C01A22C04C88364840A567DDB36CF913C0856C6AEA863648406EAA072F6EF913C080302A888536484085E69DB76FF913C00A6EFF2584364840EA1BA04D71F913C0B19EFFC3823648409C4A0EF172F913C0E7481562813648409B72E8A174F913C0AD6C40008036484070C7825F76F913C09083969E7E3648400AE2342B78F913C00114023D7D3648407A29A7037AF913C0919798DB7B364840AF3631EA7BF913C0AF94447A7A364840BA707BDD7DF913C05D0B06197936484012A431DE7FF913C0B7EE07B877364840B8D053EC81F913C011D2095776364840ABF6E10784F913C018224CF674364840EB15DC3086F913C0ADEBA395733648400262966688F913C060A826357236484066A7BCA98AF913C0A3DEBED4703648408EB2FAFA8CF913C0918197746F3648408DEAF8588FF913C00F9E85146E364840624FB7C391F913C0ABAD9EB46C364840FC798D3C94F913C0F329F8546B3648406BD123C296F913C0CA1F67F5693648402922265599F913C0BF08019668364840336C94F59BF913C0D1E4C536673648408BAF6EA39EF913C0902DCBD765364840B91F095EA1F913C0DEEFE5786436484035890F26A4F913C0D91E411A63364840FEEB81FBA6F913C0F240C7BB61364840144860DEA9F913C02856785D6036484001D1FECDACF913C00BD869FF5E3648403B5309CBAFF913C00C4D86A15D364840C2CE7FD5B2F913C02AB5CD435C3648402077B6ECB5F913C0F58955E65A364840CB185911B9F913C06DCB1D8959364840C3B36743BCF913C07486FB2B58364840927B3682BFF913C0B6272FCF56364840AE3C71CEC2F913C016BC8D7255364840A12A6C27C6F913C09343171654364840E011D38DC9F913C04DB1F6B9523648406DF2A501CDF913C02412015E51364840D1FF3882D0F913C0A7DF4B025036484082063810D4F913C049A0C1A64E364840093AF7AAD7F913C026478D4B4D364840DD662253DBF913C021E183F04B364840FF8CB908DFF913C05761D0954A364840801365CAE2F913C0ABD4473B49364840C65F289AE6F913C0ACB4FFE047364840E1D8AB76EAF913C0E87A0D8746364840D37EEF5FEEF913C04234462D45364840131E9F56F2F913C0D7D3D4D34336484029EA0E5AF6F913C01AE0A37A4236484015E33E6AFAF913C00859B321413648404ED5DA87FEF913C0A43E03C93F364840D5C0E2B202FA13C07B0AA9703E364840BB0CFFE906FA13C0FF428F183D364840EE51872E0BFA13C02FE8B5C03B3648406F907B800FFA13C09B7332693A364840C6FB2FDF13FA13C0B36BEF1139364840F493A44A18FA13C0074A02BB37364840F758D9C21CFA13C0089555643636484048177A4821FA13C044C6FE0D35364840F9352FDA25FA13C0BCDDFDB733364840F64D50792AFA13C0E0613D6232364840415FDD252FFA13C040CCD20C31364840EBD07EDE33FA13C04DA3A8B72F364840E33B8CA438FA13C024DAE9622E364840B1D359773DFA13C0A77D6B0E2D3648405598E75642FA13C0670743BA2B364840D089354347FA13C0617770662A36484020A8433C4CFA13C098CDF3122936484048F3114251FA13C0090ACDBF27364840BC374C5556FA13C0B72CFC6C2636484090DC9A745BFA13C0A035811A25364840B17A55A160FA13C0C4245CC823364840317924DA65FA13C024FA8C7622364840FF705F206BFA13C04E2F2925213648402CC9AE7270FA13C0B44A1BD41F3648402F4EBED175FA13C0564C63831E3648407FCC393E7BFA13C0333401331D3648402FABC9B680FA13C04B02F5E21B364840B5B6193C86FA13C02E3054931A36484012EF29CE8BFA13C0DBBD1E44193648404454FA6C91FA13C0C4313FF5173648404DE68A1897FA13C0E98BB5A616364840B6D82FD09CFA13C0D745975815364840F4F79494A2FA13C0915FE40A143648400944BA65A8FA13C0855F87BD12364840F4BC9F43AEFA13C0B645807011364840B662452EB4FA13C03F05FA2310364840D668FF24BAFA13C004ABC9D70E364840CD9B7928C0FA13C094B0048C0D364840242F0838C6FA13C0EE15AB400C36484050EF5654CCFA13C012DBBCF50A36484053DC657DD2FA13C0728624AB093648402CF634B3D8FA13C02B0B0D6108364840EDA36CF4DEFA13C020764B1707364840FC4A1043E5FA13C06EBA0ACE053648406A52C89DEBFA13C0F8E41F850436484037BA9404F2FA13C0DBE8B53C03364840DA4E2178F8FA13C0884CB7F40136484054106EF8FEFA13C071960EAD00364840B665238405FB13C04233FC65FF354840EEE7981C0CFB13C04EB63F1FFE354840FC96CEC112FB13C0B41204D9FC3548406AA6187319FB13C056551E93FB3548403716773020FB13C0DFEACE4DFA35484063E6E9F926FB13C0A466D508F935484066E31CD02DFB13C0523572C4F7354840C74064B234FB13C03AEA6480F635484088FEBFA03BFB13C07D78D83CF53548401FE9DB9B42FB13C018E0CCF9F33548409F6760A249FB13C07EA72CB7F2354840F412A5B550FB13C03D480D75F1354840A91EFED457FB13C055C26E33F0354840BE8A6B005FFB13C0389C3BF2EE354840BA8A413766FB13C0754F89B1ED3548408CB7D77A6DFB13C00ADC5771EC354840BE4482CA74FB13C06AC89131EB3548404F3241267CFB13C0B20762F2E93548404080148E83FB13C0C4A69DB3E83548408F2EFC018BFB13C0301F5A75E7354840C7704C8192FB13C0F5709737E6354840D5DF5C0D9AFB13C0149C55FAE4354840CBE2D5A4A1FB13C01A1AAABDE335484020466348A9FB13C0EBF76981E2354840D50905F8B0FB13C016AFAA45E1354840E92DBBB3B8FB13C028B9810AE0354840E5E5D97AC0FB13C0949CD9CFDE35484040FE0C4EC8FB13C05959B295DD354840FB76542DD0FB13C077EF0B5CDC3548409D830418D8FB13C0EF5EE622DB3548409FF0C80EE0FB13C04F2157EAD935484000BEA111E8FB13C008BD48B2D83548404A1FE31FF0FB13C0AAABD07AD7354840F2E0383AF8FB13C0A473D943D63548408336F75F00FC13C0878E780DD5354840FC1F1E9108FC13C0C38298D7D3354840D46959CE10FC13C0595039A2D23548409447FD1619FC13C0D670706DD1354840B385B56B21FC13C03CE43D39D0354840BB57D6CB29FC13C08AAAA105CF354840ABBD5F3732FC13C0314A86D2CD35484083B751AE3AFC13C0C13C01A0CC354840BA11583143FC13C03982126ECB354840D9FFC6BF4BFC13C00AA1A43CCA354840E1819E5954FC13C0C312CD0BC9354840D097DEFE5CFC13C0F350A1DBC73548401F0E33B065FC13C07D68F6ABC6354840DF4B446C6EFC13C0EED2E17CC5354840871DBE3377FC13C04890634EC43548408F4F4C0780FC13C08AA07B20C3354840074997E588FC13C0B5032AF3C135484068D64ACF91FC13C0C7B96EC6C035484028C412C59AFC13C0513C5F9ABF354840597997C5A3FC13C03398D06EBE35484072C284D1ACFC13C08DC0ED43BD354840FCD22EE8B5FC13C0CF3BA119BC354840E643ED0ABFFC13C0FA09EBEFBA354840407C6838C8FC13C09BA4E0C6B935484083484C71D1FC13C025926C9EB835484037DCECB4DAFC13C096D28E76B7354840D303F603E4FC13C07FDF5C4FB635484057BF675EEDFC13C0503FC128B53548404C4296C3F6FC13C009F2BB02B43548402A592D3400FD13C0397162DDB2354840783781AF09FD13C0E1BCB4B8B1354840AFA93D3613FD13C0705B9D94B035484056E3B6C71CFD13C077C63171AF354840E6B0986426FD13C065845C4EAE354840E745370C30FD13C05A88482CAD3548405AA292BE39FD13C0A865B50AAC3548403DC6AA7B43FD13C0FC88E3E9AA354840087E2B444DFD13C0C778BDC9A935484045FD681757FD13C07ABB2DAAA8354840F24363F560FD13C0A4CA498BA735484011521ADE6AFD13C046A6116DA6354840A1278ED174FD13C05E4E854FA5354840A1C4BECF7EFD13C0EDC2A432A43548401329ACD888FD13C0658A5A16A33548406D2102ED92FD13C0E397D1FAA1354840C214690B9DFD13C0D771F4DFA035484087CF8C34A7FD13C04318C3C59F354840BD516D68B1FD13C0268B3DAC9E354840EDCE5EA6BBFD13C080CA63939D35484006E0B8EFC5FD13C0E04F4B7B9C35484018EC2343D0FD13C0B6A1DE639B3548409CBF4BA1DAFD13C004C01D4D9A3548401A8E8409E5FD13C0C9AA08379935484008247A7CEFFD13C006629F219835484068812CFAF9FD13C0485FF70C9735484039A69B8204FE13C00129FBF8953548408DF96F140FFE13C0C038C0E594354840C9E0ACB119FE13C0F61431D39335484088F64E5824FE13C0323763C192354840B8D3AD092FFE13C0E52541B0913548405A78C9C539FE13C09E5AE09F903548407E4B4A8B44FE13C0CE5B2B908F35484013E6875B4FFE13C004A337818E354840194882365AFE13C0B2B6EF728D354840A3D8E11A65FE13C0651069658C3548402664520970FE13C01EB0A3588B3548401AB77F027BFE13C0DD959F4C8A3548400905BE0586FE13C013484741893548407A81611291FE13C04F40B036883548405DC5C1299CFE13C0917EDA2C87354840C237874AA7FE13C0D902C6238635484099710976B2FE13C027CD721B85354840F2D9F0AABDFE13C07BDDE01384354840463DE9E9C8FE13C046BAFA0C83354840939BF232D4FE13C0A656EB0682354840DBF40C86DFFE13C00B399D0181354840A67C8CE2EAFE13C0E8E7FAFC7F3548406AFF1C49F6FE13C05A562FF97E354840B2B012B901FF13C0D10A25F67D354840F35C19330DFF13C04F05DCF37C3548402F0431B718FF13C0D24554F27B354840EDD9AD4424FF13C05CCC8DF17A3548402FDE8FDB2FFF13C07A129EF1793548406ADD827C3BFF13C09E9E6FF278354840290BDB2647FF13C0C97002F477354840E23344DB52FF13C0F98856F676354840A6BE66985EFF13C0BE6081F97535484064449A5F6AFF13C017F882FD74354840A6F8323076FF13C0E85B3002743548406ADB300A82FF13C04E7FB40773354840B1EC93ED8DFF13C049620F0E72354840F3F807DB99FF13C0498B2B1571354840406735D1A5FF13C050FA081D703548401004C8D0B1FF13C0EB28BD256F35484063CFBFD9BDFF13C01B17482F6E35484039C91CECC9FF13C0514B94396D3548401B253307D6FF13C01C3FB7446C354840F77B5A2CE2FF13C07CF2B0506B354840DF343B5AEEFF13C0E1EB6B5D6A354840D34FD590FAFF13C0DCA4FD6A69354840C16580D1060014C06B1D667968354840BBDDE41A130014C08F55A58867354840C0B7026D1F0014C0BAD3A5986635484049C085C82B0014C079117DA965354840DD2AC22C380014C0CC0E2BBB64354840F5C3639A440014C0B5CBAFCD6335484018BFBE10510014C033480BE162354840471CD38F5D0014C045843DF561354840F9A74C186A0014C0EC7F460A61354840B7957FA9760014C0283B2620603548400A19C042830014C0F9B5DC365F354840E0CA65E58F0014C05FF0694E5E354840C2DEC4909C0014C059EACD665D354840AF54DD44A90014C0E8A308805C354840A92CAF01B60014C00D1D1A9A5B354840AE663AC7C20014C055CF17B55A354840BF027F95CF0014C0A2C7D6D059354840DD007D6CDC0014C014F981ED583548408F94884BE90014C0A963190B583548404C8A4D33F60014C0451472295735484016E2CB23030114C003FEB6485635484075CF571C100114C057A7D26855354840DF1E9D1D1D0114C04010C58954354840DF03F0262A0114C04CB2A3AB53354840EA4AFC38370114C0ED1359CE523548408A271653440114C0B2AEFAF1513548403666E975510114C00C09731651354840763ACAA05E0114C08A9CD73B503548404CA4B8D36B0114C09CEF12624F3548402D70600F790114C0D27B3A894E3548402C056A52860114C09DC738B14D35484037FC2C9E930114C08B4C23DA4C354840D788FDF1A00114C00F91E4034C3548400CABDB4DAE0114C04588A72E4B354840D662C7B1BB0114C081C52B5A4A354840BDE3141DC90114C06FB5B18649354840B0C61B91D60114C0F3640EB448354840C172840CE40114C09A4D57E24735484067B4FA8FF10114C0656F8C1147354840A18B7E1BFF0114C0C45098414635484071F80FAF0C0214C0486B9072453548405E2E034A1A0214C07E388AA444354840E0F903ED270214C048C55AD7433548407F8E6697350214C0378B170B43354840B4B8D649430214C0BA10AB3F4235484006ACA803510214C0F048407541354840ED3488C55E0214C04ABAC1AB403548407BBA1D8E6C0214C0C7642FE33F3548409ED5C05E7A0214C0DACE731B3F35484055867137880214C09FEBB9543E354840B333D816960214C08741EC8E3D354840A6764CFEA30214C094D00ACA3C35484040B676ECB10214C0C49815063C3548406E8BAEE2BF0214C0179A0C433B354840435D9CDFCD0214C08FD4EF803A354840ADC497E4DB0214C02A48BFBF39354840BE2849F0E90214C0786E90FF38354840EC555C03F80214C0E9CD4D4038354840C17F251D060314C07E66F781373548402B3FFC3E140314C037388DC4363548403CFB8867220314C0A3BC240836354840F3B3CB96300314C0327AA84C353548403F021CCE3E0314C0E570189234354840BB80760B4D0314C0BCA074D83335484054C832505B0314C04583D21F33354840940CA59B690314C08118326832354840F21979EE770314C0526D68B131354840F7230348860314C064EEB5FB30354840A22A43A8940314C00B2FDA4630354840F42D390FA30314C0652200932F35484064FA907DB10314C071C827E02E35484003F7F2F1BF0314C0A1A73B2E2E35484049F00A6DCE0314C08439517D2D354840ADB284EFDC0314C08A0453CD2C35484040A50878EB0314C04382561E2C3548407A944207FA0314C01F3946702B354840E4B3869C080414C0AFA237C32A3548406B9C2C39170414C0F0BE2A172A35484022B5DCDB250414C056140A6C2935484009FE9684340414C06E1CEBC12835484096430734430414C039D7CD1828354840CA852DEA510414C027CB9C70273548402EF85DA6600414C057EB82C926354840386744696F0414C0AB44552326354840FB3989317E0414C022D7137E25354840650984008D0414C0DB95E9D92435484075D534D69B0414C0B88DAB36243548403E0544B1AA0414C047386F9423354840AD310993B90414C0899534F322354840D5C12C7AC80414C07DA5FB5222354840A44E0668D70414C02468C4B3213548402B3F3E5BE60414C07EDD8E1521354840E25F8054F50414C08A055B7820354840C8B0CC53040514C0BA6613DC1F354840DE312359130514C02CF4E2401F35484024E38364220514C05034B4A61E35484022F84275310514C097AD710D1E354840503D0C8C400514C0215346751D35484037E633A84F0514C05CAB1CDE1C3548404DBF65CA5E0514C0BC3CDF471C3548401BFCF5F16D0514C05DFAB8B21B3548401969901F7D0514C0B16A941E1B354840D03989528C0514C0B78D718B1A3548403F6EE08A9B0514C0706350F919354840670696C8AA0514C0DBEB3068193548404802AA0BBA0514C088A028D818354840582EC854C90514C0E807224918354840A9F198A2D80514C06BA807BB173548402AE573F6E70514C0BFEE192E17354840ED6F014FF70514C0366E18A216354840DF2A99AD060614C060A0181716354840127DE310160614C0CBFE2F8D153548408866E078250614C0E90F4904153548402C80E7E6340614C0494D797C143548401331A159440614C0CCC395F5133548403A790DD1530614C09166C96F133548401B25D84D630614C0973514EB12354840B33401D0720614C050B76067123548408EDBDC56820614C0BBEBAEE411354840A9196BE2910614C0D9D2FE621135484007EFAB72A10614C039E665E2103548401C284B08B10614C0DA25E4621035484074F89CA2C00614C09F9E4EE40F3548400D60A141D00614C034BDE5660F354840E75E58E5DF0614C0EC1469EA0E35484002F5C18DEF0614C0E798036F0E354840E955323AFF0614C02349B5F40D354840871A01EC0E0714C011AC687B0D354840F0A9D6A11E0714C0413B33030D354840129D0A5D2E0714C0237DFF8B0C354840878E991B3E0714C047EBE2150C354840B4E386DF4D0714C01E0CC8A00B354840AC037BA75D0714C03659C42C0B3548406FEE75736D0714C08FD2D7B90A354840737023447D0714C09BFEEC470A354840B88983198D0714C0E95619D70935484050A13EF29C0714C0E9614767093548402B50ACCFAC0714C02B998CF808354840CFC920B1BC0714C0AEFCE88A083548403E0E9C96CC0714C0E412471E08354840EEE9C980DC0714C05B55BCB207354840F2C3526EEC0714C014C4484807354840C068E25FFC0714C00E5FECDE0635484059D878550C0814C0BBAC917606354840BC12164F1C0814C0AA264E0F06354840E917BA4C2C0814C0D9CC21A905354840E1E7644E3C0814C0BC25F743053548402CB66A534C0814C0E0AAE3DF04354840CB82CB5B5C0814C0455CE77C04354840ABE6DE686C0814C0EC39021B04354840677CA1787C0814C0D44334BA0335484065A9168D8C0814C06F00685A033548403F083BA49C0814C04CE9B2FB02354840E33166BFAC0814C06AFE149E02354840DB59ECDDBC0814C0C93F8E41023548402680CDFFCC0814C06AAD1EE601354840C4A40925DD0814C04D47C68B013548402D944C4EED0814C0E2936F320135484072B53E7AFD0814C0478645DA0035484082A137AA0D0914C05F2B1D83003548406EBFDFDC1D0914C0B8FC0B2D00354840ADDBE2122E0914C0E27327D8FF344840C829954B3E0914C0BF9D4484FF344840AE424E884E0914C0DDF37831FF344840708DB6C75E0914C03C76C4DFFE3448400F0ACE096F0914C0DD24278FFE3448400085404F7F0914C0BFFFA03FFE34484045FE0D988F0914C0E30632F1FD34484067A98AE39F0914C0493ADAA3FD3448406486B631B00914C0EF999957FD344840B5613D83C00914C0D825700CFD3448406BA2C7D6D00914C002DE5DC2FC34484075E1AC2DE10914C06DC26279FC3448405B524187F10914C01AD37E31FC3448401DF584E3010A14C00810B2EAFB344840BBC97742120A14C03879FCA4FB34484036D019A4220A14C0A90E5E60FB344840163CBF07330A14C05CD0D61CFB344840D2D9136E430A14C0DF377CDAFA3448406AA917D7530A14C015522399FA344840DFAACA42640A14C01B12F758FA344840B81181B0740A14C0D384CC19FA3448406EAAE620850A14C05C9DCEDBF93448408AA84F93950A14C027E2E79EF934484081D86708A60A14C033531863F9344840DE6D837FB60A14C081F05F28F9344840A068A2F8C60A14C010BABEEEF83448403E957074D70A14C06F294AB6F8344840CB5A96F1E70A14C0814BD77EF834484033526B71F80A14C063139148F834484001AF43F3080B14C087076213F8344840BDA47376190B14C0EC274ADFF734484056CC52FC290B14C0937449ACF7344840DC8C89833A0B14C07BED5F7AF7344840C8B2C30C4B0B14C0340CA349F7344840193E01985B0B14C02E57FD19F7344840CF2E42256C0B14C06ACE6EEBF634484073B8DAB37C0B14C0E771F7BDF634484005DBCA438D0B14C0A6419791F6344840742F6AD69D0B14C035B76366F63448405950B569AE0B14C00559473CF6344840A4D603FFBE0B14C017274213F6344840DDF5A995CF0B14C06A2154EBF534484004AEA72DE00B14C0FF477DC4F534484091CBA8C7F00B14C06514D39EF534484094B55562010C14C00B0D407AF5344840FD0406FF110C14C0F431C456F5344840DC20629C220C14C0ACFC7434F534484021A2C13B330C14C0177A2713F5344840DDEFCCDB430C14C0539D06F3F434484087D62F7D540C14C05F6612D4F43448402056EA1F650C14C01EE21FB6F43448402FA250C3750C14C0AD035A99F43448402C870E68860C14C07D51AB7DF43448401805240E970C14C08FCB1363F43448407B4FE5B4A70C14C071EBA849F43448405466525CB80C14C095375531F43448401C161705C90C14C0FAAF181AF43448405B9287AED90C14C0A154F303F434484011DBA358EA0C14C0189FFAEEF3344840B5BC1704FB0C14C0D11519DBF3344840599E8BAF0B0D14C0CBB84EC8F3344840EC18575C1C0D14C09501B1B6F33448407E9322092D0D14C0A1762AA6F334484087DA99B63D0D14C0EF17BB96F33448407FBA68654E0D14C00C5F7888F3344840FFCD8B135F0D14C06CD24C7BF33448406E7A06C36F0D14C00C72386FF3344840DC268172800D14C0EF3D3B64F3344840C29FA722910D14C0A1AF6A5AF33448401EE579D3A10D14C0954DB151F33448407B2A4C84B20D14C05A91244AF3344840D86F1E35C30D14C0D1879943F334484034B5F0E5D30D14C018243B3EF334484008C76E97E40D14C03066093AF3344840DCD8EC48F50D14C0FB5AD936F334484027B716FB050E14C095F5D534F3344840FAC894AC160E14C00136FF33F3344840CEDA125E270E14C01E292A34F3344840A2EC900F380E14C00CC28135F3344840EDCABAC1480E14C03C87F037F3344840C0DC3873590E14C03CF28B3BF33448401D220B246A0E14C07E893E40F3344840F13389D57A0E14C0014D0846F33448404D795B868B0E14C0C53CE94CF3344840AABE2D379C0E14C05AD2F654F3344840903754E7AC0E14C030941B5EF334484075B07A97BD0E14C0D7FB6C68F3344840E45CF546CE0E14C03016C073F3344840DB3CC4F5DE0E14C05AD63F80F3344840D31C93A4EF0E14C0543CEC8DF3344840DC630A52000F14C000559A9CF3344840E5AA81FF100F14C07D1375ACF3344840EFF1F8AC210F14C0CB777CBDF33448400AA01859320F14C0CB8E85CFF3344840AE818C04430F14C09B4BBBE2F3344840DB9654AF530F14C0AD3408F7F33448401A13C558640F14C08FC3810CF4344840598F3502750F14C02405FD22F4344840AA724EAA850F14C089ECA43AF43448408389BB51960F14C0BF797953F43448406F07D1F7A60F14C0A7B94F6DF4344840E4B83A9DB70F14C05F9F5288F4344840E19DF841C80F14C059B16CA4F4344840791DB3E4D80F14C02469B3C1F4344840119D6D87E90F14C0A0D3FBDFF434484044B72428FA0F14C0EEE370FFF4344840000530C80A1014C07D20FD1FF534484057ED37661B1014C0DC02B641F5344840370994032C1014C07C118664F5344840288C989F3C1014C05F4C6D88F53448402C76453A4D1014C082B36BADF5344840CAFAEED25D1014C0E74681D3F5344840F1B2EC6A6E1014C01D80C3FAF5344840B305E7007F1014C094E51C23F634484087BF89958F1014C04C778D4CF6344840F6132928A01014C046351577F634484076CF70B9B01014C01199C9A2F634484008F26049C11014C01D2995CFF634484035AF4DD7D11014C06AE577FDF634484074D3E263E21014C0F9CD712CF73448404E9274EEF21014C0C9E2825CF7344840C3EB0277031114C06A9DC08DF7344840D2DF8DFD131114C04C8415C0F73448407C6E1582241114C06F9781F3F734484038644505351114C0D4D60428F83448401828C685451114C07B429F5DF83448400A53EF04561114C0F2536694F83448401F4C6981661114C01B182FCCF8344840CFDFDFFB761114C015822405F93448401A0E5374871114C05118313FF934484000D7C2EA971114C0CEDA547AF9344840096E835EA81114C08CC98FB6F9344840AD9F40D0B81114C08CE4E1F3F9344840EC6BFA3FC91114C05CA56032FA344840D83959ACD91114C0DF18E171FA344840D66E6017EA1114C032328EB2FA34484080A50C7FFA1114C038FE3CF4FA344840C576B5E40A1214C00E701837FB3448402E16AF471B1214C0260E0B7BFB3448403150A5A82B1214C07FD814C0FB344840E18B40063C1214C01ACF3506FC344840B5952C614C1214C0F6F16D4DFC344840243A15BA5C1214C01441BD95FC3448403FE0A20F6D1214C073BC23DFFC3448407E5481627D1214C01364A129FD344840E196B0B28D1214C0F5373675FD344840F1DA84FF9D1214C01938E2C1FD34484024EDA949AE1214C07E64A50FFE3448407BCD1F91BE1214C0B336955EFE344840F57BE6D5CE1214C09BBB86AEFE344840A65FA616DF1214C0C56C8FFFFE344840F1DD6255EF1214C0304AAF51FF34484071911890FF1214C0DC53E6A4FF34484016131FC80F1314C0CA8934F9FF3448406796CAFC1F1314C06B72844E00354840641B1B2E301314C0DC0001A500354840866EBC5C401314C08EBB94FC00354840DDF65687501314C0F3282A5501354840574D42AF601314C0293CECAE0135484008D926D3701314C01102B009023548406566B0F3801314C0C96DA065023548406EF5DE10911314C0348C92C2023548402586B22AA11314C0E1D69B2003354840104C7F40B11314C040D4A67F03354840A913F152C11314C06F77DEDF03354840EEDC0762D11314C051CD17410435484069DB176DE11314C0754F68A30435484090DBCC74F11314C0DAFDCF0605354840ED107B78011414C080D84E6B05354840807B2278111414C068DFE4D005354840481BC373211414C003997C3706354840BDBC086C311414C0DF7E2B9F0635484067934760411414C0FC90F10707354840489F7F50511414C0CD55B971073548405DE0B03C611414C0DE4698DC07354840A856DB24711414C031648E48083548402902FF08811414C0C6AD9BB508354840681670E8901414C00DAAAA2309354840542C86C4A01414C096D2D09209354840FFAAE99BB01414C060270E030A354840DF5E466FC01414C0DD2E4D740A3548407E7BF03DD01414C09B62A3E60A35484052CD9308E01414C00C49FB590B354840E58784CEEF1414C0BE5B6ACE0B354840AD776E90FF1414C02321DB430C354840AB9C514E0F1514C0CA1263BA0C354840F05DD6061F1514C0B23002320D3548406B5454BB2E1514C04C01A3AA0D354840A5B31F6B3E1514C028FE5A240E3548409D7B38164E1514C0B7AD149F0E35484053AC9EBC5D1514C08789E51A0F354840C845525E6D1514C00A18B8970F354840FC4753FB7C1514C0CED2A11510354840EEB2A1938C1514C045408D94103548409E863D279C1514C06E607A14113548400DC326B6AB1514C0D9AC7E9511354840C49BB13FBB1514C086259A171235484039DD89C4CA1514C056D7A19A123548406D87AF44DA1514C067B5C01E13354840E8CD76BFE91514C0BABFF6A313354840217D8B35F91514C0C07C2E2A14354840A2C841A6081614C078EC67B1143548406BB09911181614C0E30EA33915354840F2003F78271614C0905DF5C215354840C0ED85D9361614C0EF5E494D16354840D6766E35461614C000139FD816354840339CF88B551614C0C479F664173548404F2AD0DD641614C0CA0C65F2173548403C889D29741614C08252D580183548406F820C70831614C0ED4A47101935484062E5C8B1921614C00BF6BAA01935484024187BEDA11614C06ACD45321A3548402EE7CE23B11614C0ECDDBCC41A35484009861854C01614C0B11A4B581B354840A28DAF7FCF1614C0270ADBEC1B3548400B653CA5DE1614C051AC6C821C354840450CBFC4ED1614C02D0100191D354840C64FE3DEFC1614C0BB0895B01D3548408F2FA9F30B1714C0FCC22B491E354840B112B9011B1714C0F02FC4E21E354840915E160B2A1714C0974F5E7D1F354840CBADBD0D391714C0F021FA18203548404C99060B481714C0FBA697B5203548409E544502571714C0B9DE3653213548404913CEF2651714C02AC9D7F1213548403B6EF8DD741714C04E667A9122354840FE9818C3831714C024B61E322335484091932EA2921714C01D3FAFD323354840F55D3A7BA11714C059F456762435484029F83B4EB01714C0B7E2EA1925354840B695871ABF1714C0C98380BE253548401403C9E0CD1714C08DD7176426354840424000A1DC1714C075649B0A27354840404D2D5BEB1714C09E1D36B227354840985DA40EFA1714C0EB0FBD5A28354840497165BB081814C0EBB4450429354840CA541C62171814C00E93BAAE29354840A53B1D02261814C0E423315A2A35484050F2139C341814C06D67A9062B35484055AC542F431814C0A85D23B42B354840B269DFBB511814C0078D89622C3548406A2AB441601814C0196FF1112D3548407AEED2C06E1814C04E8A45C22D3548405B82E7397D1814C036589B732E3548401E4D9AAB8B1814C0415FDD252F354840B1E742179A1814C0FF1821D92F35484027B9897BA81814C0E10B518D30354840F68D1AD9B61814C076B18242313548401E66F52FC51814C0BD09B6F831354840A0411A80D31814C09921C0AF323548400454DDC8E11814C027ECCB6733354840C169EA0AF01814C06869D9203435484060B69545FE1814C0CD1FD3DA3435484059068B790C1914C0560FB99535354840AB59CAA61A1914C002388B5136354840DFE3A7CC281914C061135F0E37354840F6A423EB361914C0E3271FCC37354840EF9C3D02451914C019EFE08A383548404198A112531914C0E375794A3935484075CAA31B611914C05FAF130B3A3548408C33441D6F1914C000229ACC3A354840FC9F2E187D1914C0C4CD0C8F3B354840D7760B0B8B1914C0ACB26B523C354840948486F6981914C0464ACC163D35484034C99FDAA61914C075A103DC3D354840B54457B7B41914C057AB3CA23E35484019F7AC8CC21914C0CE744C693F35484060E0A05AD01914C0F7F05D314035484011348720DE1914C044A65BFA40354840A5BE0BDFEB1914C0261B30C4413548401B802E96F91914C0BA42068F42354840FCAB4345071A14C0E329B35A43354840C00EF7EC141A14C0304A4C2744354840EEDB9C8C221A14C0301DE7F444354840FFDFE024301A14C0C4AF58C3453548407B4E17B53D1A14C07D7BB692463548406227403D4B1A14C0CA06EB62473548402C3707BE581A14C0C94421344835484061B1C036661A14C05E422E064935484000966CA7731A14C0167927D9493548400BE50A10811A14C0F2E80CAD4A354840829E9B708E1A14C06218C9814B35484063C21EC99B1A14C0F78071574C354840AF509419A91A14C0AF22062E4D3548406749FC61B61A14C0FC8371054E3548408AAC56A2C31A14C06C1EC9DD4E354840187AA3DAD01A14C07278F7B64F3548409AE5360ADE1A14C09B0B12915035484088BBBC31EB1A14C0E8D7186C51354840E0FB3451F81A14C0CA63F64752354840A4A69F68051B14C041AFAA24533548405CEF5077121B14C0DB334B025435484008D6487D1F1B14C00A78C2E0543548401F27337B2C1B14C05DF525C055354840A1E20F71391B14C0453260A056354840A06F875D461B14C0C12E7181573548400B67F141531B14C0D3EA586358354840E1C84D1E601B14C008E02C465935484033FC44F16C1B14C0D294D7295A354840F1992EBC791B14C0C0826E0E5B354840A3D55E7E861B14C0B3B6C6F35B3548404AAFD537931B14C0CB230BDA5C354840E42693E89F1B14C0775026C15D354840723C9790AC1B14C029C302A95E354840F5EFE12FB91B14C0FF6ECB915F354840F474C7C5C51B14C069DA6A7B603548405F649F53D21B14C06905E16561354840472512D8DE1B14C0FDEF2D51623548402284CB53EB1B14C0279A513D63354840F280CBC6F71B14C0E5034C2A64354840B61B1231041C14C0372D1D1865354840F887F391101C14C01F16C50666354840B6C56FE91C1C14C09CBE43F666354840DF6DDE38291C14C01EAD83E6673548400E1B3C7E351C14C0365B9AD7683548403266E0BA411C14C0E2C887C969354840494FCBEE4D1C14C023F64BBC6A354840673DA5185A1C14C0F9E2E6AF6B35484078C9C539661C14C0D41543A46C3548407EF32C52721C14C0450876996D3548408A2283607E1C14C0BC406A8F6E354840122374658A1C14C0C73835866F3548408FC1AB61961C14C067F0D67D7035484089317E54A21C14C00DEE3976713548400073EB3DAE1C14C048AB736F723548407DB9471DBA1C14C089AE6E6973354840EE9DEAF3C51C14C05F7140647435484065877CC0D11C14C03B7AD35F75354840D00E5584DD1C14C01DC9275C76354840419B1C3EE91C14C093D75259773548402FF97EEEF41C14C0102C3F5778354840235CD094001D14C021400256793548409590BC310C1D14C0AA2071557A354840839643C5171D14C0C7C0B6557B35484077A1B94E231D14C07920D3567C354840E87DCACE2E1D14C0A24C9B587D354840D62B76453A1D14C060383A5B7E354840531265B1451D14C095F0845E7F354840C5969A14511D14C05F68A66280354840C553136D5C1D14C02F2689678135484042E226BC671D14C0052A2D6D82354840C5752901731D14C0E0739273833548404E0E1B3C7E1D14C0C203B97A843548405478A76D891D14C01B608B828535484061E72295941D14C0097C348B86354840FC8EE1B19F1D14C0FCDD9E948735484014083BC5AA1D14C0670CB59E88354840328683CEB51D14C0D7808CA9893548405609BBCDC01D14C04E3B25B58A35484009C535C2CB1D14C0CA3B7FC18B35484039524BADD61D14C04D829ACE8C354840F817A48DE11D14C0469561DC8D35484034AF9764EC1D14C046EEE9EA8E354840FF7ECE30F71D14C0BC131EFA8F354840588748F2011E14C0C8F8280A913548402F615DAA0C1E14C0BB30CA1A923548409573B557171E14C0B5AE2C2C9335484089BE50FA211E14C0B472503E94354840FBDA86932C1E14C02B0320519535484085635421371E14C0A7D9B064963548408BBDBCA5411E14C09B7CED7897354840A983BC1E4C1E14C005ECD58D98354840CE4EAB8D561E14C076A17FA399354840F81E89F2601E14C05D23D5B99A354840B127AA4C6B1E14C0BC71D6D09B354840F9680E9C751E14C0210699E89C354840D0E2B5E07F1E14C0FD6607019E3548403695A01A8A1E14C04F94211A9F354840A24C7A4A941E14C0198EE733A03548409D3C976F9E1E14C05A54594EA13548402765F789A81E14C012E77669A23548403FC69A99B21E14C041464085A3354840E75F819EBC1E14C076EBCAA1A43548401D32AB98C61E14C093E3EBBEA5354840E33C1888D01E14C028A8B8DCA63548403780C86CDA1E14C0333931FBA7354840A32F1046E41E14C0B596551AA935484015E44615EE1E14C0AFC0253AAA3548409F0415D9F71E14C01FB7A15AAB354840B85D2692011F14C07800B47BAC3548405FEF7A400B1F14C04816729DAD3548401FED66E3141F14C08FF8DBBFAE3548406D23967B1E1F14C04DA7F1E2AF3548404B920809281F14C0F3A89D06B1354840406D128B311F14C081FDDF2AB2354840C4805F023B1F14C01598E34FB3354840D7CCEF6E441F14C092857D75B43548408BB86BCF4D1F14C0F6C5AD9BB535484045A9D625571F14C0D2D289C2B63548409F392D70601F14C09632FCE9B73548408802C7AF691F14C0D15E1A12B93548400104A4E4721F14C0F4DDCE3ABA3548401AA56C0D7C1F14C0FFAF1964BB354840C27E782B851F14C0824E108EBC35484082C41B3E8E1F14C0EC3F9DB8BD354840D0420246971F14C03F84C0E3BE354840C060D441A01F14C07A1B7A0FC03548403EB7E932A91F14C09D05CA3BC13548405DADEA17B21F14C037BCC568C23548400CDC2EF2BA1F14C02B4C4296C3354840D1760AC1C31F14C095A86AC4C4354840AF7D7D84CC1F14C0E85729F3C53548402E24DC3BD51F14C094E06822C73548403B037EE8DD1F14C0B7355452C8354840604EB789E61F14C03464C082C93548402639DC1EEF1F14C0275FD8B3CA354840049098A8F71F14C0743371E5CB354840FA52EC26002014C0A95AA017CD3548400882D799082014C0C6D4654ACE354840B650AE00112014C03D28AC7DCF354840F357C85C192014C09BCE88B1D03548405A3222AC212014C0E2C7FBE5D13548405045BFF0292014C0829AEF1AD3354840E6F74729322014C00AC07950D4354840951668563A2014C07B389A86D5354840E4D47377422014C0458A3BBDD63548404BFF168D4A2014C068B55DF4D735484053C9A596522014C07333162CD9354840FB3220945A2014C0D88A4F64DA354840BC083286622014C024351F9DDB354840944ADB6C6A2014C0CBB86FD6DC3548400D2C7047722014C0CA154110DE35484027ADF0157A2014C0B1C5A84ADF354840E1CD5CD8812014C063D57B85E0354840B45A608F892014C0FE37E5C0E135484027874F3A912014C0F173CFFCE23548403B532AD9982014C03E893A39E4354840668B9C6CA02014C0E4772676E5354840BC964EF3A72014C0E33F93B3E6354840290E986EAF2014C0CB5A96F1E73548403725CDDDB62014C07DD50430E93548406F0F4240BE2014C08829F46EEA354840BF654E97C52014C0ED5664AEEB354840AF5B46E2CC2014C01CE43FEEEC35484040F12921D42014C033C4B12EEE3548407226F953DB2014C014048F6FEF35484045FBB37AE22014C04F1DEDB0F0354840B86F5A95E92014C0E30FCCF2F135484055B740A3F02014C042621635F33548400A6BBEA5F72014C0FA8DE177F4354840E9F17B9BFE2014C00B932DBBF535484068182585052114C0E7F7E4FEF635484089DEB9620C2114C08DBC0743F8354840D2778E33132114C08C5AAB87F9354840347DFAF8192114C0E5D1CFCCFA354840C055A6B1202114C0792F4A12FC3548407501925D272114C0F5DF5A58FD354840421915FE2D2114C0AD76C19EFE3548403804D891342114C0BFE6A8E5FF35484059C2DA183B2114C09AB6FB2C013648401A20C993412114C040E6B974023648407C1DA302482114C0B175E3BC0336484008EEBC644E2114C0EC64780505364840345EC2BA542114C0802D8E4E063648408AA107045B2114C04FDCF9970736484081843841612114C07864E6E108364840A13AA971672114C0DDD2282C0A364840639005966D2114C09B1AEC760B364840D7ECF5AC732114C0944805C20C36484062B57DB8792114C058D6890D0E364840A18499B67F2114C0E6C379590F36484080F3A0A8852114C0B097BFA5103648408935E88D8B2114C0D34486F21136484033171B67912114C032D8A23F133648408FFFE132972114C0CC51158D143648408C8794F29C2114C0BFA408DB153648402AAF32A6A22114C0EEDD5129173648407ADD644CA82114C059FDF07718364840F4DED6E5AD2114C08E7CFBC6193648400F803473B32114C0FEE15B161B36484054F4D1F3B82114C039A727661C364840C23BAF67BE2114C0AF5249B61D3648405A56CCCEC32114C061E4C0061F3648401C442929C92114C0DED5A357203648400705C676CE2114C095ADDCA8213648401D99A2B7D32114C0896B6BFA223648405B00BFEBD82114C04789654C24364840C43A1B13DE2114C0B113A09E253648405648B72DE32114C0E6FD45F1263648401229933BE82114C0C8542C4428364840F8DCAE3CED2114C0740B7E972936484090975E30F22114C0CC2E10EB2A364840C9F1F917F72114C0EFB10D3F2C364840B55229F2FB2114C0BFA14B932D364840415344C0002214C059F1F4E72E364840805AF380052214C0A0ADDE3C30364840E934E2340A2214C093D60892313648407BE210DC0E2214C0515F9EE732364840C096D375132214C0BC54743D34364840A6EA8103182214C06230A093353648403F45C4831C2214C043F221EA36364840017346F7202214C0D120E4403836484076A75C5D252214C00CBCE6973936484014AFB2B6292214C011B754EF3A364840DD8948032E2214C035A5ED463C364840CE371E43322214C09379DC9E3D36484073EC8775362214C09EBA0BF73E3648404174319B3A2214C0E5E1904F40364840C2026FB33E2214C0D87556A8413648406D64ECBE422214C079765C01433648404199A9BD462214C0545DB85A44364840C8D4FAAE4A2214C04D373FB4453648400117E0924E2214C082F71B0E47364840DCF8B06A522214C06424396848364840F2146A34562214C0F2BD96C249364840A8D00EF2592214C09E4A1F1D4B3648409BC69BA15D2214C086BDFD774C3648402D5C1445612214C01A9D1CD34D364840FC2B75DA642214C0CC6F662E4F364840F4CE1563682214C0B928068A503648401645F6DE6B2214C0C4D4D0E551364840EBC16A4D6F2214C07CEDDB4153364840724573AE722214C0E172279E54364840239CBB02762214C063EB9DFA5536484086F99749792214C092D0545757364840142AB4837C2214C06D224CB458364840546164B07F2214C067676E115A364840469FA8CF822214C00D19D16E5B36484062B02CE2852214C0D1BD5ECC5C36484031C844E7882214C0B255172A5E364840B2E6F0DE8B2214C0405A10885F3648405ED8DCC98E2214C07BCB49E660364840BBD05CA7912214C045B6984462364840CCCF7077942214C0BB0D28A3633648408FD5183A972214C04F58E201653648407CAE00F0992214C00196C760663648401B8E7C989C2214C06040EDBF673648406D748C339F2214C04D64281F69364840726130C1A12214C0E7F4A37E6A364840A0211442A42214C010FF34DE6B36484081E88BB5A62214C0E675063E6D36484015B6971BA92214C0D9DF029E6E3648405B8A3774AB2214C05CC314FE6F364840CB3117C0AD2214C0FC99515E713648407613DFFDAF2214C0B963B9BE723648404CC8E62EB22214C095204C1F74364840D3838252B42214C08ED00980753648400E46B268B62214C017FADCE076364840FB0E7671B82214C0BD16DB41783648409BDECD6CBA2214C0F1ACEEA2793648406481655BBC2214C044362D047B364840E02A913CBE2214C0B4B296657C364840980EA50FC02214C0B4A815C77D36484079C5F8D5C12214C04218AA287F3648400D83E08EC32214C0EE7A698A8036484054475C3AC52214C029573EEC813648404D126CD8C62214C081263E4E83364840F9E30F69C82214C0696F53B084364840CE88F3ECC92214C0DF317E1286364840DF67BF62CB2214C0E46DBE7487364840A34D1FCBCC2214C0792314D7883648409106BF26CE2214C02ACC94398A364840BAF94674CF2214C0DC74159C8B3648400CC00EB5D02214C0AC10C1FE8C3648409BC0BEE7D12214C07CAC6C618E3648405394AE0DD32214C0693B43C48F364840BD6E3226D42214C056CA19279136484063839E30D52214C0D3D2058A92364840336B4A2ED62214C0DE5407ED93364840B6598A1ED72214C078501E5095364840EB4E5E01D82214C0A1C54AB3963648405B7E1AD6D82214C0CA3A771698364840F680169ED92214C08229B97999364840438AA658DA2214C03A18FBDC9A364840439ACA05DB2214C0808052409C364840F5B082A5DB2214C0C7E8A9A39D364840E3012337DC2214C09DCA16079F364840FA2503BCDC2214C00126996AA0364840C4507733DD2214C066811BCEA136484041827F9DDD2214C0CADC9D31A336484071BA1BFADD2214C02F382095A4364840DC2CA048DE2214C0220DB8F8A53648407072648ADE2214C016E24F5CA7364840B8BEBCBEDE2214C009B7E7BFA8364840B211A9E5DE2214C0FC8B7F23AA3648405E6B29FFDE2214C07FDA2C87AB36484046FF910ADF2214C072AFC4EAAC36484058663A09DF2214C0F4FD714EAE3648401DD476FADE2214C0E8D209B2AF3648401D7C9BDDDE2214C06A21B715B136484047F7FFB3DE2214C05DF64E79B23648402379F87CDE2214C051CBE6DCB33648403B35D937DE2214C044A07E40B53648407DC4F9E5DD2214C0377516A4B6364840715AAE86DD2214C09CD09807B8364840A12A4B19DD2214C0002C1B6BB9364840FACD279FDC2214C065879DCEBA36484006789817DC2214C03B690A32BC3648404E5CF181DB2214C0104B7795BD364840C0138ADFDA2214C057B3CEF8BE364840E4D1B62FDA2214C09E1B265CC036484043CACB71D92214C0E4837DBFC1364840CD9520A7D82214C00DF9A922C3364840096809CFD72214C0366ED685C43648408074DAE8D62214C05FE302E9C53648402154EBF5D52214C06A65044CC7364840753A90F5D42214C076E705AFC83648407C27C9E7D32214C0F2EFF111CA364840BE4EEACBD22214C0DF7EC874CB3648402A494BA3D12214C03E9489D7CC364840484A406DD02214C09CA94A3ACE3648401952C929CF2214C0DDCBE09CCF3648409D60E6D8CD2214C08F7461FFD0364840D375977ACC2214C0B2A3CC61D2364840BC91DC0ECB2214C0D5D237C4D336484057B4B595C92214C04C956226D5364840A6DD220FC82214C0C2578D88D6364840A60D247BC62214C0A9A0A2EAD7364840D11065DAC42214C073F68C4CD9364840374E8E2BC32214C0AED261AEDA364840C75EF76FC12214C0CBBB0B10DC36484092A948A6BF2214C0E8A4B571DD36484087C7D9CFBD2214C058211FD3DE3648402FECFEEBBB2214C03A247334E03648408917B8FAB92214C08DADB195E1364840964905FCB72214C0C143C5F6E23648405682E6EFB52214C06760C357E4364840C8C15BD6B32214C0611081B8E536484064D410B0B12214C05AC03E19E73648403B21AE7BAF2214C0A703BC79E83648403C418B3AAD2214C065CD23DAE9364840F067FCEBAA2214C0762A4B3AEB36484056950190A82214C0F80D5D9AEC364840E7954627A62214C05DFE43FAED364840B2D073B0A32214C03275155AEF364840A8DEE02CA12214C05B7FA6B9F036484050F3E19B9E2214C066960C19F2364840AA0E77FD9B2214C054BA4778F33648402FFD4B52992214C023EB57D7F4364840EE250999962214C046AF2736F6364840D82106D3932214C0DBF9E194F7364840EBF04200912214C0C2D75BF3F83648403AFA671F8E2214C08CC2AA51FA364840B3D6CC318B2214C038BACEAFFB364840DEB9C536882214C0C6BEC70DFD364840BCA3522E852214C0A856806BFE364840C3601F19822214C0DC81F8C8FF3648407E2480F67E2214C0F4B945260137484061BB20C77B2214C0EDFE678302374840818CA989782214C03AD749E00337484041FD1D40752214C0DA42EB3C053748403DA87AE8712214C05CBB619906374840622617846E2214C032C797F5073748403AAB47126B2214C05A668D51093748403C03B893672214C0661258AD0A374840F161BC07642214C0C451E2080C374840CF93006F602214C076242C640D3748405FCCD8C85C2214C07B8A35BF0E3748401AD8F015592214C0D483FE191037484087EA9C55552214C08010877411374840A703DD87512214C07F30CFCE12374840F0EF5CAD4D2214C0D2E3D6281437484063AF1CC6492214C0782A9E8215374840897570D1452214C0710425DC16374840D80E04D0412214C02FF8553518374840DAAE2BC13D2214C0CFF85B8E19374840062293A5392214C034130CE71A3748405C683A7D352214C0ECC07B3F1C37484064B57547312214C0688895971D37484096D5F0042D2214C0C65C84EF1E3748407AFCFFB4282214C05BD107472037484088F64E58242214C0D152609E21374840C0C3DDEE1F2214C07D744DF522374840AB9700781B2214C00BA30F4C24374840360B0FF5162214C0CF7166A2253748407485B164122214C0E6D37CF8263748406406E8C60D2214C051C9524E28374840F5260A1D092214C0F15EBDA329374840394EC065042214C0E487E7F82A374840A748B6A1FF2114C09CCABB4D2C3748403E16ECD0FA2114C0A7A04FA22D374840FFB661F3F52114C0E81678F62E374840735E6B08F12114C07C20604A3037484087A56011EC2114C0D543F29D313748404EF3E90CE72114C0630719F1323748403F14B3FBE12114C0455EFF4334374840D0D467DEDC2114C05C557A9635374840159CB0B3D72114C0C6DFB4E8363748408236397CD22114C0660A843A383748401AA40138CD2114C0CB4EFD8B39374840DBE409E7C72114C0F4AC20DD3A374840C6F85189C22114C0E124EE2D3C37484052AC851FBD2114C0043D507E3D37484090664DA8B72114C0EC6E5CCE3E374840F8F35424B22114C098BA121E4037484001214894AC2114C079A65D6D4137484034217BF7A62114C01FAC52BC4237484090F4ED4DA12114C0FB51DC0A44374840169BA0979B2114C09B11105945374840C51493D4952114C07171D8A6463748409F61C504902114C00BEB4AF447374840194EE3288A2114C0DB04524149374840BC0D4140842114C0E0BEED8D4A3748408AA0DE4A7E2114C01B191EDA4B374840F8D26749782114C01A8DF8254D37484090D8303B722114C04FA167714E37484052B139206C2114C0B9556BBC4F3748403D5D82F8652114C05AAA030751374840C9A8B6C45F2114C02F9F305152374840F693D684592114C0C9AD079B533748404C523638532114C00AE35DE454374840CDE3D5DE4C2114C081B8482D56374840EE146179462114C02D2EC8755737484039192C07402114C00E44DCBD5837484024BDE288392114C025FA84055A374840B00085FE322114C07250C24C5B374840661767672C2114C065CD7E935C374840BDCD34C4252114C08EEACFD95D3748403D5742141F2114C0EDA7B51F5F3748405F803B58182114C0810530656037484021492090112114C0BC8929AA613748400CE544BB0A2114C09E34A2EE62374840992055DA032114C0B57FAF3264374840C6FB50EDFC2014C0026B517665374840947638F4F52014C0F57C72B96637484003910BEFEE2014C01E2F28FC673748409B7E1EDDE72014C0EE075D3E693748404CD8C8BFE02014C0640711806A3748402605B395D92014C010A759C16B374840A0D1885FD22014C0D4F30B026D374840BC3D4A1DCB2014C05C5A68426E3748407849F7CEC32014C0FD6D2E826F374840D5F48F74BC2014C043A873C170374840D33F140EB52014C0C0824D0072374840E9F62F9CAD2014C0540A913E7337484028818B1DA62014C01E32697C7437484008ABD2929E2014C08E80C0B9753748400041B1FC962014C0167C81F67637484099767B5A8F2014C0D417D73278374840D24B31AC872014C0AA60966E79374840ADC0D2F17F2014C0B549EAA97A37484028D55F2B782014C0D8DFA7E47B374840BB558459702014C0A29CE41E7D374840EE75947B682014C084068B587E3748403A023C92602014C09B10C6917F374840AF61239C582014C0CAC76ACA80374840B3F94D9B502014C0112C790282374840E164B88D482014C08D301C3A833748409E086675402014C09368137184374840847F5350382014C0CD409FA7853748408262D81F302014C020C694DD8637484098B1F4E3272014C08BF8F31288374840C66CA89C1F2014C09C51D2478937484095C74749172014C0C5571A7C8A37484004C2D2E90E2014C0060BCCAF8B37484003F5A07F062014C0EDE4FCE28C374840A2C75A09FE1F14C0ED6B97158E3748405906AC87F51F14C004A09B478F374840B0E4E8F9EC1F14C0338109799037484097FB6861E41F14C00989F6A9913748401EB2D4BCDB1F14C0F63D4DDA92374840BED4D70CD31F14C0FC9F0D0A9437484075637251CA1F14C08A35223995374840BB2A508BC11F14C0BFF1B56796374840A19119B9B81F14C00C5BB39597374840A0647ADBAF1F14C070711AC398374840B6A372F2A61F14C0ED34EBEF99374840E54E02FE9D1F14C0F22B101C9B3748402B6629FE941F14C09E49B4479C37484000B693F38B1F14C0D39AAC729D37484076A5E9DC821F14C020990E9D9E3748407ACD82BB791F14C0F6CAC4C69F3748409761B38E701F14C07223FAEFA0374840422E2757671F14C077AF8318A2374840056732145E1F14C095E87640A3374840E10BD5C5541F14C03B55BE67A4374840D31C0F6C4B1F14C0F96E6F8EA537484055668C07421F14C040BC74B4A637484066E84C98381F14C09EB6E3D9A7374840180AF91C2F1F14C0155EBCFEA8374840CF309497251F14C085BFD322AA3748409EC3C6061C1F14C09C476A46AB37484085C2906A121F14C0AE893F69AC37484073C649C4081F14C0D7787E8BAD37484078369A12FF1E14C0899B11ADAE37484094128255F51E14C0C4F1F8CDAF374840B7F3588EEB1E14C017F549EEB0374840F240C7BBE11E14C0F22BEF0DB2374840BBC678DED71E14C05796E82CB337484014856DF6CD1E14C04534364BB437484084AFF902C41E14C0BB05D868B5374840FADE7405BA1E14C0BA0ACE85B6374840FF4633FDAF1E14C0434318A2B737484093E734EAA51E14C054AFB6BDB83748403FF4CDCB9B1E14C0EE4EA9D8B9374840F10556A3911E14C01122F0F2BA37484032502170871E14C0BE288B0CBC37484001D32F327D1E14C0F3627A25BD374840D75A2DEA721E14C0B1D0BD3DBE374840C54EC296681E14C069F83F55BF374840B84746395E1E14C0A953166CC03748403A790DD1531E14C073E24082C1374840C3AFC35E491E14C0372BAA97C2374840DA1EBDE13E1E14C084A767ACC337484080C6F959341E14C05A5779C0C43748402C7325C8291E14C0B93ADFD3C53748406758942B1F1E14C0825E6EE6C6374840A842F284141E14C0642F67F8C7374840EF313FD4091E14C040BA9E09C9374840C559CF18FF1D14C016FF141ACA374840A1864E53F41D14C07477DF29CB3748400CEC1083E91D14C0CDA9E838CC374840F3226EA9DE1D14C0AF0F4647CD3748406A920EC5D31D14C0FCB5CC54CE374840E7069ED6C81D14C06009BD61CF37484069801CDEBD1D14C0309DD66DD03748407B32DEDAB21D14C089644479D137484009B63ACEA71D14C0DCE5F083D23748409E3E86B79C1D14C02921DC8DD337484038CCC096911D14C070160697D4374840D95EEA6B861D14C0B0C56E9FD53748407FF602377B1D14C0EB2E16A7D63748402C930AF86F1D14C0AFCB11AED7374840DE3401AF641D14C0DFA836B4D83748400EA8925C591D14C097B9AFB9D9374840432013004E1D14C0BA0A52BEDA3748407F9D8299421D14C0D71533C2DB37484037EC8C29371D14C07D5468C5DC374840F63F86AF2B1D14C08FD3C6C7DD37484031651A2C201D14C00B934EC9DE374840728F9D9E141D14C010862ACADF374840318BBB07091D14C0103345CAE0374840F58BC866FD1C14C07B2089C9E1374840375E70BCF11C14C0DFC70BC8E2374840F501B308E61C14C0AFAFB7C5E3374840BAAAE44ADA1C14C07951A2C2E4374840FC24B183CE1C14C03DADCBBEE5374840BA7018B3C21C14C0FBC233BAE6374840F68D1AD9B61C14C02419C5B4E7374840AE7CB7F5AA1C14C0B9AF7FAEE83748406D7043089F1C14C0470079A7E937484020021612931C14C0CF0AB19FEA37484050658312871C14C0C3551297EB374840FD998B097B1C14C022E19C8DEC37484026A02EF76E1C14C07B266683ED374840CD776CDB621C14C03FAC5878EE37484068EDF0B6561C14C06E72746CEF374840096864884A1C14C097F2CE5FF03748409F801E513E1C14C02BB35252F137484028371F11321C14C02BB4FF43F23748402EBFBAC7251C14C0246FEB34F3374840B118F174191C14C0896A0025F437484029106E190D1C14C0CA2C2914F53748401DD985B4001C14C005A99002F63748400640E446F41B14C0AB6521F0F6374840E34489D0E71B14C0BD62DBDCF73748403C1BC950DB1B14C0C819D4C8F83748408A8F4FC8CE1B14C0B097E0B3F9374840CCA11C37C21B14C00356169EFA3748408B85849CB51B14C0C1547587FB374840B5D3DEF9A81B14C0EA93FD6FFC3748405DF3D34D9C1B14C07E13AF57FD3748406F7DBB998F1B14C07ED3893EFE374840FFD83DDC821B14C0E9D38D24FF374840F99EB216761B14C0309BA50900384840E8026E48691B14C0E2A2E6ED00384840CB0470715C1B14C08E6466D101384840A2A4B8914F1B14C08873E4B3023848406DE247A9421B14C07B3CA19503384840A38AC9B8351B14C04BCC717604384840CDD091BF281B14C0869C6B5605384840ECB4A0BD1B1B14C02CAD8E35063848407603A2B30E1B14C0AF84C51307384840F3EFE9A0011B14C09D9C25F107384840DC462486F41A14C0677B99CD0838484030085163E71A14C09C9A36A9093848407967C437DA1A14C0AD80E7830A3848402C312A04CD1A14C02AA7C15D0B3848404B6582C8BF1A14C08394AF360C3848405D372184B21A14C047C2C60E0D38484052405E38A51A14C0E7B6F1E50D3848403BE7E1E3971A14C0F3EB45BC0E3848408FF857878A1A14C0DAE7AD910F3848404F74C0227D1A14C09EAA296610384840F126C7B66F1A14C03F34B9391138484086771442621A14C04AFE710C12384840FEFEFFC5541A14C0328F3EDE12384840E1F0DD41471A14C0856034AF13384840304DAEB5391A14C0257F287F14384840E91371212C1A14C031DE454E153848408511D2851E1A14C01804771C163848408C7925E2101A14C04E77A6E91638484075181737031A14C07DA414B617384840CA21FB83F51914C0F91E8181183848408995D1C8E71914C05260014C19384840A20CF206DA1914C0876895151A38484026EE043DCC1914C099373DDE1A384840163A0A6BBE1914C016470EA61B3848405E895992B01914C0E0A3DD6C1C38484012439BB1A21914C086C7C0321D3848401F0027CA941914C008B2B7F71D3848409727A5DA861914C06763C2BB1E384840F285C1E3781914C0A2DBE07E1F3848402F1B7CE56A1914C0BA1A1341203848404EE7D4DF5C1914C01FA7430221384840C6B677D34E1914C0EF739DC221384840A9F00CBF401914C00C8EF58122384840E62DECA3321914C0066F61402338484005A26981241914C04D9DCBFD233848407D193158161914C0FF0B5FBA24384840D8C79627081914C0FFC7F0752538484015AD9AEFF91814C0DB4A963026384840AB95E8B0EB1814C0041B3AEA263848409B81806BDD1814C009B2F1A2273848406CA4B61ECF1814C05C96A75A2838484097CA36CBC01814C01BBB861129384840A5275570B21814C097B34EC7293848408254690FA41814C07FEC3F7C2A38484042B81BA7951814C025F919302B3848405C1F1838871814C037461DE32B384840CE895EC2781814C096E01E952C3848409AF7EE456A1814C042C81E462D384840BF68C9C25B1814C03CFD1CF62D3848403EDDED384D1814C0A17244A52E3848408D2108A93E1814C0C4BB54532F384840BE9CC011301814C0C4CB780030384840BFE76E74211814C011299BAC303848401A3667D0121814C03A4DD1573138484045545526041814C02245F00132384840CA758D75F51714C0757D38AB32384840A89A0FBEE61714C08689695333384840CD5B3301D81714C0745CAEFA33384840D553F53CC91714C0AF7CF1A03438484024E85873BA1714C038EA324635384840CC7F06A3AB1714C00EA572EA3538484045E7A9CC9C1714C0C026C68D36384840175297EF8D1714C0317C0230373848403059260D7F1714C07E9852D137384840A363FF23701714C01902A171383848405D0A7A35611714C001B9ED1039384840E880EA40521714C036BD38AF39384840CCFAA445431714C0B80E824C3A384840F7100145341714C089ADC9E83A384840F3F6523E251714C0A6990F843B38484036794632161714C0A04C691E3C384840D3FE831F071714C058D3ABB73C3848402EED0E08F81614C05EA7EC4F3D384840E2DEE3E9E81614C0B1C82BE73D384840DE6C5AC6D91614C05137697D3E3848402197729DCA1614C03FF3A4123F3848403591806EBB1614C07AFCDEA63F3848409027303AAC1614C00353173A40384840335A81009D1614C04A7D38CC40384840A65CC8C08D1614C06D6E6D5D41384840D7C75C7C7E1614C04F338BED41384840D902E7316F1614C07F45A77C4238484022DA12E25F1614C0FBA4C10A433848402A1A8C8D501614C0C651DA9743384840022AFB32411614C04ED2DB234438484022D60BD3311614C0B319F1AE4438484000EB696E221614C0D734EF3845384840269C6904131614C0B923D6C14538484093E90A95031614C0E85FBB4946384840BF9FF920F41514C0F462B4D04638484032F289A7E41514C02FC080564738484063AD6729D51514C046E460DB47384840DC04E7A5C51514C08E62145F4838484014C5B31DB61514C0B1A7DBE14838484093212290A61514C093C08B6349384840D1E6DDFD961514C0C2263AE449384840CD14E766871514C0B060D1634A38484087AB3DCB771514C0ECE766E24A38484089DE352A681514C074BCFA5F4B384840C1462785581514C0BB6477DC4B384840B71766DB481514C0C1E0DC574C384840F584462C391514C014AA40D24C38484068272079291514C0B5C0A24B4D3848409A3247C1191514C014ABEDC34D384840017367050A1514C03169213B4E384840B04F2944FA1414C09C7453B14E3848409461E47EEA1414C0C6536E264F384840AEA898B5DA1414C03C80879A4F38484086589AE7CA1414C07280890D503848401D71E914BB1414C0F5CD897F50384840EABE313EAB1414C0A7755DF050384840EC4173639B1414C036E4446051384840AD2D02848B1414C0F4ACFFCE513848401A1B36A17B1414C000C3B83C523848404671B7B96B1414C0CAAC5AA952384840A7FC31CE5B1414C0E1E3FA14533848403EBDA5DE4B1414C0B8EE837F533848400BB312EB3B1414C04CCDF5E8533848400DDE78F32B1414C09F7F505154384840453ED8F71B1414C0407FA9B8543848402AA0DCF80B1414C09F52EB1E553848404437DAF5FB1314C0BCF91584553848409303D1EEEB1314C0997429E8553848401805C1E3DB1314C0C23C3B4B563848404A0856D5CB1314C01B5F20AD56384840290D90C3BB1314C0C2CE030E573848403D47C3ADAB1314C02712D06D5738484087B6EF939B1314C0D9A29ACC57384840F4F36C778B1314C0BB8D382A583848409766E3567B1314C0EBC5D48658384840E7DAFE326B1314C0D8D159E258384840E350BF0B5B1314C0F637B23C5938484015FC78E04A1314C061EB0896593848406B7583B23A1314C08B7248EE593848406DF032812A1314C073CD70455A3848401C6D874C1A1314C0A875979B5A38484078EB80140A1314C00D7891F05A384840806B1FD9F91214C0314E74445B384840ACB90E9BE91214C0A27155975B3848408509A359D91214C042EF09E95B38484081278815C91214C030BABC395C3848402A4712CEB81214C04EDF42895C38484080684183A81214C0B951C7D75C384840FA57C135981214C0531E1F255D384840971592E5871214C03B3875715D38484058A1B392771214C053AC9EBC5D384840C52E7A3C671214C029F4B0065E384840578A91E3561214C04D89C14F5E3848400CB4F987461214C0A078A5975E384840E4ABB229361214C041B587DE5E384840E171BCC8251214C0114C3D245F38484078D2C265151214C0A0B6DB685F384840BC346EFF041214C0EDF462AC5F3848409B311697F41114C0F906D3EE5F3848409DFC0E2CE41114C0C3EC2B3060384840C39558BED31114C04CA66D706038484084C99E4EC31114C0933398AF6038484069CB35DCB21114C00A1B96ED60384840719B1D67A21114C0CE4F922A613848408CD2ADF0911114C0C2DE616661384840CAD78E77811114C075411AA1613848402BABC0FB701114C075F1D0DA613848409FE59A7E601114C0158245136238484036EEC5FE4F1114C00360B84A623848406891ED7C3F1114C0B01114816238484035CF11F92E1114C08C1D43B6623848401474DE731E1114C0B67670EA6238484017E7FBEB0D1114C00F2A711D63384840B4F41562FD1014C026B15A4F633848406369D8D6EC1014C06E92178063384840AD789749DC1014C003C1D2AF63384840922253BACB1014C0C74961DE633848408833B729BB1014C04AA6D80B643848401ADF1797AA1014C08BD6383864384840BDF120039A1014C08BDA816364384840FB9E266D891014C0BB389E8D643848404BB3D4D5781014C038E4B8B664384840AD2E2B3D681014C0E4E9A6DE6438484021112AA3571014C0C0496805653848402F8E2507471014C0EAF6272B653848404F72C969361014C043FEBA4F6538484082BD15CB251014C05BD93673653848403D3CB62B151014C031889B95653848409355538A041014C03791D3B665384840FAD598E7F30F14C0FC6DF4D665384840EB893244E30F14C07E1EFEF565384840EEA4749FD20F14C0C0A2F0136638484079F30AFAC10F14C03181B630663848409FDC9D52B10F14C0EFAC7A4C66384840C6C530ABA00F14C04FB9FC66663848408749C001900F14C0FB127D806638484048CD4F587F0F14C0D7C6D098663848401BB887AD6E0F14C0724E0DB066384840000A68015E0F14C0CBA932C666384840E45B48554D0F14C0545F2BDB66384840DB14D1A73C0F14C09CE80CEF66384840D2CD59FA2B0F14C0A245D70167384840DAED8A4B1B0F14C066768A13673848406C41109C0A0F14C05A01112467384840FD9495ECF90E14C00D60803367384840A04FC33BE90E14C0EF18C34167384840440AF18AD80E14C090A5EE4E6738484070F872D9C70E14C0EF05035B673848409CE6F427B70E14C00D3A006667384840DA3B1F75A60E14C05AC8D06F67384840905DF5C2950E14C0662A8A7867384840CEB21F10850E14C030602C8067384840953B9E5C740E14C02AF0A186673848405CC41CA9630E14C0E353008C67384840234D9BF5520E14C05A8B479067384840EAD51942420E14C0011D6293673848403A92EC8D310E14C06682659567384840011B6BDA200E14C08ABB51966738484051D73D26100E14C0DD4E1196673848401860BC72FF0D14C0EFB5B99467384840681C8FBEEE0D14C0BFF04A92673848402FA50D0BDE0D14C04EFFC48E67384840F62D8C57CD0D14C00D68128A67384840BDB60AA4BC0D14C0FB2A338467384840FB0B35F1AB0D14C0363B527D673848403A615F3E9B0D14C0A1A544756738484078B6898B8A0D14C0CBE31F6C673848402DD85FD9790D14C0247CCE616738484059C6E127690D14C0CB617B566738484085B46376580D14C01328E64967384840296F91C5470D14C0A73B4F3C6738484043F66A15370D14C06CA98B2D67384840D549F065260D14C0EFEAB01D67384840DD6921B7150D14C03000BF0C67384840E6895208050D14C0A26FA0FA66384840DC42DB5AF40C14C0D1B26AE7663848404AC80FAEE30C14C0BFC91DD3663848402F1AF001D30C14C0DD3AA4BD663848408B387C56C20C14C049F928A766384840D5EF5FACB10C14C054986B8F663848409673EF02A10C14C0AE84AC7666384840CEC32A5A900C14C037CBC05C66384840F4ACBDB27F0C14C07EE5BD41663848409262FC0B6F0C14C084D3A325663848401DB192665E0C14C0BA1B5D0866384840979880C24D0C14C03DB114EA65384840874C1A1F3D0C14C061278ACA6538484066990B7D2C0C14C0D2EAFDA965384840AA4B00DD1B0C14C0730845886538484065CAA03D0B0C14C0D2F97465653848400FE2989FFA0B14C0F0BE8D4165384840A692E802EA0B14C0CC578F1C653848402CDC8F67D90B14C0D84A64F6643848409FBE8ECDC80B14C0A31122CF6438484078069135B80B14C02CACC8A6643848403FE7EA9EA70B14C0731A587D64384840F4609C09970B14C0EAE2BA52643848400F405176860B14C0207F06276438484017B85DE4750B14C014EF3AFA633848400EC9C153650B14C0C73258CC63384840E10BD5C5540B14C0A9D0489D63384840A2E73F39440B14C0D9BB376D63384840C828AEAE330B14C03801FA3B63384840DC027425230B14C0561AA50963384840CD0EE99E120B14C0330739D662384840ACB3B519020B14C03F4EA0A162384840F0BD8596F10A14C098E2056C6238484010FA0416E10A14C021D13E35623848401ECFDB96D00A14C0699360FD6138484009D6611AC00A14C06F296BC4613848405942EB9FAF0A14C033935E8A613848400E1478279F0A14C02857254F613848409F17B4B18E0A14C06968EA12613848409680F33D7E0A14C0DAD382D560384840F14E36CC6D0A14C00A130497603848402A4F285D5D0A14C0F8256E57603848403E81C9F04C0A14C03486D61660384840B7186E863C0A14C010C7FCD45F38484084AE6D1F2C0A14C03A5521925F3848403FDDC4B91B0A14C023B72E4E5F3848404E0A77570B0A14C0C9EC24095F3848403869D8F7FA0914C0A07CEEC25E384840FFF9E89AEA0914C0C459B67B5E3848402BF0FC3FDA0914C0A60A67335E384840ABE46BE8C90914C0B815EBE95D384840060B8A93B90914C0186E6D9F5D3848403E635741A90914C0A720C3535D384840CAB97FF2980914C0F4A601075D384840BA75ABA5880914C08F7A3EB95C38484075FCDD5C780914C05AA84E6A5C38484095E81316680914C072235D1A5C384840809F50D3570914C0B9F83EC95B384840CFBB9092470914C04E1B1F775B384840EAA2D755370914C01398D2235B384840E0BBCD1B270914C0256284CF5A3848402AD31EE5160914C0F5FF1E7A5A384840C7E8CAB1060914C0F6F78C235A384840B7FCD181F60814C0433DF9CB59384840FB0E3455E60814C04F564E73593848401B53452BD60814C01A438C195938484006625D05C60814C0A303B3BE58384840446FD0E2B50814C0EB97C26258384840D57A9EC3A50814C08079D00558384840305173A8950814C044B5B1A7573848406859F78F850814C0563E914857384840E2F82D7C750814C0279B59E85638484037CA136B650814C0B6CB0A87563848405766005E550814C004D0A4245638484042CDF354450814C09F213DC1553848408032424F350814C069CDA85C553848408862974D250814C081C612F7543848405A5DF34F150814C05893659054384840F7225656050814C07CADB62854384840E8E61360F50714C0CF21DBBF53384840A275D86DE50714C070E3FD55533848409F9B4F80D50714C05FF21EEB52384840EEBF2196C50714C07C5B137F523848407F7BA6B0B50714C0E811061252384840643586CEA50714C0129CE1A3513848408A8618F1950714C08973BB3451384840F16E5D18860714C030A568C450384840AC55FD42760714C0B39D295350384840A8D34F72660714C066F0BDE04F384840E6E854A6560714C06690506D4F384840EEC860DE460714C0B47DE1F84E384840C073731A370714C031C545834E384840D4B5385B270714C08BD3BD0C4E384840298FB0A0170714C0143C09954D384840C0FFDAEA070714C0EAF1521C4D3848409907B839F80614C00EF59AA24C3848403CDA9B8CE80614C0F1CBCB274C384840204432E4D80614C021F0FAAB4B384840BD112741C90614C00FE8122F4B38484024AA22A2B90614C04B2D29B14A38484044A67C08AA0614C0454628324A3848402E6DDD729A0614C08DAC25B249384840D1979CE28A0614C093E60B31493848402C26BA577B0614C0E76DF0AE48384840527FDED06B0614C08842D32B48384840303C614F5C0614C0E7EA9EA747384840C75C42D34C0614C094E06822473848409F14D65B3D0614C000AA1B9C46384840B9631CE92D0614C0B8C0CC144638484002E36C7C1E0614C0BF247C8C453848408DF96F140F0614C012D629034538484059A725B1FF0514C0245BC078443848405585E553F00514C0842D55ED4338484093FA57FBE00514C0314DE8604338484000A0D4A8D10514C09C4064D342384840AEDC035BC20514C0E4FAF344423848408D493D13B30514C0EA886CB541384840AC4D29D0A30514C03E64E32441384840FB811F93940514C05013439340384840031A745B850514C03F89B60040384840C4152729760514C07A4C286D3F384840B341E4FC660514C075E382D83E384840E50454D5570514C0BCC7DB423E384840BDC479B4480514C0E07248AC3D3848404EE8FD98390514C0C3F19D143D384840976FE0822A0514C0F3BDF17B3C3848401027CD721B0514C070D743E23B384840B80EC4680C0514C03B3E94473B3848409026C564FD0414C053F2E2AB3A38484021A22466EE0414C0B9F32F0F3A384840E14D8E6DDF0414C0FABB907139384840D129027BD00414C0FB57DAD238384840F035808EC10414C048412233383848403F7208A8B20414C072F17D923738484035AB46C8A30414C05B75C2F036384840E347E3ED940414C020C01A4E36384840C1148A19860414C0325871AA3538484046DEE64B770414C0923DC60535384840FAD74D84680414C03F70196034384840DE01BFC2590414C0C86980B9333848406828E6074B0414C01037D01133384840237F17533C0414C034CB33693238484083D2FEA42D0414C03426ABBF313848408B229CFD1E0414C0F3540B1531384840C2A2435C100414C08E4A7F69303848402953F5C0010414C0768DF1BC2F384840ADCC082DF30314C03B97770F2F3848406176269FE40314C04DEEFB602E384840BC1CFA17D60314C0AD927EB12D384840BEBF8397C70314C0E9FD14012D384840665FC31DB90314C072B6A94F2C384840B5FBB8AAAA0314C0D835529D2B384840AA94643E9C0314C08B02F9E92A384840462AC6D88D0314C01A96B3352A38484089BCDD797F0314C0F7766C8029384840EA175722710314C0B01E39CA28384840F16F86D1620314C0B6130413283848409FC46B87540314C099CFE25A27384840F4150744460314C05752D5A12638484066300408380314C06422C6E725384840F71363D3290314C04CB9CA2C253848402DF477A51B0314C01117E37024384840829DEE7E0D0314C023C2F9B3233848407D431B5FFF0214C0123424F62238484096B2A946F10214C0DD6C623722384840CDEA9935E30214C0F5F29E772138484022ECEB2BD50214C0E93FEFB6203848401DEAF328C70214C0BA5353F51F384840AD7D092EB90214C0672ECB321F384840E40DD539AB0214C0F0CF566F1E3848403867024D9D0214C05638F6AA1D38484022563D688F0214C009EE93E51C384840290EDA8A810214C027E45A1F1C3848404E8FD8B4730214C0932720581B38484090D938E6650214C069AB0E901A384840F1ECFA1E580214C08E7CFBC619384840E695CA5F4A0214C01D8E11FD18384840F907FCA73C0214C0FAEC253218384840A10F3BF82E0214C0418C63661738484066E0DB4F210214C0D7789F9916384840C0468AAF130214C0D7A504CC1538484038769A16060214C0B4997DFD14384840453BB885F80114C06D540A2E1438484070C937FCEA0114C002D6AA5D13384840A6B9707BDD0114C00298748C12384840FB720B02D00114C0DF2052BA11384840E4C1B390C20114C0987043E71038484062A66927B50114C02D8748131038484075202DC6A70114C02EDE763E0F3848401C30FE6C9A0114C00AFCB8680E38484059D5DC1B8D0114C0C3E00E920D3848402A10C9D27F0114C0E8058EBA0C38484090E0C291720114C0E8F120E20B38484002137659650114C0C5A4C7080B384840910E8B28580114C00D98972E0A3848402D6C59004B0114C0C0CB905309384840D42BE1E03D0114C04FC69D7708384840118176C9300114C04A01D49A07384840E26B19BA230114C020031EBD06384840BFB875B3160114C0624591DE05384840319BDFB4090114C0804E18FF04384840AEDF02BFFC0014C00A98C81E043848403886DFD1EF0014C0FE21A23D0338484056C2C9ECE20014C0CF728F5B0238484081606D10D60014C00B04A67801384840B760CA3CC90014C0B2D5E59400384840F9C2E071BC0014C0C5E74EB0FF374840D0BA04AFAF0014C0B3C0CBCAFE3748402AE18DF5A20014C09C5387E4FD374840189D2444960014C061AD56FDFC3748408A87209C890014C091474F15FC37484090072AFC7C0014C02C22712CFB3748401AB69865700014C0333DBC42FA374840AFC6C0D7630014C0A4983058F93748405039A252570014C08134CE6CF837484075DAE8D64A0014C0C9109580F7374840A5DDE8633E0014C07C2D8593F6374840E042A2F9310014C09A8A9EA5F53748409FD6C098250014C02428E1B6F43748406ACC9840190014C018064DC7F337484041242AF10C0014C0079EF7D6F23748409AAA20AB000014C06176CBE5F1374840775F7C6EF4FF13C0258FC8F3F03748406076913AE8FF13C056E8EE00F03748404288B710DCFF13C0F1813E0DEF374840B92FEBEECFFF13C086D5CC18EE3748402BD22FD7C3FF13C087698423ED374840A8D62DC8B7FF13C081B77A2DEC3748401FD63CC3ABFF13C058CC8436EB374840A23705C79FFF13C0B814E33EEA374840A8C732D493FF13C0839D6A46E93748403286C5EA87FF13C0B9661B4DE8374840B53F690B7CFF13C0E9E90A53E7374840445BC63470FF13C084AD2358E6374840CD71346864FF13C01A2B7B5CE537484062EA5BA458FF13C01AE9FB5FE4374840F05D94EA4CFF13C01561BB62E33748400200323A41FF13C00993B964E23748400E9DE09335FF13C0F87EF665E13748409D68F4F629FF13C052AB5C66E0374840AF626D631EFF13C0A6910166DF374840BB57F7D912FF13C0F331E564DE3748404A7BE65907FF13C0AC12F262DD374840D299E6E3FBFE13C060AD3D60DC37484055B3F777F0FE13C09C7BDD5CDB3748405BFB6D15E5FE13C0438AA658DA374840E47149BCD9FE13C0E452AE53D9374840DEAFE16DCEFE13C07FD5F44DD83748405B1CDF28C3FE13C015127A47D7374840D283EDEDB7FE13C0A4083E40D637484042E60CBDACFE13C02EB94038D5374840AD433D96A1FE13C0409D972FD43748409BCFD27896FE13C0BEC11726D3374840FA2225668BFE13C035A0D61BD2374840DCA4DC5C80FE13C036B2E910D13748402FEE505E75FE13C0307E3B05D03748407C32D6696AFE13C02504CCF8CE374840C3716C7F5FFE13C0A3BDB0EBCD37484004AC139F54FE13C08BB7BEDDCC3748403FE1CBC849FE13C0FDE420CFCB374840ECDD40FD3EFE13C0F845D7BFCA3748401B091B3B34FE13C0EC60CCAFC937484032C85D8429FE13C0DB35009FC8374840CDB505D71EFE13C0523E888DC7374840D86A6A3414FE13C0C4004F7BC6374840DD1AE09B09FE13C0BFF66968C53748405492120EFFFD13C0B3A6C354C43748403BD1018BF4FD13C0318A7140C33748401D0B0212EAFD13C037A1732BC2374840700CBFA3DFFD13C03872B415C1374840BD088D3FD5FD13C0C17649FFBF3748407ACC17E6CAFD13C0D4AE32E8BE374840A9575F97C0FD13C0E0A05AD0BD374840D2DDB752B6FD13C076C6D6B7BC3748406C2BCD18ACFD13C02399BC9EBB37484078409FE9A1FD13C03BACCB84BA3748406BE9D9C597FD13C06C6C446AB9374840588D25AC8DFD13C02560114FB8374840402C829C83FD13C067873233B73748400F5F479879FD13C0A3689216B63748405059C99E6FFD13C0F7F65BF9B4374840021B08B065FD13C0D4B879DBB33748409B70AFCC5BFD13C039AEEBBCB23748402FC167F351FD13C028D7B19DB137484034D9DC2448FD13C0A033CC7DB03748402285BA613EFD13C0A0C33A5DAF37484080F854A934FD13C0B900133CAE3748404F33ACFB2AFD13C05A713F1AAD37484007026C5921FD13C08415C0F7AB3748402F98E8C117FD13C0C666AAD4AA374840C9F521350EFD13C00272D3B0A93748404BE7C3B304FD13C0E5A37B8CA8374840B56CCE3DFBFC13C0C28F6267A737484019EDE9D1F1FC13C046A2C841A6374840DCCD1972E8FC13C0C36E6D1BA53748401176061DDFFC13C059E87BF4A3374840B6E5AFD2D5FC13C0060FF4CCA2374840BBB56D94CCFC13C0CBE2D5A4A1374840314DE860C3FC13C019EA0B7CA037484018AC1F38BAFC13C0F02496529F3748405E6B6B1BB1FC13C06E869F289E37484015F27309A8FC13C0741BFDFD9C374840B50CE5029FFC13C0935DC4D29B3748403CBBBE0796FC13C0C94CF5A69A374840ACFD00188DFC13C0886F7A7A993748408D07003384FC13C0EEB87E4D98374840CD71135A7BFC13C0DC35D71F97374840F56F8F8C72FC13C072D9AEF195374840050274CA69FC13C090B0DAC294374840875B151361FC13C055AE8593933748406815CB6758FC13C0A3DF8463923748403063E9C74FFC13C09837033391374840E244703347FC13C016C3D50190374840F2860BAB3EFC13C03A7527D08E3748407390632D36FC13C0054EF89D8D37484054FACFBB2DFC13C0595A1D6B8C3748401DF8A45525FC13C0548DC1378B37484045568EFB1CFC13C0666DCF038A3748405548E0AC14FC13C090FA46CF883748404DCE9A690CFC13C061AE3D9A873748402DE8BD3104FC13C04A0F9E64863748406D62F505FCFB13C04B1D682E853748400C3D41E6F3FB13C081CBC6F78337484093ABF5D1EBFB13C040AD79C08237484003AE12C9E3FB13C0A6B5AB888137484048DDEFCCDBFB13C0B2E45C5080374840FFD389DBD3FB13C0663A8D177F3748408CF7E3F6CBFB13C0313D27DE7D37484001AFA61DC4FB13C0A26640A47C3748405EFAD14FBCFB13C0BBB6D8697B3748409272BD8EB4FB13C0EBB3DA2E7A374840AE7E11D9ACFB13C0C2D75BF37837484029EB792FA5FB13C040225CB7773748408CEB4A919DFB13C06493DB7A76374840C518DCFF95FB13C0BEA4EF3D75374840E7D9D5798EFB13C0A1E9570074374840DFC78F0087FB13C0B9CE54C272374840BF49B2927FFB13C00754E68371374840FE2BE93078FB13C06D86E144703748409D6E34DB70FB13C07ADF5B056F3748409A11949169FB13C02D5F55C56D374840F714085462FB13C0167FE3846C3748402B453C235BFB13C0A5C5F0436B3748404609D9FD53FB13C0DC327D026A374840C12D8AE44CFB13C047409EC068374840127FFBD745FB13C05A743E7E67374840C23081D73EFB13C013CF5D3B663748405A766FE237FB13C002CA11F864374840C9E81DFA30FB13C097EB44B4633748400E888C1E2AFB13C0D433F76F623748403BBB634E23FB13C0D495532B613748403F1BFB8A1CFB13C0EDA419E65F374840A1DBA6D315FB13C0CACD89A05E374840DAC812290FFB13C04D1D795A5D3748407316938A08FB13C0060DFD135C3748406AC427F801FB13C0662300CD5A374840389F7C72FBFA13C08B53AD855937484065DAE5F8F4FA13C056AAD93D5837484068420F8CEEFA13C056A19AF556374840CB0A4D2BE8FA13C08D38F0AC553748408C339FD6E1FA13C06AF6C463543748402589B18EDBFA13C00BCE431A53374840930B8453D5FA13C0E24557D05137484060EE6A24CFFA13C0EF5DFF855037484004FE1102C9FA13C031163C3B4F3748407F3A79ECC2FA13C0A86E0DF04D37484058D7F4E2BCFA13C0566773A44C37484008A130E6B6FA13C0C87983584B37484017CB80F5B0FA13C0E0B2120C4A37484073EE3C12ABFA13C0BD054CBF483748402E720D3BA5FA13C0D0F81972473748404956F26F9FFA13C0A705922446374840B13343B299FA13C0B3B29ED6443748407971A80094FA13C084795588433748408DA8795C8EFA13C08BE0A0394237484001405FC488FA13C0C7E780EA40374840D537593883FA13C0C8080B9B3F374840F528BFB97DFA13C08D433F4B3E374840EC46E54778FA13C0871E08FB3C374840B991CBE272FA13C047137BAA3B374840E63CC6896DFA13C0CA2198593A37484060E12C3E68FA13C084D049083937484039E6A7FE62FA13C00199A5B6373748405FE48ECC5DFA13C0437BAB64363748405C0F36A758FA13C04A775B1235374840B79AF18D53FA13C0158DB5BF33374840611F19824EFA13C0A5BCB96C32374840E0D0008349FA13C0F90568193137484036AFA89044FA13C082EFAAC52F37484062BA10AB3FFA13C05F6CAD712E37484065F238D23AFA13C001035A1D2D3748403E57210636FA13C067B3B0C82B37484064B5754731FA13C020F7C6732A37484060408A952CFA13C00FDB711E2937484033F85EF027FA13C05152DCC827374840DCDCF35723FA13C057E3F072263748405BEE48CC1EFA13C0B107C51C2537484028F9094E1AFA13C0D04543C623374840CB308BDC15FA13C0B39D6B6F223748404495CC7711FA13C0E9885318213748400BF379200DFA13C07307FBC01F374840A87DE7D508FA13C0322637691E3748401B35159804FA13C0D35148111D374840DCE5AE6700FA13C0399703B91B37484073C30844FCF913C0F36F7E601A374840579ACE2DF8F913C07062A30719374840129E5424F4F913C0D0619DAE17374840A3CE9A27F0F913C0F57A41551637484081F84C38ECF913C06C27A5FB14374840364FBF55E8F913C03767C8A113374840389F9D80E4F913C0C7C0954712374840101C3CB8E0F913C0392738ED10374840BFC59AFCDCF913C0FE209A920F3748403235114FD9F913C016AEBB370E37484004059CADD5F913C0F35487DC0C3748409A9A3E1AD2F913C0B30828810B3748409090F592CEF913C054C99D250A3748404B4CC419CBF913C0BAA3BDC908374840DB3453ADC7F913C0028BB26D07374840424AA24DC4F913C00F8C5111063748406E2509FCC0F913C08C13DBB404374840F86084B6BDF913C0CFB40E58033748404762177FBAF913C0F36217FB013748406D906A54B7F913C0FA1DF59D00374840DFB72937B4F913C0546C9240FF364840280CA926B1F913C0014EEFE2FD364840BF599423AEF913C0913C2185FC364840A2A0EB2DABF913C002382827FB364840D4E0AE45A8F913C0C8C6EEC8F9364840DB4D326AA5F913C06F628A6AF836484030B4219CA2F913C0F90AFB0BF73648405B47D1DA9FF913C065C040ADF53648404AA098279DF913C02409464EF4364840102620819AF913C0C55E20EFF236484023A513E897F913C049C1CF8FF1364840841D735C95F913C03EAA6930F0364840BBC292DD92F913C08626C3D0EE3648403F611E6C90F913C0B0AFF170ED36484011F915088EF913C0BD45F510EC364840308A79B18BF913C0ACE8CDB0EA3648409C14496889F913C00C129150E93648405698842C87F913C0BFCE13F0E7364840E64880FD84F913C0E311818FE6364840C3F2E7DB82F913C079DBD82EE5364840EE95BBC780F913C06238F0CDE33648406632FBC07EF913C0BC1BF26CE23648402BC8A6C77CF913C0F80BC90BE13648403E57BEDB7AF913C0A5828AAADF364840271396FC78F913C035062149DE364840D594852B77F913C03610A2E7DC3648405943356775F913C01927F885DB364840A1B7FCB073F913C06DC43824DA364840', 'TRA', false, NULL, 'MONITORENV', false, NULL, '{LAND}'); +INSERT INTO public.missions (id, open_by, observations_cacem, facade, start_datetime_utc, end_datetime_utc, geom, closed_by, deleted, observations_cnsp, mission_source, closed, mission_order, mission_types) VALUES (10, 'KIM', 'Remain vote several ok. Bring American play woman challenge. Throw low law positive seven.', 'NAMO', '2022-03-21 12:11:13', NULL, '0106000020E610000001000000010300000001000000050000008AA293E7F23112C0EBC80D961C274840494ABC342C3312C0C127CE382A27484000F63C452F3312C077C8A4F151274840A51B17C4F63112C0B998F263442748408AA293E7F23112C0EBC80D961C274840', 'TRA', false, NULL, 'MONITORENV', false, NULL, '{LAND}'); INSERT INTO public.missions (id, open_by, observations_cacem, facade, start_datetime_utc, end_datetime_utc, geom, closed_by, deleted, observations_cnsp, mission_source, closed, mission_order, mission_types) VALUES (0, 'LOR', 'Worker smile spend parent certain tell dream. Small hope professor thus. Every nothing rest myself.', 'MED', '2022-05-10 12:23:59', NULL, NULL, 'KYL', false, NULL, 'MONITORENV', false, NULL, '{SEA}'); INSERT INTO public.missions (id, open_by, observations_cacem, facade, start_datetime_utc, end_datetime_utc, geom, closed_by, deleted, observations_cnsp, mission_source, closed, mission_order, mission_types) VALUES (14, 'MRS', 'Laugh surface few military current fine set. Wife list culture.', 'SA', '2022-03-12 03:48:14', '2022-05-15 03:13:36', NULL, 'MIC', false, NULL, 'MONITORENV', true, NULL, '{AIR}'); INSERT INTO public.missions (id, open_by, observations_cacem, facade, start_datetime_utc, end_datetime_utc, geom, closed_by, deleted, observations_cnsp, mission_source, closed, mission_order, mission_types) VALUES (15, 'KAT', 'Population source pass recognize a modern. Might board take both century.', 'MEMN', '2022-01-21 18:52:58', '2022-02-20 20:37:16', NULL, 'AND', false, NULL, 'MONITORENV', true, NULL, '{LAND}'); diff --git a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql index e5e0810d2..c25d49304 100644 --- a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql +++ b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql @@ -27,17 +27,29 @@ UPDATE public.env_actions SET WHERE mission_id > 20; ; -INSERT INTO public.env_actions_control_plan_sub_themes(env_action_id, subtheme_id, tags) VALUES -('e2257638-ddef-4611-960c-7675a3254c38', 51, NULL), -('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 83, NULL), -('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 43, NULL), -('475d2887-5344-46cd-903b-8cb5e42f9a9c', 79, NULL), -('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 48, NULL), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 52, '{"Flore, Oiseaux"}'), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 7, '{"Flore, Oiseaux"}'), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 64, NULL), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 82, NULL), -('b8007c8a-5135-4bc3-816f-c69c7b75d807', 64, NULL), -('b8007c8a-5135-4bc3-816f-c69c7b75d807', 82, NULL), -('4d9a3139-6c60-49a5-b443-0e6238a6a120', 42, NULL) +INSERT INTO public.env_actions_control_plan_themes (env_action_id, theme_id) VALUES +('b8007c8a-5135-4bc3-816f-c69c7b75d807', 12), +('475d2887-5344-46cd-903b-8cb5e42f9a9c', 16), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 12), +('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 15), +('e2257638-ddef-4611-960c-7675a3254c38', 9), +('4d9a3139-6c60-49a5-b443-0e6238a6a120', 12), +('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 1) ; + +INSERT INTO public.env_actions_control_plan_sub_themes(env_action_id, subtheme_id) VALUES +('e2257638-ddef-4611-960c-7675a3254c38', 51), +('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 83), +('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 43), +('475d2887-5344-46cd-903b-8cb5e42f9a9c', 79), +('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 48), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 64), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 82), +('b8007c8a-5135-4bc3-816f-c69c7b75d807', 64), +('b8007c8a-5135-4bc3-816f-c69c7b75d807', 82), +('4d9a3139-6c60-49a5-b443-0e6238a6a120', 42) +; + +INSERT INTO public.env_actions_control_plan_tags(env_action_id, tag_id) VALUES +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 1), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 2); diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt deleted file mode 100644 index ab966d9f3..000000000 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan - -import com.nhaarman.mockitokotlin2.given -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity -import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.extension.ExtendWith -import org.springframework.boot.test.mock.mockito.MockBean -import org.springframework.test.context.junit.jupiter.SpringExtension - -@ExtendWith(SpringExtension::class) -class GetControlPlanSubThemesByYearUTest { - @MockBean - private lateinit var controlPlanSubThemeRepository: IControlPlanSubThemeRepository - - fun `execute should return all ControlPlanSubThemes for the given year`() { - val controlPlanSubThemes = listOf( - ControlPlanSubThemeEntity( - id = 1, - theme = "ControlPlanThemeEntity Name", - subTheme = "ControlPlanSubTheme Name", - allowedTags = listOf("tag1", "tag2"), - year = 2023, - ), - ControlPlanSubThemeEntity( - id = 2, - theme = "ControlPlanThemeEntity Name 2", - subTheme = "ControlPlanSubTheme Name 2", - allowedTags = null, - year = 2023, - ), - ) - - given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) - - val result = GetControlPlansByYear(controlPlanSubThemeRepository).execute(2023) - - assertThat(result.size).isEqualTo(2) - assertThat(result).isEqualTo(controlPlanSubThemes) - } -} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt new file mode 100644 index 000000000..54a797616 --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt @@ -0,0 +1,73 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan + +import com.nhaarman.mockitokotlin2.given +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanTagRepository +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.junit.jupiter.SpringExtension + +@ExtendWith(SpringExtension::class) +class GetControlPlansByYearUTest { + @MockBean + private lateinit var controlPlanSubThemeRepository: IControlPlanSubThemeRepository + private lateinit var controlPlanThemeRepository: IControlPlanThemeRepository + private lateinit var controlPlanTagRepository: IControlPlanTagRepository + + fun `execute should return all ControlPlanThemes, ControlPlanSubThemes and ControlPlanTags for the given year`() { + val controlPlanThemes = listOf( + ControlPlanThemeEntity( + id = 1, + theme = "ControlPlanTheme Name", + ), + ControlPlanThemeEntity( + id = 2, + theme = "ControlPlanTheme Name 2", + ), + ) + val controlPlanSubThemes = listOf( + ControlPlanSubThemeEntity( + id = 1, + themeId = 1, + subTheme = "ControlPlanSubTheme Name", + year = 2023, + ), + ControlPlanSubThemeEntity( + id = 2, + themeId = 1, + subTheme = "ControlPlanSubTheme Name 2", + year = 2023, + ), + ) + val controlPlanTags = listOf( + ControlPlanTagEntity( + id = 1, + tag = "ControlPlanTag Name", + themeId = 1, + ), + ControlPlanTagEntity( + id = 2, + tag = "ControlPlanTag Name 2", + themeId = 2, + ), + ) + + given(controlPlanThemeRepository.findByYear(2023)).willReturn(controlPlanThemes) + given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) + given(controlPlanTagRepository.findByYear(2023)).willReturn(controlPlanTags) + + val result = GetControlPlansByYear( + controlPlanThemeRepository = controlPlanThemeRepository, + controlPlanSubThemeRepository = controlPlanSubThemeRepository, + controlPlanTagRepository = controlPlanTagRepository, + ).execute(2023) + + assertThat(result.first.size).isEqualTo(2) + assertThat(result).isEqualTo(controlPlanSubThemes) + } +} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt deleted file mode 100644 index 9d46374d2..000000000 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt +++ /dev/null @@ -1,51 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff - -import com.nhaarman.mockitokotlin2.verify -import fr.gouv.cacem.monitorenv.config.WebSecurityConfig -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity -import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlansByYear -import org.junit.jupiter.api.Test -import org.mockito.BDDMockito -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest -import org.springframework.boot.test.mock.mockito.MockBean -import org.springframework.context.annotation.Import -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get -import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath -import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status - -@Import(WebSecurityConfig::class) -@WebMvcTest(value = [(ControlPlanSubThemesController::class)]) -class ControlPlanSubThemesControllerITests { - @Autowired - private lateinit var mockMvc: MockMvc - - @MockBean - private lateinit var getControlPlansByYear: GetControlPlansByYear - - @Test - fun `Should get all control plan themes`() { - // Given - val ControlPlanSubTheme = ControlPlanSubThemeEntity( - id = 1, - theme = "Theme Police des mouillages", - subTheme = "Sous Theme Mouillage individuel", - allowedTags = listOf("tag1", "tag2"), - year = 2024, - ) - BDDMockito.given(getControlPlansByYear.execute(2024)).willReturn(listOf(ControlPlanSubTheme)) - // When - mockMvc.perform(get("/bff/v1/controlPlanSubThemes/2024")) - // Then - .andExpect(status().isOk) - .andExpect(jsonPath("$[0].id").value(ControlPlanSubTheme.id)) - .andExpect(jsonPath("$[0].theme").value(ControlPlanSubTheme.theme)) - .andExpect(jsonPath("$[0].subTheme").value(ControlPlanSubTheme.subTheme)) - .andExpect(jsonPath("$[0].year").value(ControlPlanSubTheme.year)) - .andExpect(jsonPath("$[0].allowedTags[0]").value(ControlPlanSubTheme.allowedTags?.get(0))) - .andExpect(jsonPath("$[0].allowedTags[1]").value(ControlPlanSubTheme.allowedTags?.get(1))) - - verify(getControlPlansByYear).execute(2024) - } -} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt new file mode 100644 index 000000000..61eec182a --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt @@ -0,0 +1,72 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff + +import com.nhaarman.mockitokotlin2.verify +import fr.gouv.cacem.monitorenv.config.WebSecurityConfig +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlansByYear +import org.junit.jupiter.api.Test +import org.mockito.BDDMockito +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.context.annotation.Import +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status + +@Import(WebSecurityConfig::class) +@WebMvcTest(value = [(ControlPlansController::class)]) +class ControlPlansControllerITests { + @Autowired + private lateinit var mockMvc: MockMvc + + @MockBean + private lateinit var getControlPlansByYear: GetControlPlansByYear + + @Test + fun `Should get all control plan themes`() { + // Given + val controlPlanTheme1 = ControlPlanThemeEntity( + id = 1, + theme = "Theme Police des mouillages", + ) + val controlPlanTheme2 = ControlPlanThemeEntity( + id = 2, + theme = "Theme Protection des espèces", + ) + val controlPlanSubTheme1 = ControlPlanSubThemeEntity( + id = 10, + themeId = 1, + subTheme = "SubTheme ZMEL", + year = 2024, + ) + val controlPlanTag = ControlPlanTagEntity( + id = 100, + themeId = 2, + tag = "Tag Bichique", + ) + val controlPlan = Triple( + listOf(controlPlanTheme1, controlPlanTheme2), + listOf(controlPlanSubTheme1), + listOf(controlPlanTag), + ) + BDDMockito.given(getControlPlansByYear.execute(2024)).willReturn(controlPlan) + // When + mockMvc.perform(get("/bff/v1/control_plans/2024")) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) + .andExpect(jsonPath("$.subThemes[\"10\"].subTheme").value(controlPlanSubTheme1.subTheme)) + .andExpect(jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId)) + .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) + .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) + .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) + + verify(getControlPlansByYear).execute(2024) + } +} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt index bd5b1d16d..2008e38a1 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt @@ -10,7 +10,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionSourceEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.ActionTargetTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity @@ -67,12 +67,13 @@ class MissionsControllerITests { @Autowired private lateinit var objectMapper: ObjectMapper + private val polygon = WKTReader().read( + "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))", + ) as MultiPolygon + private val point = WKTReader().read("POINT (-4.54877816747593 48.305559876971)") as Point + @Test fun `Should create a new mission`() { - val wktReader = WKTReader() - val multipolygonString = - "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))" - val polygon = wktReader.read(multipolygonString) as MultiPolygon // Given val expectedNewMission = MissionDTO( @@ -130,24 +131,17 @@ class MissionsControllerITests { @Test fun `Should get all missions`() { // Given - val wktReader = WKTReader() - val multipolygonString = - "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))" - val polygon = wktReader.read(multipolygonString) as MultiPolygon - - val point = wktReader.read("POINT (-4.54877816747593 48.305559876971)") as Point val controlEnvAction = EnvActionControlEntity( id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - controlPlanSubThemes = listOf( - EnvActionControlPlanSubThemeEntity( - subThemeId = 1, - subTheme = "sous theme 1", - tags = listOf("tag 1", "tag 2"), - theme = "Theme 1", + controlPlans = listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(1), + tagIds = listOf(1, 2), + themeId = 1, ), ), geom = point, @@ -344,11 +338,10 @@ class MissionsControllerITests { equalTo("2022-01-23T20:29:03Z"), ), ) - .andExpect(jsonPath("$[0].envActions[0].controlPlan[0].id", equalTo(1))) - .andExpect(jsonPath("$[0].envActions[0].controlPlan[0].theme", equalTo("Theme 1"))) - .andExpect(jsonPath("$[0].envActions[0].controlPlan[0].subTheme", equalTo("sous theme 1"))) - .andExpect(jsonPath("$[0].envActions[0].controlPlan[0].tags[0]", equalTo("tag 1"))) - .andExpect(jsonPath("$[0].envActions[0].controlPlan[0].tags[1]", equalTo("tag 2"))) + .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].themeId", equalTo(1))) + .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].subThemeIds[0]", equalTo(1))) + .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].tagIds[0]", equalTo(1))) + .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].tagIds[1]", equalTo(2))) .andExpect(jsonPath("$[0].envActions[0].geom.type", equalTo("Point"))) .andExpect(jsonPath("$[0].envActions[0].facade", equalTo("Outre-Mer"))) .andExpect(jsonPath("$[0].envActions[0].department", equalTo("29"))) @@ -469,23 +462,16 @@ class MissionsControllerITests { // Given val requestedId = 0 - val wktReader = WKTReader() - val multipolygonString = - "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))" - val polygon = wktReader.read(multipolygonString) as MultiPolygon - val point = wktReader.read("POINT (-4.54877816747593 48.305559876971)") as Point - val controlEnvAction = EnvActionControlEntity( id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - controlPlanSubThemes = listOf( - EnvActionControlPlanSubThemeEntity( - subThemeId = 1, - subTheme = "sous theme 1", - tags = listOf("tag 1", "tag 2"), - theme = "Theme 1", + controlPlans = listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(1), + tagIds = listOf(1, 2), + themeId = 1, ), ), geom = point, @@ -668,11 +654,10 @@ class MissionsControllerITests { equalTo("2022-01-23T20:29:03Z"), ), ) - .andExpect(jsonPath("$.envActions[0].controlPlan[0].id", equalTo(1))) - .andExpect(jsonPath("$.envActions[0].controlPlan[0].subTheme", equalTo("sous theme 1"))) - .andExpect(jsonPath("$.envActions[0].controlPlan[0].tags[0]", equalTo("tag 1"))) - .andExpect(jsonPath("$.envActions[0].controlPlan[0].tags[1]", equalTo("tag 2"))) - .andExpect(jsonPath("$.envActions[0].controlPlan[0].theme", equalTo("Theme 1"))) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].themeId", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].subThemeIds[0]", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].tagIds[0]", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].tagIds[1]", equalTo(2))) .andExpect(jsonPath("$.envActions[0].geom.type", equalTo("Point"))) .andExpect(jsonPath("$.envActions[0].facade", equalTo("Outre-Mer"))) .andExpect(jsonPath("$.envActions[0].department", equalTo("29"))) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt index d4965b21c..279363026 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt @@ -15,17 +15,13 @@ class JpaControlPlanSubThemeRepositoryITests : AbstractDBTests() { val requestedControlPlanSubThemesFor2024 = jpaControlPlanSubThemeRepository.findByYear(2024) // Then assertThat(requestedControlPlanSubThemesFor2023.size).isEqualTo(83) - assertThat(requestedControlPlanSubThemesFor2024.size).isEqualTo(7) - assertThat(requestedControlPlanSubThemesFor2024[6].id).isEqualTo(90) - assertThat(requestedControlPlanSubThemesFor2024[6].theme).isEqualTo( - "Police des espèces protégées et de leurs habitats (faune et flore)", + assertThat(requestedControlPlanSubThemesFor2024.size).isEqualTo(6) + assertThat(requestedControlPlanSubThemesFor2024[5].id).isEqualTo(89) + assertThat(requestedControlPlanSubThemesFor2024[5].themeId).isEqualTo(11) + assertThat(requestedControlPlanSubThemesFor2024[5].subTheme).isEqualTo( + "Destruction, capture, arrachage", ) - assertThat(requestedControlPlanSubThemesFor2024[6].subTheme).isEqualTo( - "Atteinte aux habitats d’espèces protégées", - ) - assertThat(requestedControlPlanSubThemesFor2024[6].allowedTags).isEqualTo( - listOf("Oiseaux", "Faune", "Flore", "Autres espèces protégées", "Reptiles", "Mammifères marins"), - ) - assertThat(requestedControlPlanSubThemesFor2024[6].year).isEqualTo(2024) + + assertThat(requestedControlPlanSubThemesFor2024[5].year).isEqualTo(2024) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt index d6ff20e55..19c5fada6 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt @@ -6,7 +6,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlUnit.LegacyControlUnitRes import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionSourceEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionTypeEnum -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionNoteEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionSurveillanceEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.ActionTargetTypeEnum @@ -16,8 +16,8 @@ import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.catchThrowable import org.junit.jupiter.api.Test -import org.locationtech.jts.geom.MultiPoint import org.locationtech.jts.geom.MultiPolygon +import org.locationtech.jts.geom.Point import org.locationtech.jts.io.WKTReader import org.springframework.beans.factory.annotation.Autowired import org.springframework.dao.DataIntegrityViolationException @@ -36,6 +36,11 @@ class JpaMissionRepositoryITests : AbstractDBTests() { @Autowired private lateinit var jpaControlUnitResourceRepository: JpaControlUnitResourceRepository + private val polygon = WKTReader().read( + "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))", + ) as MultiPolygon + private val point = WKTReader().read("POINT (-4.54877816747593 48.305559876971)") as Point + @Test @Transactional fun `delete Should set the deleted flag as true`() { @@ -301,10 +306,6 @@ class JpaMissionRepositoryITests : AbstractDBTests() { @Transactional fun `findById Should return specified mission`() { // When - val wktReader = WKTReader() - val multipolygonString = - "MULTIPOLYGON (((-4.99360539 48.42853215, -4.99359905 48.42848997, -4.99359291 48.42844777, -4.99358697 48.42840556, -4.99358123 48.42836334, -4.99357569 48.4283211, -4.99357035 48.42827886, -4.9935652 48.4282366, -4.99356026 48.42819434, -4.99355552 48.42815206, -4.99355097 48.42810977, -4.99354663 48.42806748, -4.99354249 48.42802517, -4.99353854 48.42798286, -4.9935348 48.42794054, -4.99353125 48.42789821, -4.99352791 48.42785587, -4.99352476 48.42781353, -4.99352182 48.42777118, -4.99351907 48.42772882, -4.99351653 48.42768646, -4.99351418 48.4276441, -4.99351203 48.42760173, -4.99351009 48.42755935, -4.99350834 48.42751697, -4.9935068 48.42747459, -4.99350545 48.42743221, -4.99350431 48.42738982, -4.99350336 48.42734743, -4.99350262 48.42730504, -4.99350207 48.42726264, -4.99350173 48.42722025, -4.99350158 48.42717785, -4.99350164 48.42713546, -4.99350189 48.42709307, -4.99350235 48.42705067, -4.99350301 48.42700828, -4.99350386 48.42696589, -4.99350492 48.4269235, -4.99350617 48.42688111, -4.99350763 48.42683873, -4.99350929 48.42679635, -4.99351114 48.42675397, -4.9935132 48.4267116, -4.99351545 48.42666923, -4.99351791 48.42662687, -4.99352057 48.42658451, -4.99352342 48.42654216, -4.99352648 48.42649981, -4.99352973 48.42645747, -4.99353319 48.42641514, -4.99353685 48.42637282, -4.9935407 48.4263305, -4.99354476 48.42628819, -4.99354901 48.42624589, -4.99355346 48.4262036, -4.99355812 48.42616132, -4.99356297 48.42611905, -4.99356802 48.42607679, -4.99357328 48.42603454, -4.99357873 48.4259923, -4.99358438 48.42595007, -4.99359023 48.42590785, -4.99359628 48.42586565, -4.99360253 48.42582346, -4.99360898 48.42578128, -4.99361562 48.42573912, -4.99362247 48.42569697, -4.99362951 48.42565484, -4.99363676 48.42561272, -4.9936442 48.42557061, -4.99365184 48.42552853, -4.99365968 48.42548645, -4.99366772 48.4254444, -4.99367596 48.42540236, -4.99368439 48.42536034, -4.99369302 48.42531833, -4.99370186 48.42527635, -4.99371089 48.42523438, -4.99372011 48.42519243, -4.99372954 48.42515051, -4.99373916 48.4251086, -4.99374898 48.42506671, -4.993759 48.42502484, -4.99376922 48.424983, -4.99377963 48.42494117, -4.99379024 48.42489937, -4.99380105 48.42485759, -4.99381206 48.42481583, -4.99382326 48.4247741, -4.99383466 48.42473239, -4.99384626 48.4246907, -4.99385805 48.42464904, -4.99387004 48.42460741, -4.99388223 48.42456579, -4.99389461 48.42452421, -4.99390719 48.42448265, -4.99391996 48.42444111, -4.99393293 48.42439961, -4.9939461 48.42435813, -4.99395946 48.42431668, -4.99397302 48.42427525, -4.99398677 48.42423386, -4.99400072 48.42419249, -4.99401487 48.42415116, -4.9940292 48.42410985, -4.99404374 48.42406857, -4.99405847 48.42402733, -4.99407339 48.42398611, -4.99408851 48.42394493, -4.99410382 48.42390378, -4.99411932 48.42386266, -4.99413502 48.42382157, -4.99415092 48.42378052, -4.994167 48.4237395, -4.99418328 48.42369851, -4.99419976 48.42365756, -4.99421643 48.42361664, -4.99423329 48.42357576, -4.99425034 48.42353491, -4.99426759 48.4234941, -4.99428502 48.42345333, -4.99430265 48.42341259, -4.99432048 48.42337189, -4.99433849 48.42333122, -4.9943567 48.4232906, -4.9943751 48.42325001, -4.99439369 48.42320946, -4.99441247 48.42316895, -4.99443144 48.42312848, -4.9944506 48.42308805, -4.99446996 48.42304766, -4.9944895 48.42300731, -4.99450924 48.422967, -4.99452916 48.42292673, -4.99454928 48.42288651, -4.99456958 48.42284633, -4.99459007 48.42280619, -4.99461076 48.42276609, -4.99463163 48.42272603, -4.99465269 48.42268602, -4.99467394 48.42264606, -4.99469538 48.42260614, -4.99471701 48.42256626, -4.99473882 48.42252643, -4.99476082 48.42248665, -4.99478301 48.42244691, -4.99480539 48.42240721, -4.99482796 48.42236757, -4.99485071 48.42232797, -4.99487365 48.42228842, -4.99489677 48.42224892, -4.99492008 48.42220947, -4.99494358 48.42217006, -4.99496727 48.42213071, -4.99499113 48.4220914, -4.99501519 48.42205215, -4.99503943 48.42201294, -4.99506385 48.42197379, -4.99508846 48.42193469, -4.99511326 48.42189563, -4.99513823 48.42185664, -4.99516339 48.42181769, -4.99518874 48.4217788, -4.99521427 48.42173995, -4.99523998 48.42170117, -4.99526587 48.42166243, -4.99529195 48.42162376, -4.99531821 48.42158513, -4.99534465 48.42154656, -4.99537128 48.42150805, -4.99539808 48.42146959, -4.99542507 48.42143119, -4.99545224 48.42139285, -4.99547959 48.42135456, -4.99550711 48.42131633, -4.99553482 48.42127816, -4.99556271 48.42124004, -4.99559078 48.42120199, -4.99561903 48.42116399, -4.99564746 48.42112605, -4.99567606 48.42108817, -4.99570485 48.42105035, -4.99573381 48.4210126, -4.99576295 48.4209749, -4.99579227 48.42093726, -4.99582177 48.42089969, -4.99585144 48.42086218, -4.99588129 48.42082473, -4.99591132 48.42078734, -4.99594152 48.42075001, -4.9959719 48.42071275, -4.99600246 48.42067555, -4.99603319 48.42063842, -4.9960641 48.42060135, -4.99609518 48.42056435, -4.99612643 48.42052741, -4.99615786 48.42049053, -4.99618946 48.42045372, -4.99622124 48.42041698, -4.99625319 48.42038031, -4.99628531 48.4203437, -4.9963176 48.42030716, -4.99635007 48.42027069, -4.99638271 48.42023428, -4.99641552 48.42019794, -4.9964485 48.42016168, -4.99648166 48.42012548, -4.99651498 48.42008935, -4.99654847 48.42005329, -4.99658214 48.4200173, -4.99661597 48.41998138, -4.99664997 48.41994553, -4.99668415 48.41990976, -4.99671849 48.41987405, -4.996753 48.41983842, -4.99678767 48.41980286, -4.99682252 48.41976737, -4.99685753 48.41973196, -4.99689271 48.41969662, -4.99692805 48.41966135, -4.99696356 48.41962616, -4.99699924 48.41959104, -4.99703508 48.41955599, -4.99707109 48.41952102, -4.99710726 48.41948613, -4.9971436 48.41945131, -4.9971801 48.41941657, -4.99721677 48.4193819, -4.9972536 48.41934732, -4.99729059 48.4193128, -4.99732774 48.41927837, -4.99736506 48.41924402, -4.99740254 48.41920974, -4.99744018 48.41917554, -4.99747798 48.41914142, -4.99751594 48.41910738, -4.99755406 48.41907342, -4.99759234 48.41903953, -4.99763079 48.41900573, -4.99766939 48.41897201, -4.99770815 48.41893837, -4.99774707 48.41890481, -4.99778614 48.41887133, -4.99782538 48.41883794, -4.99786477 48.41880463, -4.99790432 48.4187714, -4.99794402 48.41873825, -4.99798388 48.41870518, -4.9980239 48.4186722, -4.99806408 48.4186393, -4.9981044 48.41860649, -4.99814489 48.41857376, -4.99818552 48.41854112, -4.99822631 48.41850856, -4.99826726 48.41847609, -4.99830835 48.4184437, -4.9983496 48.4184114, -4.99839101 48.41837918, -4.99843256 48.41834705, -4.99847426 48.41831501, -4.99851612 48.41828306, -4.99855813 48.41825119, -4.99860028 48.41821941, -4.99864259 48.41818772, -4.99868504 48.41815612, -4.99872765 48.41812461, -4.9987704 48.41809319, -4.9988133 48.41806185, -4.99885635 48.41803061, -4.99889955 48.41799946, -4.99894289 48.41796839, -4.99898638 48.41793742, -4.99903001 48.41790654, -4.99907379 48.41787575, -4.99911772 48.41784505, -4.99916179 48.41781444, -4.999206 48.41778393, -4.99925036 48.41775351, -4.99929486 48.41772318, -4.99933951 48.41769294, -4.99938429 48.4176628, -4.99942922 48.41763276, -4.99947429 48.4176028, -4.9995195 48.41757294, -4.99956485 48.41754318, -4.99961035 48.41751351, -4.99965598 48.41748393, -4.99970175 48.41745445, -4.99974766 48.41742507, -4.99979371 48.41739578, -4.99983989 48.41736659, -4.99988622 48.4173375, -4.99993268 48.4173085, -4.99997927 48.4172796, -5.00002601 48.4172508, -5.00007288 48.4172221, -5.00011988 48.41719349, -5.00016702 48.41716498, -5.00021429 48.41713657, -5.0002617 48.41710826, -5.00030924 48.41708005, -5.00035691 48.41705194, -5.00040472 48.41702393, -5.00045266 48.41699602, -5.00050072 48.41696821, -5.00054892 48.4169405, -5.00059725 48.41691289, -5.00064571 48.41688538, -5.0006943 48.41685797, -5.00074302 48.41683067, -5.00079187 48.41680346, -5.00084085 48.41677636, -5.00088995 48.41674937, -5.00093918 48.41672247, -5.00098854 48.41669568, -5.00103802 48.41666899, -5.00108763 48.4166424, -5.00113736 48.41661592, -5.00118722 48.41658954, -5.0012372 48.41656327, -5.00128731 48.4165371, -5.00133754 48.41651104, -5.00138789 48.41648508, -5.00143837 48.41645923, -5.00148896 48.41643348, -5.00153968 48.41640784, -5.00159052 48.4163823, -5.00164148 48.41635688, -5.00169256 48.41633155, -5.00174375 48.41630634, -5.00179507 48.41628123, -5.0018465 48.41625623, -5.00189805 48.41623134, -5.00194972 48.41620655, -5.00200151 48.41618187, -5.00205341 48.41615731, -5.00210543 48.41613285, -5.00215756 48.4161085, -5.00220981 48.41608425, -5.00226217 48.41606012, -5.00231465 48.4160361, -5.00236723 48.41601219, -5.00241993 48.41598838, -5.00247275 48.41596469, -5.00252567 48.41594111, -5.00257871 48.41591764, -5.00263185 48.41589428, -5.00268511 48.41587103, -5.00273847 48.41584789, -5.00279195 48.41582486, -5.00284553 48.41580195, -5.00289922 48.41577915, -5.00295301 48.41575646, -5.00300692 48.41573388, -5.00306093 48.41571142, -5.00311504 48.41568907, -5.00316927 48.41566683, -5.00322359 48.4156447, -5.00327802 48.41562269, -5.00333255 48.4156008, -5.00338719 48.41557901, -5.00344193 48.41555735, -5.00349677 48.41553579, -5.00355171 48.41551435, -5.00360676 48.41549303, -5.0036619 48.41547182, -5.00371714 48.41545073, -5.00377249 48.41542975, -5.00382793 48.41540889, -5.00388347 48.41538814, -5.0039391 48.41536751, -5.00399484 48.415347, -5.00405067 48.4153266, -5.00410659 48.41530632, -5.00416261 48.41528616, -5.00421873 48.41526611, -5.00427494 48.41524619, -5.00433125 48.41522638, -5.00438764 48.41520668, -5.00444413 48.41518711, -5.00450072 48.41516765, -5.00455739 48.41514831, -5.00461416 48.41512909, -5.00467101 48.41510999, -5.00472796 48.41509101, -5.00478499 48.41507215, -5.00484211 48.41505341, -5.00489932 48.41503478, -5.00495662 48.41501628, -5.00501401 48.4149979, -5.00507148 48.41497963, -5.00512904 48.41496149, -5.00518668 48.41494347, -5.00524441 48.41492556, -5.00530222 48.41490778, -5.00536012 48.41489012, -5.0054181 48.41487258, -5.00547616 48.41485516, -5.0055343 48.41483786, -5.00559252 48.41482069, -5.00565083 48.41480364, -5.00570921 48.4147867, -5.00576768 48.4147699, -5.00582622 48.41475321, -5.00588485 48.41473664, -5.00594355 48.4147202, -5.00600232 48.41470388, -5.00606118 48.41468769, -5.00612011 48.41467161, -5.00617911 48.41465566, -5.00623819 48.41463984, -5.00629735 48.41462414, -5.00635658 48.41460856, -5.00641588 48.4145931, -5.00647525 48.41457777, -5.0065347 48.41456257, -5.00659422 48.41454748, -5.00665381 48.41453253, -5.00671347 48.41451769, -5.0067732 48.41450298, -5.00683299 48.4144884, -5.00689286 48.41447394, -5.00695279 48.41445961, -5.0070128 48.4144454, -5.00707286 48.41443132, -5.007133 48.41441736, -5.0071932 48.41440353, -5.00725346 48.41438983, -5.00731379 48.41437625, -5.00737419 48.4143628, -5.00743464 48.41434947, -5.00749516 48.41433627, -5.00755574 48.4143232, -5.00761638 48.41431025, -5.00767709 48.41429743, -5.00773785 48.41428474, -5.00779867 48.41427218, -5.00785955 48.41425974, -5.00792049 48.41424743, -5.00798149 48.41423525, -5.00804255 48.41422319, -5.00810366 48.41421126, -5.00816482 48.41419946, -5.00822605 48.41418779, -5.00828732 48.41417625, -5.00834866 48.41416483, -5.00841004 48.41415354, -5.00847148 48.41414238, -5.00853297 48.41413135, -5.00859451 48.41412045, -5.0086561 48.41410968, -5.00871775 48.41409903, -5.00877944 48.41408852, -5.00884119 48.41407813, -5.00890298 48.41406787, -5.00896482 48.41405775, -5.0090267 48.41404775, -5.00908864 48.41403788, -5.00915062 48.41402814, -5.00921264 48.41401853, -5.00927471 48.41400905, -5.00933683 48.4139997, -5.00939899 48.41399048, -5.00946119 48.41398139, -5.00952344 48.41397243, -5.00958572 48.4139636, -5.00964805 48.4139549, -5.00971042 48.41394633, -5.00977283 48.41393789, -5.00983528 48.41392958, -5.00989777 48.4139214, -5.00996029 48.41391335, -5.01002285 48.41390544, -5.01008545 48.41389765, -5.01014809 48.41389, -5.01021076 48.41388247, -5.01027347 48.41387508, -5.01033621 48.41386782, -5.01039899 48.41386069, -5.0104618 48.41385369, -5.01052464 48.41384682, -5.01058752 48.41384009, -5.01065042 48.41383348, -5.01071336 48.41382701, -5.01077633 48.41382067, -5.01083932 48.41381446, -5.01090235 48.41380838, -5.0109654 48.41380243, -5.01102848 48.41379662, -5.01109159 48.41379094, -5.01115473 48.41378539, -5.01121789 48.41377997, -5.01128107 48.41377468, -5.01134429 48.41376953, -5.01140752 48.41376451, -5.01147078 48.41375962, -5.01153406 48.41375486, -5.01159736 48.41375023, -5.01166069 48.41374574, -5.01172403 48.41374138, -5.0117874 48.41373715, -5.01185078 48.41373306, -5.01191419 48.41372909, -5.01197761 48.41372526, -5.01204105 48.41372157, -5.01210451 48.413718, -5.01216798 48.41371457, -5.01223147 48.41371127, -5.01229498 48.4137081, -5.0123585 48.41370507, -5.01242203 48.41370217, -5.01248558 48.4136994, -5.01254914 48.41369676, -5.01261271 48.41369426, -5.0126763 48.41369189, -5.01273989 48.41368965, -5.0128035 48.41368755, -5.01286711 48.41368558, -5.01293073 48.41368374, -5.01299437 48.41368204, -5.013058 48.41368047, -5.01312165 48.41367903, -5.0131853 48.41367772, -5.01324896 48.41367655, -5.01331263 48.41367551, -5.0133763 48.41367461, -5.01343997 48.41367383, -5.01350364 48.41367319, -5.01356732 48.41367269, -5.013631 48.41367231, -5.01369469 48.41367207, -5.01375837 48.41367197, -5.01382205 48.41367199, -5.01388573 48.41367215, -5.01394942 48.41367244, -5.0140131 48.41367287, -5.01407677 48.41367343, -5.01414045 48.41367412, -5.01420412 48.41367494, -5.01426779 48.4136759, -5.01433145 48.41367699, -5.01439511 48.41367822, -5.01445876 48.41367957, -5.0145224 48.41368106, -5.01458604 48.41368269, -5.01464966 48.41368444, -5.01471328 48.41368633, -5.0147769 48.41368836, -5.0148405 48.41369051, -5.01490409 48.4136928, -5.01496767 48.41369522, -5.01503123 48.41369778, -5.01509479 48.41370046, -5.01515833 48.41370328, -5.01522186 48.41370624, -5.01528537 48.41370932, -5.01534887 48.41371254, -5.01541236 48.41371589, -5.01547582 48.41371938, -5.01553928 48.41372299, -5.01560271 48.41372674, -5.01566613 48.41373062, -5.01572952 48.41373464, -5.0157929 48.41373879, -5.01585626 48.41374307, -5.0159196 48.41374748, -5.01598291 48.41375202, -5.01604621 48.4137567, -5.01610948 48.41376151, -5.01617273 48.41376645, -5.01623595 48.41377152, -5.01629915 48.41377673, -5.01636233 48.41378207, -5.01642548 48.41378754, -5.01648861 48.41379314, -5.01655171 48.41379887, -5.01661478 48.41380474, -5.01667782 48.41381074, -5.01674083 48.41381687, -5.01680382 48.41382313, -5.01686677 48.41382952, -5.0169297 48.41383605, -5.01699259 48.4138427, -5.01705545 48.41384949, -5.01711828 48.41385641, -5.01718108 48.41386346, -5.01724384 48.41387064, -5.01730657 48.41387795, -5.01736927 48.4138854, -5.01743192 48.41389297, -5.01749455 48.41390068, -5.01755713 48.41390851, -5.01761968 48.41391648, -5.01768219 48.41392458, -5.01774467 48.41393281, -5.0178071 48.41394117, -5.01786949 48.41394966, -5.01793185 48.41395828, -5.01799416 48.41396703, -5.01805643 48.41397591, -5.01811866 48.41398492, -5.01818084 48.41399406, -5.01824298 48.41400333, -5.01830508 48.41401274, -5.01836714 48.41402227, -5.01842914 48.41403193, -5.01849111 48.41404172, -5.01855302 48.41405164, -5.01861489 48.41406169, -5.01867671 48.41407186, -5.01873848 48.41408217, -5.01880021 48.41409261, -5.01886188 48.41410317, -5.01892351 48.41411387, -5.01898508 48.41412469, -5.0190466 48.41413565, -5.01910807 48.41414673, -5.01916949 48.41415794, -5.01923085 48.41416927, -5.01929216 48.41418074, -5.01935342 48.41419233, -5.01941462 48.41420405, -5.01947577 48.4142159, -5.01953686 48.41422788, -5.01959789 48.41423999, -5.01965886 48.41425222, -5.01971978 48.41426458, -5.01978064 48.41427707, -5.01984144 48.41428968, -5.01990218 48.41430242, -5.01996286 48.41431529, -5.02002348 48.41432829, -5.02008403 48.41434141, -5.02014453 48.41435466, -5.02020496 48.41436804, -5.02026533 48.41438154, -5.02032563 48.41439517, -5.02038587 48.41440892, -5.02044604 48.4144228, -5.02050615 48.4144368, -5.0205662 48.41445093, -5.02062617 48.41446519, -5.02068608 48.41447957, -5.02074592 48.41449408, -5.02080569 48.41450871, -5.02086539 48.41452347, -5.02092502 48.41453835, -5.02098458 48.41455336, -5.02104407 48.41456849, -5.02110349 48.41458374, -5.02116284 48.41459912, -5.02122211 48.41461463, -5.02128131 48.41463025, -5.02134044 48.414646, -5.02139949 48.41466188, -5.02145847 48.41467788, -5.02151737 48.414694, -5.02157619 48.41471024, -5.02163494 48.41472661, -5.02169361 48.4147431, -5.0217522 48.41475971, -5.02181071 48.41477644, -5.02186915 48.4147933, -5.0219275 48.41481028, -5.02198577 48.41482738, -5.02204397 48.4148446, -5.02210208 48.41486195, -5.02216011 48.41487941, -5.02221805 48.414897, -5.02227592 48.41491471, -5.0223337 48.41493254, -5.02239139 48.41495049, -5.022449 48.41496856, -5.02250653 48.41498675, -5.02256396 48.41500506, -5.02262132 48.41502349, -5.02267858 48.41504204, -5.02273576 48.41506071, -5.02279285 48.4150795, -5.02284984 48.41509841, -5.02290675 48.41511744, -5.02296357 48.41513659, -5.0230203 48.41515585, -5.02307694 48.41517524, -5.02313349 48.41519474, -5.02318994 48.41521436, -5.0232463 48.4152341, -5.02330257 48.41525395, -5.02335875 48.41527393, -5.02341483 48.41529402, -5.02347081 48.41531423, -5.0235267 48.41533455, -5.02358249 48.41535499, -5.02363819 48.41537555, -5.02369379 48.41539623, -5.02374929 48.41541702, -5.02380469 48.41543793, -5.02385999 48.41545895, -5.0239152 48.41548009, -5.0239703 48.41550134, -5.02402531 48.41552271, -5.02408021 48.41554419, -5.02413501 48.41556579, -5.02418971 48.41558751, -5.02424431 48.41560933, -5.0242988 48.41563127, -5.02435319 48.41565333, -5.02440747 48.4156755, -5.02446165 48.41569778, -5.02451573 48.41572017, -5.0245697 48.41574268, -5.02462356 48.4157653, -5.02467731 48.41578804, -5.02473096 48.41581088, -5.0247845 48.41583384, -5.02483793 48.41585691, -5.02489126 48.41588009, -5.02494447 48.41590338, -5.02499757 48.41592679, -5.02505056 48.4159503, -5.02510344 48.41597393, -5.02515621 48.41599766, -5.02520887 48.41602151, -5.02526141 48.41604547, -5.02531384 48.41606953, -5.02536616 48.41609371, -5.02541836 48.41611799, -5.02547045 48.41614238, -5.02552242 48.41616689, -5.02557428 48.4161915, -5.02562602 48.41621622, -5.02567764 48.41624104, -5.02572915 48.41626598, -5.02578054 48.41629102, -5.02583181 48.41631617, -5.02588296 48.41634143, -5.02593399 48.41636679, -5.0259849 48.41639226, -5.02603569 48.41641784, -5.02608636 48.41644352, -5.02613691 48.41646931, -5.02618734 48.4164952, -5.02623764 48.4165212, -5.02628782 48.41654731, -5.02633788 48.41657352, -5.02638782 48.41659983, -5.02643763 48.41662625, -5.02648731 48.41665277, -5.02653687 48.4166794, -5.02658631 48.41670613, -5.02663561 48.41673296, -5.02668479 48.41675989, -5.02673385 48.41678693, -5.02678277 48.41681407, -5.02683157 48.41684132, -5.02688024 48.41686866, -5.02692878 48.41689611, -5.02697719 48.41692366, -5.02702547 48.4169513, -5.02707362 48.41697905, -5.02712163 48.4170069, -5.02716952 48.41703485, -5.02721727 48.4170629, -5.02726489 48.41709105, -5.02731238 48.4171193, -5.02735974 48.41714765, -5.02740696 48.4171761, -5.02745404 48.41720465, -5.027501 48.41723329, -5.02754781 48.41726203, -5.02759449 48.41729087, -5.02764104 48.41731981, -5.02768744 48.41734885, -5.02773371 48.41737798, -5.02777985 48.41740721, -5.02782584 48.41743653, -5.02787169 48.41746595, -5.02791741 48.41749547, -5.02796299 48.41752508, -5.02800843 48.41755479, -5.02805372 48.41758459, -5.02809888 48.41761449, -5.02814389 48.41764448, -5.02818877 48.41767456, -5.0282335 48.41770474, -5.02827809 48.41773501, -5.02832253 48.41776538, -5.02836683 48.41779583, -5.02841099 48.41782638, -5.028455 48.41785703, -5.02849887 48.41788776, -5.0285426 48.41791859, -5.02858617 48.4179495, -5.02862961 48.41798051, -5.02867289 48.41801161, -5.02871603 48.4180428, -5.02875902 48.41807408, -5.02880186 48.41810545, -5.02884456 48.4181369, -5.02888711 48.41816845, -5.0289295 48.41820009, -5.02897175 48.41823181, -5.02901385 48.41826362, -5.0290558 48.41829552, -5.02909759 48.41832751, -5.02913924 48.41835959, -5.02918073 48.41839175, -5.02922208 48.418424, -5.02926327 48.41845633, -5.0293043 48.41848876, -5.02934519 48.41852126, -5.02938592 48.41855385, -5.02942649 48.41858653, -5.02946692 48.41861929, -5.02950718 48.41865214, -5.0295473 48.41868507, -5.02958725 48.41871808, -5.02962705 48.41875118, -5.0296667 48.41878436, -5.02970619 48.41881762, -5.02974552 48.41885097, -5.02978469 48.4188844, -5.0298237 48.41891791, -5.02986256 48.4189515, -5.02990126 48.41898517, -5.0299398 48.41901892, -5.02997818 48.41905275, -5.0300164 48.41908667, -5.03005446 48.41912066, -5.03009236 48.41915473, -5.0301301 48.41918888, -5.03016767 48.41922311, -5.03020509 48.41925742, -5.03024234 48.41929181, -5.03027943 48.41932627, -5.03031636 48.41936081, -5.03035312 48.41939543, -5.03038972 48.41943013, -5.03042616 48.4194649, -5.03046243 48.41949974, -5.03049854 48.41953467, -5.03053449 48.41956967, -5.03057026 48.41960474, -5.03060588 48.41963989, -5.03064132 48.41967511, -5.0306766 48.41971041, -5.03071172 48.41974578, -5.03074666 48.41978122, -5.03078144 48.41981674, -5.03081605 48.41985233, -5.0308505 48.41988799, -5.03088477 48.41992372, -5.03091888 48.41995952, -5.03095281 48.4199954, -5.03098658 48.42003134, -5.03102018 48.42006736, -5.03105361 48.42010345, -5.03108686 48.4201396, -5.03111995 48.42017583, -5.03115287 48.42021212, -5.03118561 48.42024849, -5.03121818 48.42028492, -5.03125058 48.42032142, -5.03128281 48.42035799, -5.03131486 48.42039462, -5.03134675 48.42043132, -5.03137845 48.42046809, -5.03140999 48.42050492, -5.03144135 48.42054182, -5.03147254 48.42057879, -5.03150355 48.42061582, -5.03153439 48.42065291, -5.03156505 48.42069007, -5.03159553 48.42072729, -5.03162584 48.42076458, -5.03165598 48.42080193, -5.03168594 48.42083934, -5.03171572 48.42087682, -5.03174532 48.42091435, -5.03177475 48.42095195, -5.031804 48.42098961, -5.03183307 48.42102733, -5.03186197 48.42106511, -5.03189068 48.42110295, -5.03191922 48.42114086, -5.03194758 48.42117882, -5.03197575 48.42121684, -5.03200375 48.42125492, -5.03203157 48.42129305, -5.03205921 48.42133125, -5.03208667 48.4213695, -5.03211395 48.42140781, -5.03214105 48.42144618, -5.03216796 48.4214846, -5.0321947 48.42152308, -5.03222125 48.42156162, -5.03224762 48.42160021, -5.03227381 48.42163885, -5.03229981 48.42167755, -5.03232564 48.42171631, -5.03235128 48.42175511, -5.03237673 48.42179398, -5.03240201 48.42183289, -5.0324271 48.42187186, -5.032452 48.42191088, -5.03247672 48.42194995, -5.03250126 48.42198907, -5.03252561 48.42202824, -5.03254978 48.42206747, -5.03257376 48.42210674, -5.03259756 48.42214607, -5.03262117 48.42218544, -5.0326446 48.42222487, -5.03266783 48.42226434, -5.03269089 48.42230386, -5.03271375 48.42234343, -5.03273643 48.42238304, -5.03275892 48.42242271, -5.03278123 48.42246242, -5.03280334 48.42250217, -5.03282527 48.42254198, -5.03284702 48.42258183, -5.03286857 48.42262172, -5.03288993 48.42266166, -5.03291111 48.42270164, -5.0329321 48.42274167, -5.0329529 48.42278174, -5.03297351 48.42282185, -5.03299393 48.42286201, -5.03301416 48.42290221, -5.0330342 48.42294245, -5.03305405 48.42298274, -5.03307371 48.42302306, -5.03309318 48.42306343, -5.03311246 48.42310383, -5.03313155 48.42314428, -5.03315044 48.42318476, -5.03316915 48.42322529, -5.03318766 48.42326585, -5.03320599 48.42330646, -5.03322412 48.4233471, -5.03324206 48.42338777, -5.03325981 48.42342849, -5.03327736 48.42346924, -5.03329473 48.42351003, -5.0333119 48.42355086, -5.03332888 48.42359172, -5.03334566 48.42363261, -5.03336225 48.42367355, -5.03337865 48.42371451, -5.03339486 48.42375551, -5.03341087 48.42379654, -5.03342669 48.42383761, -5.03344231 48.42387871, -5.03345774 48.42391984, -5.03347298 48.42396101, -5.03348802 48.4240022, -5.03350286 48.42404343, -5.03351752 48.42408469, -5.03353197 48.42412598, -5.03354624 48.42416729, -5.0335603 48.42420864, -5.03357418 48.42425002, -5.03358785 48.42429142, -5.03360133 48.42433286, -5.03361462 48.42437432, -5.03362771 48.42441581, -5.0336406 48.42445733, -5.0336533 48.42449887, -5.0336658 48.42454044, -5.03367811 48.42458204, -5.03369022 48.42462366, -5.03370213 48.42466531, -5.03371385 48.42470698, -5.03372537 48.42474867, -5.03373669 48.42479039, -5.03374782 48.42483214, -5.03375875 48.4248739, -5.03376948 48.42491569, -5.03378001 48.4249575, -5.03379035 48.42499933, -5.03380049 48.42504119, -5.03381043 48.42508306, -5.03382017 48.42512496, -5.03382972 48.42516687, -5.03383907 48.42520881, -5.03384822 48.42525077, -5.03385717 48.42529274, -5.03386593 48.42533473, -5.03387448 48.42537674, -5.03388284 48.42541877, -5.033891 48.42546082, -5.03389896 48.42550288, -5.03390672 48.42554496, -5.03391428 48.42558705, -5.03392165 48.42562916, -5.03392882 48.42567129, -5.03393578 48.42571343, -5.03394255 48.42575558, -5.03394912 48.42579775, -5.03395549 48.42583993, -5.03396166 48.42588213, -5.03396763 48.42592434, -5.03397341 48.42596656, -5.03397898 48.42600879, -5.03398435 48.42605103, -5.03398953 48.42609329, -5.0339945 48.42613555, -5.03399928 48.42617783, -5.03400385 48.42622011, -5.03400823 48.42626241, -5.03401241 48.42630471, -5.03401638 48.42634702, -5.03402016 48.42638934, -5.03402374 48.42643167, -5.03402712 48.42647401, -5.03403029 48.42651635, -5.03403327 48.4265587, -5.03403605 48.42660105, -5.03403863 48.42664341, -5.03404101 48.42668577, -5.03404318 48.42672814, -5.03404516 48.42677052, -5.03404694 48.4268129, -5.03404852 48.42685528, -5.0340499 48.42689766, -5.03405107 48.42694005, -5.03405205 48.42698244, -5.03405283 48.42702483, -5.03405341 48.42706722, -5.03405379 48.42710962, -5.03405396 48.42715201, -5.03405394 48.42719441, -5.03405372 48.4272368, -5.03405329 48.4272792, -5.03405267 48.42732159, -5.03405185 48.42736398, -5.03405082 48.42740637, -5.0340496 48.42744876, -5.03404818 48.42749114, -5.03404655 48.42753352, -5.03404473 48.4275759, -5.03404271 48.42761827, -5.03404048 48.42766064, -5.03403806 48.427703, -5.03403544 48.42774536, -5.03403261 48.42778772, -5.03402959 48.42783006, -5.03402637 48.4278724, -5.03402294 48.42791474, -5.03401932 48.42795706, -5.0340155 48.42799938, -5.03401148 48.42804169, -5.03400725 48.42808399, -5.03400283 48.42812628, -5.03399821 48.42816857, -5.03399339 48.42821084, -5.03398837 48.4282531, -5.03398315 48.42829535, -5.03397773 48.4283376, -5.03397211 48.42837982, -5.03396629 48.42842204, -5.03396027 48.42846425, -5.03395406 48.42850644, -5.03394764 48.42854862, -5.03394103 48.42859078, -5.03393421 48.42863294, -5.0339272 48.42867507, -5.03391999 48.42871719, -5.03391258 48.4287593, -5.03390497 48.42880139, -5.03389716 48.42884347, -5.03388915 48.42888552, -5.03388095 48.42892757, -5.03387254 48.42896959, -5.03386394 48.4290116, -5.03385514 48.42905358, -5.03384614 48.42909555, -5.03383695 48.4291375, -5.03382755 48.42917944, -5.03381796 48.42922135, -5.03380817 48.42926324, -5.03379818 48.42930511, -5.033788 48.42934696, -5.03377761 48.42938878, -5.03376703 48.42943059, -5.03375626 48.42947237, -5.03374528 48.42951413, -5.03373411 48.42955587, -5.03372274 48.42959759, -5.03371117 48.42963928, -5.03369941 48.42968094, -5.03368745 48.42972258, -5.0336753 48.4297642, -5.03366294 48.42980579, -5.0336504 48.42984735, -5.03363765 48.42988889, -5.03362471 48.4299304, -5.03361157 48.42997188, -5.03359824 48.43001334, -5.03358471 48.43005477, -5.03357099 48.43009617, -5.03355707 48.43013754, -5.03354296 48.43017888, -5.03352865 48.43022019, -5.03351414 48.43026147, -5.03349944 48.43030272, -5.03348455 48.43034394, -5.03346946 48.43038513, -5.03345418 48.43042628, -5.0334387 48.43046741, -5.03342303 48.4305085, -5.03340717 48.43054956, -5.03339111 48.43059058, -5.03337486 48.43063158, -5.03335841 48.43067253, -5.03334177 48.43071346, -5.03332494 48.43075434, -5.03330791 48.4307952, -5.0332907 48.43083601, -5.03327329 48.43087679, -5.03325568 48.43091754, -5.03323789 48.43095824, -5.0332199 48.43099891, -5.03320172 48.43103954, -5.03318335 48.43108014, -5.03316479 48.43112069, -5.03314603 48.43116121, -5.03312709 48.43120169, -5.03310795 48.43124212, -5.03308862 48.43128252, -5.03306911 48.43132287, -5.0330494 48.43136319, -5.0330295 48.43140346, -5.03300941 48.43144369, -5.03298913 48.43148388, -5.03296866 48.43152403, -5.03294801 48.43156413, -5.03292716 48.43160419, -5.03290612 48.43164421, -5.0328849 48.43168418, -5.03286349 48.43172411, -5.03284189 48.43176399, -5.0328201 48.43180383, -5.03279812 48.43184362, -5.03277595 48.43188337, -5.0327536 48.43192307, -5.03273106 48.43196272, -5.03270833 48.43200232, -5.03268542 48.43204188, -5.03266232 48.43208139, -5.03263903 48.43212085, -5.03261555 48.43216026, -5.03259189 48.43219962, -5.03256805 48.43223894, -5.03254402 48.4322782, -5.0325198 48.43231741, -5.0324954 48.43235657, -5.03247081 48.43239568, -5.03244604 48.43243474, -5.03242109 48.43247375, -5.03239595 48.4325127, -5.03237063 48.4325516, -5.03234512 48.43259045, -5.03231943 48.43262925, -5.03229356 48.43266799, -5.0322675 48.43270667, -5.03224126 48.4327453, -5.03221484 48.43278388, -5.03218824 48.4328224, -5.03216146 48.43286087, -5.03213449 48.43289928, -5.03210735 48.43293763, -5.03208002 48.43297593, -5.03205251 48.43301416, -5.03202482 48.43305235, -5.03199695 48.43309047, -5.0319689 48.43312853, -5.03194067 48.43316654, -5.03191227 48.43320448, -5.03188368 48.43324237, -5.03185491 48.4332802, -5.03182597 48.43331796, -5.03179685 48.43335567, -5.03176755 48.43339331, -5.03173807 48.4334309, -5.03170841 48.43346842, -5.03167858 48.43350588, -5.03164857 48.43354327, -5.03161839 48.43358061, -5.03158802 48.43361788, -5.03155749 48.43365508, -5.03152677 48.43369223, -5.03149589 48.4337293, -5.03146482 48.43376632, -5.03143358 48.43380327, -5.03140217 48.43384015, -5.03137059 48.43387697, -5.03133883 48.43391372, -5.03130689 48.4339504, -5.03127479 48.43398702, -5.03124251 48.43402357, -5.03121006 48.43406005, -5.03117743 48.43409646, -5.03114464 48.43413281, -5.03111167 48.43416909, -5.03107853 48.4342053, -5.03104522 48.43424143, -5.03101175 48.4342775, -5.0309781 48.4343135, -5.03094428 48.43434943, -5.03091029 48.43438529, -5.03087613 48.43442107, -5.0308418 48.43445679, -5.03080731 48.43449243, -5.03077264 48.434528, -5.03073781 48.43456349, -5.03070281 48.43459892, -5.03066765 48.43463427, -5.03063232 48.43466955, -5.03059682 48.43470475, -5.03056115 48.43473988, -5.03052532 48.43477493, -5.03048933 48.43480991, -5.03045316 48.43484482, -5.03041684 48.43487964, -5.03038035 48.4349144, -5.03034369 48.43494907, -5.03030688 48.43498367, -5.0302699 48.43501819, -5.03023275 48.43505263, -5.03019545 48.435087, -5.03015798 48.43512129, -5.03012035 48.4351555, -5.03008256 48.43518963, -5.0300446 48.43522368, -5.03000649 48.43525765, -5.02996822 48.43529154, -5.02992979 48.43532535, -5.02989119 48.43535908, -5.02985244 48.43539273, -5.02981353 48.4354263, -5.02977446 48.43545979, -5.02973524 48.4354932, -5.02969585 48.43552652, -5.02965631 48.43555976, -5.02961661 48.43559292, -5.02957676 48.43562599, -5.02953675 48.43565898, -5.02949658 48.43569189, -5.02945626 48.43572472, -5.02941578 48.43575745, -5.02937515 48.43579011, -5.02933437 48.43582268, -5.02929343 48.43585516, -5.02925234 48.43588756, -5.02921109 48.43591987, -5.0291697 48.4359521, -5.02912815 48.43598423, -5.02908645 48.43601629, -5.0290446 48.43604825, -5.02900259 48.43608013, -5.02896044 48.43611192, -5.02891814 48.43614362, -5.02887569 48.43617523, -5.02883309 48.43620675, -5.02879034 48.43623818, -5.02874744 48.43626953, -5.02870439 48.43630078, -5.0286612 48.43633195, -5.02861786 48.43636302, -5.02857437 48.436394, -5.02853074 48.4364249, -5.02848696 48.4364557, -5.02844304 48.4364864, -5.02839897 48.43651702, -5.02835476 48.43654755, -5.0283104 48.43657798, -5.0282659 48.43660832, -5.02822126 48.43663856, -5.02817647 48.43666871, -5.02813154 48.43669877, -5.02808647 48.43672874, -5.02804126 48.43675861, -5.02799591 48.43678838, -5.02795041 48.43681806, -5.02790478 48.43684765, -5.02785901 48.43687714, -5.0278131 48.43690653, -5.02776705 48.43693583, -5.02772086 48.43696503, -5.02767454 48.43699413, -5.02762807 48.43702314, -5.02758147 48.43705205, -5.02753474 48.43708086, -5.02748787 48.43710958, -5.02744086 48.4371382, -5.02739372 48.43716671, -5.02734644 48.43719513, -5.02729903 48.43722345, -5.02725149 48.43725167, -5.02720381 48.4372798, -5.027156 48.43730782, -5.02710806 48.43733574, -5.02705998 48.43736356, -5.02701178 48.43739128, -5.02696344 48.4374189, -5.02691498 48.43744642, -5.02686638 48.43747384, -5.02681766 48.43750115, -5.02676881 48.43752836, -5.02671983 48.43755548, -5.02667072 48.43758248, -5.02662148 48.43760939, -5.02657212 48.43763619, -5.02652263 48.43766289, -5.02647301 48.43768949, -5.02642327 48.43771598, -5.0263734 48.43774237, -5.02632341 48.43776865, -5.0262733 48.43779483, -5.02622306 48.4378209, -5.0261727 48.43784687, -5.02612222 48.43787273, -5.02607161 48.43789849, -5.02602089 48.43792414, -5.02597004 48.43794969, -5.02591907 48.43797513, -5.02586798 48.43800046, -5.02581678 48.43802568, -5.02576545 48.4380508, -5.02571401 48.43807581, -5.02566245 48.43810072, -5.02561077 48.43812551, -5.02555897 48.4381502, -5.02550706 48.43817478, -5.02545503 48.43819924, -5.02540289 48.43822361, -5.02535063 48.43824786, -5.02529825 48.438272, -5.02524577 48.43829603, -5.02519317 48.43831995, -5.02514045 48.43834377, -5.02508763 48.43836747, -5.02503469 48.43839106, -5.02498165 48.43841454, -5.02492849 48.43843791, -5.02487522 48.43846117, -5.02482184 48.43848432, -5.02476835 48.43850735, -5.02471476 48.43853028, -5.02466105 48.43855309, -5.02460724 48.43857579, -5.02455332 48.43859837, -5.0244993 48.43862085, -5.02444517 48.43864321, -5.02439093 48.43866546, -5.02433659 48.43868759, -5.02428215 48.43870961, -5.0242276 48.43873151, -5.02417295 48.43875331, -5.02411819 48.43877498, -5.02406334 48.43879655, -5.02400838 48.43881799, -5.02395332 48.43883933, -5.02389816 48.43886055, -5.0238429 48.43888165, -5.02378754 48.43890263, -5.02373208 48.43892351, -5.02367653 48.43894426, -5.02362087 48.4389649, -5.02356512 48.43898542, -5.02350927 48.43900583, -5.02345333 48.43902611, -5.02339729 48.43904629, -5.02334115 48.43906634, -5.02328493 48.43908628, -5.0232286 48.4391061, -5.02317219 48.4391258, -5.02311568 48.43914538, -5.02305908 48.43916485, -5.02300238 48.43918419, -5.0229456 48.43920342, -5.02288872 48.43922253, -5.02283176 48.43924152, -5.02277471 48.43926039, -5.02271756 48.43927914, -5.02266033 48.43929777, -5.02260301 48.43931628, -5.02254561 48.43933468, -5.02248811 48.43935295, -5.02243054 48.4393711, -5.02237287 48.43938913, -5.02231512 48.43940704, -5.02225729 48.43942483, -5.02219937 48.4394425, -5.02214137 48.43946005, -5.02208329 48.43947747, -5.02202512 48.43949478, -5.02196688 48.43951196, -5.02190855 48.43952902, -5.02185014 48.43954596, -5.02179166 48.43956278, -5.02173309 48.43957947, -5.02167444 48.43959605, -5.02161572 48.4396125, -5.02155692 48.43962882, -5.02149804 48.43964502, -5.02143909 48.43966111, -5.02138006 48.43967706, -5.02132096 48.4396929, -5.02126178 48.4397086, -5.02120253 48.43972419, -5.0211432 48.43973965, -5.0210838 48.43975499, -5.02102433 48.4397702, -5.02096479 48.43978529, -5.02090517 48.43980026, -5.02084549 48.4398151, -5.02078574 48.43982981, -5.02072591 48.4398444, -5.02066602 48.43985887, -5.02060606 48.43987321, -5.02054604 48.43988742, -5.02048594 48.43990151, -5.02042578 48.43991547, -5.02036556 48.43992931, -5.02030527 48.43994302, -5.02024491 48.43995661, -5.02018449 48.43997006, -5.02012401 48.4399834, -5.02006346 48.4399966, -5.02000286 48.44000968, -5.01994219 48.44002263, -5.01988146 48.44003546, -5.01982067 48.44004816, -5.01975982 48.44006073, -5.01969891 48.44007317, -5.01963794 48.44008549, -5.01957692 48.44009768, -5.01951584 48.44010974, -5.0194547 48.44012167, -5.0193935 48.44013348, -5.01933225 48.44014515, -5.01927095 48.4401567, -5.01920959 48.44016812, -5.01914817 48.44017942, -5.01908671 48.44019058, -5.01902519 48.44020162, -5.01896362 48.44021253, -5.018902 48.4402233, -5.01884032 48.44023395, -5.0187786 48.44024447, -5.01871683 48.44025486, -5.01865501 48.44026513, -5.01859314 48.44027526, -5.01853122 48.44028526, -5.01846926 48.44029514, -5.01840725 48.44030488, -5.0183452 48.4403145, -5.0182831 48.44032398, -5.01822095 48.44033334, -5.01815876 48.44034256, -5.01809653 48.44035166, -5.01803426 48.44036062, -5.01797194 48.44036945, -5.01790958 48.44037816, -5.01784718 48.44038673, -5.01778474 48.44039518, -5.01772226 48.44040349, -5.01765975 48.44041167, -5.01759719 48.44041972, -5.0175346 48.44042764, -5.01747197 48.44043543, -5.0174093 48.44044309, -5.0173466 48.44045062, -5.01728386 48.44045801, -5.01722108 48.44046528, -5.01715828 48.44047241, -5.01709544 48.44047941, -5.01703256 48.44048629, -5.01696966 48.44049302, -5.01690672 48.44049963, -5.01684375 48.44050611, -5.01678075 48.44051245, -5.01671773 48.44051867, -5.01665467 48.44052475, -5.01659158 48.4405307, -5.01652847 48.44053651, -5.01646533 48.4405422, -5.01640216 48.44054775, -5.01633897 48.44055317, -5.01627575 48.44055846, -5.01621251 48.44056362, -5.01614924 48.44056864, -5.01608595 48.44057354, -5.01602264 48.4405783, -5.01595931 48.44058292, -5.01589595 48.44058742, -5.01583257 48.44059178, -5.01576917 48.44059601, -5.01570576 48.44060011, -5.01564232 48.44060407, -5.01557886 48.4406079, -5.01551539 48.4406116, -5.0154519 48.44061517, -5.0153884 48.4406186, -5.01532487 48.44062191, -5.01526134 48.44062507, -5.01519778 48.44062811, -5.01513422 48.44063101, -5.01507064 48.44063378, -5.01500704 48.44063642, -5.01494344 48.44063892, -5.01487982 48.44064129, -5.0148162 48.44064353, -5.01475256 48.44064564, -5.01468891 48.44064761, -5.01462526 48.44064945, -5.01456159 48.44065115, -5.01449792 48.44065272, -5.01443424 48.44065416, -5.01437056 48.44065547, -5.01430686 48.44065664, -5.01424317 48.44065768, -5.01417947 48.44065859, -5.01411576 48.44065936, -5.01405205 48.44066, -5.01398834 48.44066051, -5.01392463 48.44066088, -5.01386091 48.44066112, -5.0137972 48.44066123, -5.01373348 48.4406612, -5.01366977 48.44066104, -5.01360605 48.44066075, -5.01354234 48.44066033, -5.01347863 48.44065977, -5.01341492 48.44065907, -5.01335122 48.44065825, -5.01328752 48.44065729, -5.01322382 48.4406562, -5.01316013 48.44065497, -5.01309645 48.44065362, -5.01303277 48.44065212, -5.0129691 48.4406505, -5.01290544 48.44064874, -5.01284179 48.44064685, -5.01277815 48.44064483, -5.01271451 48.44064267, -5.01265089 48.44064038, -5.01258728 48.44063796, -5.01252368 48.4406354, -5.01246009 48.44063272, -5.01239652 48.44062989, -5.01233296 48.44062694, -5.01226941 48.44062385, -5.01220588 48.44062063, -5.01214236 48.44061728, -5.01207886 48.44061379, -5.01201538 48.44061018, -5.01195191 48.44060642, -5.01188846 48.44060254, -5.01182504 48.44059852, -5.01176163 48.44059437, -5.01169824 48.44059009, -5.01163487 48.44058568, -5.01157152 48.44058113, -5.01150819 48.44057645, -5.01144489 48.44057164, -5.01138161 48.4405667, -5.01131835 48.44056162, -5.01125512 48.44055641, -5.01119191 48.44055107, -5.01112872 48.4405456, -5.01106557 48.44053999, -5.01100244 48.44053426, -5.01093934 48.44052839, -5.01087626 48.44052239, -5.01081322 48.44051626, -5.0107502 48.44050999, -5.01068721 48.4405036, -5.01062426 48.44049707, -5.01056133 48.44049041, -5.01049844 48.44048362, -5.01043558 48.4404767, -5.01037275 48.44046964, -5.01030996 48.44046246, -5.0102472 48.44045514, -5.01018447 48.44044769, -5.01012178 48.44044011, -5.01005913 48.44043241, -5.00999651 48.44042456, -5.00993394 48.44041659, -5.00987139 48.44040849, -5.00980889 48.44040026, -5.00974643 48.44039189, -5.00968401 48.4403834, -5.00962162 48.44037478, -5.00955928 48.44036602, -5.00949698 48.44035714, -5.00943472 48.44034812, -5.00937251 48.44033897, -5.00931033 48.4403297, -5.00924821 48.44032029, -5.00918612 48.44031076, -5.00912409 48.44030109, -5.00906209 48.4402913, -5.00900015 48.44028137, -5.00893825 48.44027132, -5.0088764 48.44026114, -5.0088146 48.44025082, -5.00875285 48.44024038, -5.00869115 48.44022981, -5.00862949 48.44021911, -5.00856789 48.44020828, -5.00850634 48.44019732, -5.00844484 48.44018624, -5.0083834 48.44017502, -5.008322 48.44016368, -5.00826067 48.44015221, -5.00819938 48.44014061, -5.00813815 48.44012888, -5.00807698 48.44011703, -5.00801586 48.44010504, -5.0079548 48.44009293, -5.0078938 48.44008069, -5.00783286 48.44006833, -5.00777197 48.44005583, -5.00771114 48.44004321, -5.00765038 48.44003047, -5.00758967 48.44001759, -5.00752903 48.44000459, -5.00746844 48.43999146, -5.00740792 48.43997821, -5.00734747 48.43996482, -5.00728707 48.43995132, -5.00722674 48.43993768, -5.00716648 48.43992392, -5.00710628 48.43991004, -5.00704614 48.43989602, -5.00698607 48.43988189, -5.00692607 48.43986762, -5.00686614 48.43985323, -5.00680628 48.43983872, -5.00674648 48.43982408, -5.00668675 48.43980932, -5.0066271 48.43979443, -5.00656751 48.43977942, -5.006508 48.43976428, -5.00644855 48.43974902, -5.00638918 48.43973363, -5.00632989 48.43971812, -5.00627066 48.43970249, -5.00621151 48.43968673, -5.00615244 48.43967085, -5.00609344 48.43965484, -5.00603451 48.43963871, -5.00597567 48.43962246, -5.0059169 48.43960609, -5.0058582 48.43958959, -5.00579959 48.43957297, -5.00574105 48.43955623, -5.0056826 48.43953936, -5.00562422 48.43952238, -5.00556593 48.43950527, -5.00550771 48.43948804, -5.00544958 48.43947068, -5.00539153 48.43945321, -5.00533356 48.43943562, -5.00527568 48.4394179, -5.00521787 48.43940006, -5.00516016 48.43938211, -5.00510253 48.43936403, -5.00504498 48.43934583, -5.00498752 48.43932751, -5.00493015 48.43930907, -5.00487287 48.43929051, -5.00481567 48.43927183, -5.00475856 48.43925304, -5.00470154 48.43923412, -5.00464461 48.43921508, -5.00458777 48.43919593, -5.00453103 48.43917665, -5.00447437 48.43915726, -5.0044178 48.43913775, -5.00436133 48.43911812, -5.00430495 48.43909837, -5.00424866 48.43907851, -5.00419247 48.43905852, -5.00413637 48.43903842, -5.00408037 48.43901821, -5.00402447 48.43899787, -5.00396866 48.43897742, -5.00391294 48.43895685, -5.00385733 48.43893617, -5.00380181 48.43891537, -5.00374639 48.43889445, -5.00369107 48.43887342, -5.00363585 48.43885227, -5.00358073 48.43883101, -5.00352571 48.43880963, -5.00347079 48.43878814, -5.00341597 48.43876653, -5.00336126 48.43874481, -5.00330665 48.43872297, -5.00325214 48.43870102, -5.00319773 48.43867896, -5.00314343 48.43865678, -5.00308924 48.43863449, -5.00303515 48.43861209, -5.00298117 48.43858957, -5.00292729 48.43856694, -5.00287352 48.4385442, -5.00281986 48.43852134, -5.00276631 48.43849837, -5.00271286 48.43847529, -5.00265953 48.4384521, -5.0026063 48.4384288, -5.00255318 48.43840539, -5.00250018 48.43838186, -5.00244729 48.43835823, -5.00239451 48.43833448, -5.00234184 48.43831063, -5.00228928 48.43828666, -5.00223684 48.43826259, -5.00218451 48.4382384, -5.0021323 48.43821411, -5.0020802 48.4381897, -5.00202822 48.43816519, -5.00197635 48.43814057, -5.0019246 48.43811584, -5.00187296 48.438091, -5.00182145 48.43806606, -5.00177005 48.43804101, -5.00171877 48.43801585, -5.00166761 48.43799058, -5.00161657 48.43796521, -5.00156565 48.43793973, -5.00151485 48.43791414, -5.00146417 48.43788845, -5.00141361 48.43786265, -5.00136318 48.43783674, -5.00131286 48.43781073, -5.00126267 48.43778462, -5.00121261 48.4377584, -5.00116267 48.43773208, -5.00111285 48.43770565, -5.00106316 48.43767912, -5.00101359 48.43765248, -5.00096415 48.43762574, -5.00091484 48.4375989, -5.00086565 48.43757195, -5.00081659 48.4375449, -5.00076766 48.43751775, -5.00071886 48.4374905, -5.00067018 48.43746314, -5.00062164 48.43743569, -5.00057322 48.43740813, -5.00052494 48.43738047, -5.00047678 48.43735271, -5.00042876 48.43732485, -5.00038087 48.43729689, -5.00033311 48.43726883, -5.00028549 48.43724067, -5.000238 48.43721241, -5.00019064 48.43718405, -5.00014342 48.43715559, -5.00009633 48.43712703, -5.00004937 48.43709838, -5.00000255 48.43706963, -4.99995587 48.43704078, -4.99990932 48.43701183, -4.99986292 48.43698278, -4.99981664 48.43695364, -4.99977051 48.4369244, -4.99972451 48.43689507, -4.99967866 48.43686563, -4.99963294 48.43683611, -4.99958736 48.43680649, -4.99954192 48.43677677, -4.99949663 48.43674696, -4.99945147 48.43671705, -4.99940646 48.43668705, -4.99936158 48.43665695, -4.99931685 48.43662676, -4.99927226 48.43659648, -4.99922782 48.43656611, -4.99918352 48.43653564, -4.99913936 48.43650508, -4.99909535 48.43647443, -4.99905148 48.43644368, -4.99900776 48.43641284, -4.99896419 48.43638192, -4.99892076 48.4363509, -4.99887747 48.43631979, -4.99883434 48.43628859, -4.99879135 48.4362573, -4.99874851 48.43622592, -4.99870582 48.43619445, -4.99866328 48.4361629, -4.99862088 48.43613125, -4.99857864 48.43609951, -4.99853654 48.43606769, -4.9984946 48.43603578, -4.99845281 48.43600378, -4.99841117 48.4359717, -4.99836968 48.43593952, -4.99832834 48.43590726, -4.99828716 48.43587492, -4.99824612 48.43584249, -4.99820525 48.43580997, -4.99816452 48.43577737, -4.99812395 48.43574468, -4.99808353 48.43571191, -4.99804327 48.43567905, -4.99800317 48.43564611, -4.99796322 48.43561309, -4.99792343 48.43557998, -4.99788379 48.43554679, -4.99784431 48.43551352, -4.99780499 48.43548016, -4.99776582 48.43544672, -4.99772681 48.43541321, -4.99768796 48.4353796, -4.99764928 48.43534592, -4.99761075 48.43531216, -4.99757237 48.43527832, -4.99753416 48.43524439, -4.99749611 48.43521039, -4.99745822 48.43517631, -4.9974205 48.43514215, -4.99738293 48.43510791, -4.99734552 48.43507359, -4.99730828 48.43503919, -4.9972712 48.43500472, -4.99723428 48.43497017, -4.99719753 48.43493554, -4.99716094 48.43490084, -4.99712451 48.43486605, -4.99708825 48.4348312, -4.99705216 48.43479626, -4.99701622 48.43476126, -4.99698046 48.43472617, -4.99694486 48.43469101, -4.99690942 48.43465578, -4.99687416 48.43462048, -4.99683906 48.4345851, -4.99680412 48.43454964, -4.99676936 48.43451412, -4.99673476 48.43447852, -4.99670033 48.43444285, -4.99666607 48.43440711, -4.99663198 48.43437129, -4.99659805 48.43433541, -4.9965643 48.43429945, -4.99653072 48.43426343, -4.99649731 48.43422733, -4.99646406 48.43419117, -4.99643099 48.43415493, -4.99639809 48.43411863, -4.99636536 48.43408225, -4.99633281 48.43404581, -4.99630042 48.43400931, -4.99626821 48.43397273, -4.99623617 48.43393609, -4.99620431 48.43389938, -4.99617262 48.4338626, -4.9961411 48.43382576, -4.99610975 48.43378885, -4.99607858 48.43375187, -4.99604759 48.43371484, -4.99601677 48.43367773, -4.99598612 48.43364056, -4.99595566 48.43360333, -4.99592536 48.43356604, -4.99589525 48.43352868, -4.99586531 48.43349126, -4.99583554 48.43345378, -4.99580596 48.43341623, -4.99577655 48.43337862, -4.99574732 48.43334095, -4.99571826 48.43330322, -4.99568939 48.43326544, -4.99566069 48.43322758, -4.99563218 48.43318967, -4.99560384 48.43315171, -4.99557568 48.43311368, -4.9955477 48.43307559, -4.9955199 48.43303744, -4.99549228 48.43299924, -4.99546485 48.43296098, -4.99543759 48.43292266, -4.99541051 48.43288429, -4.99538362 48.43284586, -4.99535691 48.43280737, -4.99533037 48.43276883, -4.99530402 48.43273023, -4.99527786 48.43269157, -4.99525187 48.43265287, -4.99522607 48.4326141, -4.99520045 48.43257529, -4.99517502 48.43253642, -4.99514977 48.4324975, -4.9951247 48.43245852, -4.99509982 48.4324195, -4.99507512 48.43238042, -4.99505061 48.43234129, -4.99502628 48.43230211, -4.99500213 48.43226287, -4.99497817 48.43222359, -4.9949544 48.43218426, -4.99493081 48.43214488, -4.99490741 48.43210545, -4.9948842 48.43206597, -4.99486117 48.43202644, -4.99483833 48.43198687, -4.99481567 48.43194724, -4.99479321 48.43190757, -4.99477093 48.43186785, -4.99474883 48.43182809, -4.99472693 48.43178828, -4.99470521 48.43174843, -4.99468369 48.43170853, -4.99466235 48.43166858, -4.99464119 48.43162859, -4.99462023 48.43158856, -4.99459946 48.43154848, -4.99457888 48.43150836, -4.99455848 48.4314682, -4.99453828 48.43142799, -4.99451826 48.43138774, -4.99449844 48.43134745, -4.99447881 48.43130712, -4.99445936 48.43126675, -4.99444011 48.43122634, -4.99442105 48.43118589, -4.99440218 48.43114539, -4.9943835 48.43110486, -4.99436501 48.43106429, -4.99434671 48.43102368, -4.99432861 48.43098304, -4.9943107 48.43094235, -4.99429298 48.43090163, -4.99427545 48.43086087, -4.99425811 48.43082008, -4.99424097 48.43077925, -4.99422402 48.43073838, -4.99420726 48.43069748, -4.9941907 48.43065655, -4.99417433 48.43061557, -4.99415815 48.43057457, -4.99414217 48.43053353, -4.99412638 48.43049246, -4.99411079 48.43045135, -4.99409539 48.43041022, -4.99408018 48.43036905, -4.99406517 48.43032785, -4.99405035 48.43028662, -4.99403573 48.43024535, -4.9940213 48.43020406, -4.99400706 48.43016274, -4.99399303 48.43012139, -4.99397918 48.43008, -4.99396554 48.43003859, -4.99395208 48.42999716, -4.99393883 48.42995569, -4.99392577 48.4299142, -4.9939129 48.42987267, -4.99390024 48.42983113, -4.99388776 48.42978955, -4.99387549 48.42974795, -4.99386341 48.42970633, -4.99385153 48.42966468, -4.99383984 48.429623, -4.99382835 48.4295813, -4.99381706 48.42953958, -4.99380597 48.42949783, -4.99379507 48.42945606, -4.99378437 48.42941427, -4.99377386 48.42937246, -4.99376356 48.42933062, -4.99375345 48.42928876, -4.99374354 48.42924688, -4.99373383 48.42920499, -4.99372431 48.42916307, -4.99371499 48.42912113, -4.99370587 48.42907917, -4.99369695 48.42903719, -4.99368823 48.4289952, -4.99367971 48.42895318, -4.99367138 48.42891115, -4.99366325 48.42886911, -4.99365532 48.42882704, -4.99364759 48.42878496, -4.99364006 48.42874286, -4.99363273 48.42870075, -4.99362559 48.42865862, -4.99361866 48.42861648, -4.99361192 48.42857432, -4.99360539 48.42853215)))" - val polygon = wktReader.read(multipolygonString) as MultiPolygon val firstMission = MissionDTO( mission = @@ -405,15 +406,6 @@ class JpaMissionRepositoryITests : AbstractDBTests() { assertThat(existingMissions).hasSize(21) - val wktReader = WKTReader() - - val multipolygonString = - "MULTIPOLYGON(((-2.7335 47.6078, -2.7335 47.8452, -3.6297 47.8452, -3.6297 47.6078, -2.7335 47.6078)))" - val polygon = wktReader.read(multipolygonString) as MultiPolygon - - val multipointString = "MULTIPOINT((49.354105 -0.427455))" - val point = wktReader.read(multipointString) as MultiPoint - val noteObservations = "Quelqu'un aurait vu quelque chose quelque part à un certain moment." val newMission = @@ -433,12 +425,11 @@ class JpaMissionRepositoryITests : AbstractDBTests() { "33310163-4e22-4d3d-b585-dac4431eb4b5", ), facade = "Facade 1", - controlPlanSubThemes = listOf( - EnvActionControlPlanSubThemeEntity( - subThemeId = 1, - subTheme = "Sub theme 1", - theme = "Theme 1", - tags = listOf("Tag 1", "Tag 2"), + controlPlans = listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(1), + tagIds = listOf(1, 2), + themeId = 1, ), ), department = "Department 1", @@ -738,10 +729,6 @@ class JpaMissionRepositoryITests : AbstractDBTests() { @Transactional fun `save Should update mission`() { // Given - val wktReader = WKTReader() - val multipolygonString = - "MULTIPOLYGON (((-4.54877816747593 48.305559876971, -4.54997332394943 48.3059760121399, -4.54998501370013 48.3071882334181, -4.54879290083417 48.3067746138142, -4.54877816747593 48.305559876971)))" - val polygon = wktReader.read(multipolygonString) as MultiPolygon val infraction = InfractionEntity( id = UUID.randomUUID().toString(), @@ -836,10 +823,6 @@ class JpaMissionRepositoryITests : AbstractDBTests() { @Transactional fun `save Should update mission with associated envActions`() { // Given - val wktReader = WKTReader() - val multipolygonString = - "MULTIPOLYGON (((-4.54877816747593 48.305559876971, -4.54997332394943 48.3059760121399, -4.54998501370013 48.3071882334181, -4.54879290083417 48.3067746138142, -4.54877816747593 48.305559876971)))" - val polygon = wktReader.read(multipolygonString) as MultiPolygon val envAction = EnvActionControlEntity( @@ -900,35 +883,38 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save Should update subThemes of envActions`() { val mission = jpaMissionRepository.findById(34) val envAction = mission.envActions?.find { it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") } - assertThat(envAction?.controlPlanSubThemes?.size).isEqualTo(2) - val nextControlPlanSubThemes = listOf( - EnvActionControlPlanSubThemeEntity( - subThemeId = 7, - tags = listOf("Flore", "Oiseaux"), + assertThat(envAction?.controlPlans?.size).isEqualTo(1) + assertThat(envAction?.controlPlans?.get(0)?.subThemeIds?.size).isEqualTo(2) + val nextControlPlans = listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(53, 34), + themeId = 2, + ), + EnvActionControlPlanEntity( + tagIds = listOf(1, 2, 3), + themeId = 11, + ), + EnvActionControlPlanEntity( + themeId = 17, ), ) val nextMission = mission.copy( envActions = mission.envActions?.map { if (it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") && it is EnvActionControlEntity) { - it.copy( - controlPlanSubThemes = nextControlPlanSubThemes, - ) + it.copy(controlPlans = nextControlPlans) } else { it } }, ) val updatedMission = jpaMissionRepository.save(nextMission) - val updatedControlPlanSubThemes = updatedMission.mission.envActions?.find { - it.id == UUID.fromString( - "b8007c8a-5135-4bc3-816f-c69c7b75d807", - ) - }?.controlPlanSubThemes - assertThat( - updatedControlPlanSubThemes?.size, - ).isEqualTo(1) - assertThat( - updatedControlPlanSubThemes?.first()?.subThemeId, - ).isEqualTo(7) + val updatedControlPlan = updatedMission.mission.envActions?.find { + it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") + }?.controlPlans + assertThat(updatedControlPlan?.size).isEqualTo(3) + assertThat(updatedControlPlan?.get(0)?.subThemeIds?.size).isEqualTo(2) + assertThat(updatedControlPlan?.get(0)?.subThemeIds?.get(0)).isEqualTo(53) + assertThat(updatedControlPlan?.get(1)?.tagIds?.size).isEqualTo(3) + assertThat(updatedControlPlan?.get(1)?.tagIds?.get(0)).isEqualTo(1) } } From 811ba8ae96dcfc15007cc1e15b91ead39b904e7e Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:51 +0100 Subject: [PATCH 16/53] backend for reportings controlPlans --- .../entities/reporting/ReportingEntity.kt | 4 +- .../CreateOrUpdateReportingDataInput.kt | 8 +- .../outputs/AttachedReportingDataOutput.kt | 8 +- .../bff/outputs/ReportingDataOutput.kt | 8 +- .../bff/outputs/ReportingsDataOutput.kt | 8 +- .../MissionAttachedReportingDataOutput.kt | 8 +- .../EnvActionsControlPlanSubThemeModel.kt | 4 +- .../database/model/ReportingModel.kt | 147 ++++++++++----- .../ReportingsControlPlanSubThemeModel.kt | 73 +++++++ .../repositories/JpaMissionRepository.kt | 2 +- .../repositories/JpaReportingRepository.kt | 33 +++- .../internal/V0.103__create_action_theme.sql | 15 +- .../V666.12__insert_dummy_reportings.sql | 178 ++---------------- .../CreateOrUpdateReportingUTests.kt | 44 ++--- .../controlUnit/CanDeleteControlUnitUTests.kt | 4 +- .../domain/use_cases/missions/TestUtils.kt | 8 +- .../endpoints/bff/MissionsControllerITests.kt | 8 +- .../bff/ReportingsControllerITests.kt | 46 +++-- .../JpaReportingRepositoryITests.kt.kt | 8 +- 19 files changed, 306 insertions(+), 308 deletions(-) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ReportingsControlPlanSubThemeModel.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/reporting/ReportingEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/reporting/ReportingEntity.kt index ecb7bb2ef..0ca672346 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/reporting/ReportingEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/reporting/ReportingEntity.kt @@ -19,8 +19,8 @@ data class ReportingEntity( val seaFront: String? = null, val description: String? = null, val reportType: ReportingTypeEnum? = null, - val theme: String? = null, - val subThemes: List? = listOf(), + val themeId: Int? = null, + val subThemeIds: List? = emptyList(), val actionTaken: String? = null, val isControlRequired: Boolean? = null, val hasNoUnitAvailable: Boolean? = null, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/CreateOrUpdateReportingDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/CreateOrUpdateReportingDataInput.kt index 89be994ec..2b7473089 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/CreateOrUpdateReportingDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/CreateOrUpdateReportingDataInput.kt @@ -23,8 +23,8 @@ data class CreateOrUpdateReportingDataInput( val geom: Geometry? = null, val description: String? = null, val reportType: ReportingTypeEnum? = null, - val theme: String? = null, - val subThemes: List? = listOf(), + val themeId: Int? = null, + val subThemeIds: List? = emptyList(), val actionTaken: String? = null, val isControlRequired: Boolean? = null, val hasNoUnitAvailable: Boolean? = null, @@ -51,8 +51,8 @@ data class CreateOrUpdateReportingDataInput( geom = this.geom, description = this.description, reportType = this.reportType, - theme = this.theme, - subThemes = this.subThemes, + themeId = this.themeId, + subThemeIds = this.subThemeIds, actionTaken = this.actionTaken, isControlRequired = this.isControlRequired, hasNoUnitAvailable = this.hasNoUnitAvailable, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/AttachedReportingDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/AttachedReportingDataOutput.kt index 4e8ac379f..b2e7c177f 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/AttachedReportingDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/AttachedReportingDataOutput.kt @@ -27,8 +27,8 @@ data class AttachedReportingDataOutput( val seaFront: String? = null, val description: String? = null, val reportType: ReportingTypeEnum? = null, - val theme: String? = null, - val subThemes: List? = listOf(), + val themeId: Int? = null, + val subThemeIds: List? = emptyList(), val actionTaken: String? = null, val isControlRequired: Boolean? = null, val hasNoUnitAvailable: Boolean? = null, @@ -76,8 +76,8 @@ data class AttachedReportingDataOutput( seaFront = dto.reporting.seaFront, description = dto.reporting.description, reportType = dto.reporting.reportType, - theme = dto.reporting.theme, - subThemes = dto.reporting.subThemes, + themeId = dto.reporting.themeId, + subThemeIds = dto.reporting.subThemeIds, actionTaken = dto.reporting.actionTaken, isControlRequired = dto.reporting.isControlRequired, hasNoUnitAvailable = dto.reporting.hasNoUnitAvailable, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ReportingDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ReportingDataOutput.kt index 36a88ce45..2805d5587 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ReportingDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ReportingDataOutput.kt @@ -29,8 +29,8 @@ data class ReportingDataOutput( val seaFront: String? = null, val description: String? = null, val reportType: ReportingTypeEnum? = null, - val theme: String? = null, - val subThemes: List? = listOf(), + val themeId: Int? = null, + val subThemeIds: List? = emptyList(), val actionTaken: String? = null, val isControlRequired: Boolean? = null, val hasNoUnitAvailable: Boolean? = null, @@ -91,8 +91,8 @@ data class ReportingDataOutput( seaFront = dto.reporting.seaFront, description = dto.reporting.description, reportType = dto.reporting.reportType, - theme = dto.reporting.theme, - subThemes = dto.reporting.subThemes, + themeId = dto.reporting.themeId, + subThemeIds = dto.reporting.subThemeIds, actionTaken = dto.reporting.actionTaken, isControlRequired = dto.reporting.isControlRequired, hasNoUnitAvailable = dto.reporting.hasNoUnitAvailable, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ReportingsDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ReportingsDataOutput.kt index c936fe6ee..401aba82e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ReportingsDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ReportingsDataOutput.kt @@ -26,8 +26,8 @@ data class ReportingsDataOutput( val seaFront: String? = null, val description: String? = null, val reportType: ReportingTypeEnum? = null, - val theme: String? = null, - val subThemes: List? = listOf(), + val themeId: Int? = null, + val subThemeIds: List? = emptyList(), val actionTaken: String? = null, val isControlRequired: Boolean? = null, val hasNoUnitAvailable: Boolean? = null, @@ -68,8 +68,8 @@ data class ReportingsDataOutput( seaFront = dto.reporting.seaFront, description = dto.reporting.description, reportType = dto.reporting.reportType, - theme = dto.reporting.theme, - subThemes = dto.reporting.subThemes, + themeId = dto.reporting.themeId, + subThemeIds = dto.reporting.subThemeIds, actionTaken = dto.reporting.actionTaken, isControlRequired = dto.reporting.isControlRequired, hasNoUnitAvailable = dto.reporting.hasNoUnitAvailable, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionAttachedReportingDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionAttachedReportingDataOutput.kt index 93acf82c5..5adb514c4 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionAttachedReportingDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionAttachedReportingDataOutput.kt @@ -29,8 +29,8 @@ data class MissionAttachedReportingDataOutput( val seaFront: String? = null, val description: String? = null, val reportType: ReportingTypeEnum? = null, - val theme: String? = null, - val subThemes: List? = listOf(), + val themeId: Int? = null, + val subThemeIds: List? = emptyList(), val actionTaken: String? = null, val isControlRequired: Boolean? = null, val hasNoUnitAvailable: Boolean? = null, @@ -89,8 +89,8 @@ data class MissionAttachedReportingDataOutput( seaFront = dto.reporting.seaFront, description = dto.reporting.description, reportType = dto.reporting.reportType, - theme = dto.reporting.theme, - subThemes = dto.reporting.subThemes, + themeId = dto.reporting.themeId, + subThemeIds = dto.reporting.subThemeIds, actionTaken = dto.reporting.actionTaken, isControlRequired = dto.reporting.isControlRequired, hasNoUnitAvailable = dto.reporting.hasNoUnitAvailable, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt index b4797dbb7..50840de2c 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt @@ -36,8 +36,8 @@ class EnvActionsControlPlanSubThemeModel( controlPlanSubTheme: ControlPlanSubThemeModel, ) = EnvActionsControlPlanSubThemeModel( id = EnvActionsSubThemePk( - envActionId = envAction.id!!, - subthemeId = controlPlanSubTheme.id!!, + envActionId = envAction.id, + subthemeId = controlPlanSubTheme.id, ), envAction = envAction, controlPlanSubTheme = controlPlanSubTheme, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ReportingModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ReportingModel.kt index 16597bd60..c66181189 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ReportingModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ReportingModel.kt @@ -11,9 +11,9 @@ import fr.gouv.cacem.monitorenv.domain.entities.reporting.SourceTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.reporting.TargetDetailsEntity import fr.gouv.cacem.monitorenv.domain.entities.reporting.TargetTypeEnum import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos.ReportingDTO -import io.hypersistence.utils.hibernate.type.array.ListArrayType import io.hypersistence.utils.hibernate.type.basic.PostgreSQLEnumType import io.hypersistence.utils.hibernate.type.json.JsonBinaryType +import jakarta.persistence.CascadeType import jakarta.persistence.Column import jakarta.persistence.Entity import jakarta.persistence.EnumType @@ -24,12 +24,13 @@ import jakarta.persistence.GenerationType import jakarta.persistence.Id import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne +import jakarta.persistence.OneToMany import jakarta.persistence.Table import org.hibernate.Hibernate import org.hibernate.annotations.Generated -import org.hibernate.annotations.GenerationTime import org.hibernate.annotations.JdbcType import org.hibernate.annotations.Type +import org.hibernate.generator.EventType import org.hibernate.type.descriptor.jdbc.UUIDJdbcType import org.locationtech.jts.geom.Geometry import org.n52.jackson.datatype.jts.GeometryDeserializer @@ -39,12 +40,13 @@ import java.time.ZoneOffset.UTC @Entity @Table(name = "reportings") -data class ReportingModel( +class ReportingModel( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false) val id: Int? = null, - @Generated(GenerationTime.INSERT) + + @Generated(event = [EventType.INSERT]) @Column( name = "reporting_id", unique = true, @@ -57,55 +59,97 @@ data class ReportingModel( @Enumerated(EnumType.STRING) @Type(PostgreSQLEnumType::class) val sourceType: SourceTypeEnum? = null, + @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "semaphore_id", nullable = true) @JsonBackReference val semaphore: SemaphoreModel? = null, + @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "control_unit_id", nullable = true) @JsonBackReference val controlUnit: ControlUnitModel? = null, - @Column(name = "source_name") val sourceName: String? = null, + + @Column(name = "source_name") + val sourceName: String? = null, + @Column(name = "target_type", columnDefinition = "reportings_target_type") @Enumerated(EnumType.STRING) @Type(PostgreSQLEnumType::class) val targetType: TargetTypeEnum? = null, + @Column(name = "vehicle_type", columnDefinition = "reportings_vehicle_type") @Enumerated(EnumType.STRING) @Type(PostgreSQLEnumType::class) val vehicleType: VehicleTypeEnum? = null, + @Column(name = "target_details", columnDefinition = "jsonb") @Type(JsonBinaryType::class) val targetDetails: List? = listOf(), + @JsonSerialize(using = GeometrySerializer::class) @JsonDeserialize(contentUsing = GeometryDeserializer::class) @Column(name = "geom") val geom: Geometry? = null, - @Column(name = "sea_front") val seaFront: String? = null, - @Column(name = "description") val description: String? = null, + + @Column(name = "sea_front") + val seaFront: String? = null, + + @Column(name = "description") + val description: String? = null, + @Column(name = "report_type", columnDefinition = "reportings_report_type") @Enumerated(EnumType.STRING) @Type(PostgreSQLEnumType::class) val reportType: ReportingTypeEnum? = null, - @Column(name = "theme") val theme: String? = null, - @Column(name = "sub_themes") - @Type(ListArrayType::class) - val subThemes: List? = listOf(), - @Column(name = "action_taken") val actionTaken: String? = null, - @Column(name = "is_control_required") val isControlRequired: Boolean? = null, - @Column(name = "has_no_unit_available") val hasNoUnitAvailable: Boolean? = null, - @Column(name = "created_at") val createdAt: Instant, - @Column(name = "validity_time") val validityTime: Int? = null, - @Column(name = "is_archived", nullable = false) val isArchived: Boolean, - @Column(name = "is_deleted", nullable = false) val isDeleted: Boolean, - @Column(name = "open_by") val openBy: String? = null, + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "control_plan_theme_id", nullable = true) + val controlPlanTheme: ControlPlanThemeModel? = null, + + @OneToMany( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + orphanRemoval = true, + mappedBy = "reporting", + ) + val controlPlanSubThemes: MutableList? = ArrayList(), + + @Column(name = "action_taken") + val actionTaken: String? = null, + + @Column(name = "is_control_required") + val isControlRequired: Boolean? = null, + + @Column(name = "has_no_unit_available") + val hasNoUnitAvailable: Boolean? = null, + + @Column(name = "created_at") + val createdAt: Instant, + + @Column(name = "validity_time") + val validityTime: Int? = null, + + @Column(name = "is_archived", nullable = false) + val isArchived: Boolean, + + @Column(name = "is_deleted", nullable = false) + val isDeleted: Boolean, + + @Column(name = "open_by") + val openBy: String? = null, + @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "mission_id", nullable = true) @JsonBackReference val mission: MissionModel? = null, - @Column(name = "attached_to_mission_at_utc") val attachedToMissionAtUtc: Instant? = null, + + @Column(name = "attached_to_mission_at_utc") + val attachedToMissionAtUtc: Instant? = null, + @Column(name = "detached_from_mission_at_utc") val detachedFromMissionAtUtc: Instant? = null, + @JdbcType(UUIDJdbcType::class) @ManyToOne(fetch = FetchType.LAZY) @JoinColumn( @@ -131,8 +175,8 @@ data class ReportingModel( seaFront = seaFront, description = description, reportType = reportType, - theme = theme, - subThemes = subThemes, + themeId = controlPlanTheme?.id, + subThemeIds = controlPlanSubThemes?.map { it.id.subthemeId }, actionTaken = actionTaken, isControlRequired = isControlRequired, hasNoUnitAvailable = hasNoUnitAvailable, @@ -187,35 +231,34 @@ data class ReportingModel( controlUnitReference: ControlUnitModel?, missionReference: MissionModel?, envActionReference: EnvActionModel?, - ) = - ReportingModel( - id = reporting.id, - reportingId = reporting.reportingId, - sourceType = reporting.sourceType, - semaphore = semaphoreReference, - controlUnit = controlUnitReference, - sourceName = reporting.sourceName, - targetType = reporting.targetType, - vehicleType = reporting.vehicleType, - targetDetails = reporting.targetDetails, - geom = reporting.geom, - seaFront = reporting.seaFront, - description = reporting.description, - reportType = reporting.reportType, - theme = reporting.theme, - subThemes = reporting.subThemes, - actionTaken = reporting.actionTaken, - isControlRequired = reporting.isControlRequired, - hasNoUnitAvailable = reporting.hasNoUnitAvailable, - createdAt = reporting.createdAt.toInstant(), - validityTime = reporting.validityTime, - isArchived = reporting.isArchived, - isDeleted = reporting.isDeleted, - openBy = reporting.openBy, - mission = missionReference, - attachedToMissionAtUtc = reporting.attachedToMissionAtUtc?.toInstant(), - detachedFromMissionAtUtc = reporting.detachedFromMissionAtUtc?.toInstant(), - attachedEnvAction = envActionReference, - ) + controlPlanThemeReference: ControlPlanThemeModel?, + ) = ReportingModel( + id = reporting.id, + reportingId = reporting.reportingId, + sourceType = reporting.sourceType, + semaphore = semaphoreReference, + controlUnit = controlUnitReference, + sourceName = reporting.sourceName, + targetType = reporting.targetType, + vehicleType = reporting.vehicleType, + targetDetails = reporting.targetDetails, + geom = reporting.geom, + seaFront = reporting.seaFront, + description = reporting.description, + reportType = reporting.reportType, + controlPlanTheme = controlPlanThemeReference, + actionTaken = reporting.actionTaken, + isControlRequired = reporting.isControlRequired, + hasNoUnitAvailable = reporting.hasNoUnitAvailable, + createdAt = reporting.createdAt.toInstant(), + validityTime = reporting.validityTime, + isArchived = reporting.isArchived, + isDeleted = reporting.isDeleted, + openBy = reporting.openBy, + mission = missionReference, + attachedToMissionAtUtc = reporting.attachedToMissionAtUtc?.toInstant(), + detachedFromMissionAtUtc = reporting.detachedFromMissionAtUtc?.toInstant(), + attachedEnvAction = envActionReference, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ReportingsControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ReportingsControlPlanSubThemeModel.kt new file mode 100644 index 000000000..024534925 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ReportingsControlPlanSubThemeModel.kt @@ -0,0 +1,73 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.model + +import jakarta.persistence.Column +import jakarta.persistence.Embeddable +import jakarta.persistence.EmbeddedId +import jakarta.persistence.Entity +import jakarta.persistence.FetchType +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne +import jakarta.persistence.MapsId +import jakarta.persistence.Table +import org.hibernate.Hibernate +import java.io.Serializable + +@Entity +@Table(name = "reportings_control_plan_sub_themes") +class ReportingsControlPlanSubThemeModel( + @EmbeddedId + val id: ReportingsSubThemePk, + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("reportingId") + @JoinColumn(name = "reporting_id") + val reporting: ReportingModel? = null, + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("subthemeId") + @JoinColumn(name = "subtheme_id") + val controlPlanSubTheme: ControlPlanSubThemeModel? = null, +) { + companion object { + fun fromModels( + reporting: ReportingModel, + controlPlanSubTheme: ControlPlanSubThemeModel, + ) = ReportingsControlPlanSubThemeModel( + id = ReportingsSubThemePk( + reportingId = reporting.id!!, + subthemeId = controlPlanSubTheme.id, + ), + reporting = reporting, + controlPlanSubTheme = controlPlanSubTheme, + ) + } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false + other as ReportingsControlPlanSubThemeModel + + return id != null && id == other.id + } + + override fun hashCode(): Int = javaClass.hashCode() +} + +@Embeddable +data class ReportingsSubThemePk( + @Column(name = "reporting_id") + val reportingId: Int, + @Column(name = "subtheme_id") + val subthemeId: Int, +) : Serializable { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is ReportingsSubThemePk) return false + + return reportingId == other.reportingId && + subthemeId == other.subthemeId + } + + override fun hashCode(): Int { + return listOf(reportingId, subthemeId).hashCode() + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt index 92c4d8abf..05ed5a20b 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt @@ -145,11 +145,11 @@ class JpaMissionRepository( val missionModel = MissionModel.fromMissionEntity( mission = mission, - mapper = mapper, controlUnitResourceModelMap = controlUnitResourceModelMap, controlPlanThemesReferenceModelMap = controlPlanThemesReferenceModelMap ?: emptyMap(), controlPlanSubThemesReferenceModelMap = controlPlanSubThemesReferenceModelMap ?: emptyMap(), controlPlanTagsReferenceModelMap = controlPlanTagsReferenceModelMap ?: emptyMap(), + mapper = mapper, ) return dbMissionRepository.saveAndFlush(missionModel).toMissionDTO(mapper) } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt index fa0f22cfa..871fba790 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt @@ -8,6 +8,9 @@ import fr.gouv.cacem.monitorenv.domain.exceptions.NotFoundException import fr.gouv.cacem.monitorenv.domain.repositories.IReportingRepository import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos.ReportingDTO import fr.gouv.cacem.monitorenv.infrastructure.database.model.ReportingModel +import fr.gouv.cacem.monitorenv.infrastructure.database.model.ReportingsControlPlanSubThemeModel +import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanSubThemeRepository +import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanThemeRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlUnitRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBEnvActionRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBMissionRepository @@ -27,6 +30,8 @@ class JpaReportingRepository( private val dbReportingRepository: IDBReportingRepository, private val dbMissionRepository: IDBMissionRepository, private val dbSemaphoreRepository: IDBSemaphoreRepository, + private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, + private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, private val dbControlUnitRepository: IDBControlUnitRepository, private val dbEnvActionRepository: IDBEnvActionRepository, private val mapper: ObjectMapper, @@ -118,15 +123,39 @@ class JpaReportingRepository( } else { null } - val reportingModel = + val controlPlanThemeReference = + if (reporting.themeId != null) { + dbControlPlanThemeRepository.getReferenceById( + reporting.themeId, + ) + } else { + null + } + val controlPlanSubThemesReferenceList = reporting.subThemeIds?.map { + dbControlPlanSubThemeRepository.getReferenceById(it) + } + + // To save controlPlanSubThemes we must ensure that reportingId is set + // to simplify the understandability of the code, we do the same steps for creation and update + // even if it is not necessary for update + // first save (ensure id is set) + val reportingModel = dbReportingRepository.save( ReportingModel.fromReportingEntity( reporting = reporting, semaphoreReference = semaphoreReference, controlUnitReference = controlUnitReference, missionReference = missionReference, envActionReference = envActionReference, - ) + controlPlanThemeReference = controlPlanThemeReference, + ), + ) + // set controlPlanSubThemes and save again (and flush) + controlPlanSubThemesReferenceList?.forEach { it -> + reportingModel.controlPlanSubThemes?.add( + ReportingsControlPlanSubThemeModel.fromModels(reportingModel, it), + ) + } dbReportingRepository.saveAndFlush(reportingModel).toReportingDTO(mapper) } catch (e: JpaObjectRetrievalFailureException) { throw NotFoundException( diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index 2de08e4f2..933d52f0f 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -45,14 +45,11 @@ CREATE TABLE env_actions_control_plan_tags ( ); CREATE TABLE reportings_control_plan_sub_themes ( - id serial PRIMARY KEY, reporting_id integer, - theme_id integer NOT NULL, subtheme_id integer, foreign key (reporting_id) references reportings(id), - foreign key (theme_id) references control_plan_themes(id), foreign key (subtheme_id) references control_plan_subthemes(id), - unique (reporting_id, theme_id, subtheme_id) + primary key (reporting_id, subtheme_id) ); COMMENT ON TABLE reportings_control_plan_sub_themes IS 'Table de jointure entre les signalements et les sous-thèmes du plan de contrôle'; @@ -62,6 +59,9 @@ COMMENT ON TABLE control_plan_tags IS 'Table des tags du plan de contrôle reli COMMENT ON TABLE env_actions_control_plan_sub_themes IS 'Table de jointure entre les actions et les sous-thèmes du plan de contrôle'; COMMENT ON TABLE env_actions_control_plan_tags IS 'Table de jointure entre les actions et les tags reliées aux thématiques du plan de contrôle'; +ALTER TABLE reportings add column control_plan_theme_id integer; +ALTER TABLE reportings ADD CONSTRAINT fk_reportings_control_plan_themes FOREIGN KEY (control_plan_theme_id) REFERENCES control_plan_themes(id); + -- Insertion des themes et sous-themes à partir de la table control_themes INSERT INTO control_plan_themes (theme) SELECT distinct theme_level_1 FROM control_themes ORDER BY theme_level_1 @@ -147,7 +147,7 @@ INSERT INTO reportings_control_plan_sub_themes (reporting_id, subtheme_id) FROM public.reportings r WHERE r.sub_themes is not null ) - SELECT rt.id, th.id + SELECT rt.id, sbt.id FROM reportingthemes rt, public.control_plan_themes as th, public.control_plan_subthemes as sbt @@ -156,3 +156,8 @@ INSERT INTO reportings_control_plan_sub_themes (reporting_id, subtheme_id) AND rt.subtheme = sbt.subtheme AND sbt.year = 2023 ; + +UPDATE reportings + SET control_plan_theme_id = th.id + FROM control_plan_themes as th + WHERE th.theme = reportings.theme; \ No newline at end of file diff --git a/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql b/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql index 447c8792c..f3970017c 100644 --- a/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql +++ b/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql @@ -1,168 +1,13 @@ DELETE FROM reportings; -INSERT INTO reportings ( - id, - reporting_id, - source_type , - semaphore_id , - control_unit_id , - source_name , - target_type , - vehicle_type, - target_details, - geom, - sea_front, - description, - report_type, - theme, - sub_themes, - action_taken, - is_control_required, - has_no_unit_available, - created_at, - validity_time, - is_deleted, - is_archived, - mission_id, - attached_to_mission_at_utc, - detached_from_mission_at_utc - ) -VALUES -( - 1, - 2300001, - 'SEMAPHORE', - 21, - null, - null, - 'VEHICLE', - 'VESSEL', - '[{"vesselName": "Vessel 1", "mmsi": "012314231343" }]', - ST_GeomFromText('MULTIPOINT((-4.938881879556736 48.4149566883917))', 4326), - 'NAMO', - 'Description 1', - 'INFRACTION_SUSPICION', - 'Rejets illicites', - '{"Jet de déchet","Carénage sauvage"}', - 'ACTION TAKEN', - true, - true, - now() - INTERVAL '3 days', - 24, - false, - false, - null, - null, - null - ), -( - 2, - 2300002, - 'SEMAPHORE', - 23, - null, - null, - 'VEHICLE', - 'VESSEL', - '[{"vesselName": "Vessel 2", "mmsi": "012314231344" }]', - ST_GeomFromText('MULTIPOINT((-4.779484119719514 48.619074487031526))', 4326), - 'NAMO', - 'Description 2', - 'INFRACTION_SUSPICION', - 'Police des mouillages', - '{"ZMEL"}', - 'ACTION TAKEN', - true, - true, - now() - INTERVAL '2 days', - 2, - false, - false, - null, - null, - null -), -( - 3, - 2300003, - 'CONTROL_UNIT', - null, - 10000, - null, - 'VEHICLE', - 'VESSEL', - '[{"vesselName": "Vessel 3", "mmsi": "012314231345" }]', - ST_GeomFromText('MULTIPOLYGON(((-3.504632038765229 48.938606793539606,-3.24829506967698 48.956239351532986,-3.484446288370139 48.996964545159244,-3.504632038765229 48.938606793539606)))', 4326), - 'NAMO', - 'Description 3', - 'INFRACTION_SUSPICION', - 'Police des mouillages', - '{"ZMEL"}', - 'ACTION TAKEN', - true, - true, - now() - INTERVAL '1 hour', - 1, - false, - false, - null, - null, - null -), -( - 4, - 2300004, - 'OTHER', - null, - null, - 'MA SUPER SOCIETE', - 'INDIVIDUAL', - NULL, - '[{"operatorName": "Mr le dirigeant" }]', - ST_GeomFromText('MULTIPOLYGON(((-2.81383107 49.49805557, -2.63290938 49.59886363, -2.80213877 49.69953506, -2.91683355 49.52263623, -2.81383107 49.49805557)))', 4326), - 'MED', - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ultrices risus ac arcu pellentesque, et tempor justo tempor. Pellentesque sem nisl, tempor id augue non, interdum sollicitudin felis.', - 'OBSERVATION', - 'Pêche à pied', - '{"Braconnage"}', - NULL, - true, - true, - now() - INTERVAL '3 hour', - 4, - false, - false, - null, - null, - null -), -( - 5, - 2300005, - 'SEMAPHORE', - 36, - NULL, - NULL, - 'COMPANY', - NULL, - '[{"operatorName": "Ma société", "vesselName": "Mr le gérant" }]', - ST_GeomFromText('MULTIPOINT((0.37083333 49.76777778))', 4326), - 'Guadeloupe', - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', - 'OBSERVATION', - NULL, - NULL, - NULL, - true, - true, - now() - INTERVAL '1 hour', - 6, - false, - false, - null, - null, - null -); +INSERT INTO public.reportings VALUES (1, 2300001, 'SEMAPHORE', 21, NULL, NULL, 'VEHICLE', 'VESSEL', '[{"mmsi": "012314231343", "vesselName": "Vessel 1"}]', '0104000020E610000001000000010100000045035E406AC113C00CF3FE4C1D354840', 'NAMO', 'Description 1', 'INFRACTION_SUSPICION', 'Rejets illicites', '{"Jet de déchet","Carénage sauvage"}', 'ACTION TAKEN', true, true, '2023-12-05 18:27:58.191835', 24, false, false, NULL, NULL, NULL, NULL, NULL, 19); +INSERT INTO public.reportings VALUES (2, 2300002, 'SEMAPHORE', 23, NULL, NULL, 'VEHICLE', 'VESSEL', '[{"mmsi": "012314231344", "vesselName": "Vessel 2"}]', '0104000020E610000001000000010100000062C9C715311E13C050CB31D53D4F4840', 'NAMO', 'Description 2', 'INFRACTION_SUSPICION', 'Police des mouillages', '{ZMEL}', 'ACTION TAKEN', true, true, '2023-12-06 18:27:58.191835', 2, false, false, NULL, NULL, NULL, NULL, NULL, 12); +INSERT INTO public.reportings VALUES (3, 2300003, 'CONTROL_UNIT', NULL, 10000, NULL, 'VEHICLE', 'VESSEL', '[{"mmsi": "012314231345", "vesselName": "Vessel 3"}]', '0106000020E610000001000000010300000001000000040000006E15B8857C090CC02C07754424784840552A202082FC09C0C0FD120D667A484025BF296025E00BC0805DC2889C7F48406E15B8857C090CC02C07754424784840', 'NAMO', 'Description 3', 'INFRACTION_SUSPICION', 'Police des mouillages', '{ZMEL}', 'ACTION TAKEN', true, true, '2023-12-08 17:27:58.191835', 1, false, false, NULL, NULL, NULL, NULL, NULL, 12); +INSERT INTO public.reportings VALUES (4, 2300004, 'OTHER', NULL, NULL, 'MA SUPER SOCIETE', 'INDIVIDUAL', NULL, '[{"operatorName": "Mr le dirigeant"}]', '0106000020E6100000010000000103000000010000000500000012F330DDB98206C0CD5EF048C0BF4840FE7303CB321005C092CE3C90A7CC4840820740BBC76A06C07E8D665D8AD94840310109D4AC5507C002C775BEE5C2484012F330DDB98206C0CD5EF048C0BF4840', 'MED', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ultrices risus ac arcu pellentesque, et tempor justo tempor. Pellentesque sem nisl, tempor id augue non, interdum sollicitudin felis.', 'OBSERVATION', 'Pêche à pied', '{Braconnage}', NULL, true, true, '2023-12-08 15:27:58.191835', 4, false, false, NULL, NULL, NULL, NULL, NULL, 18); +INSERT INTO public.reportings VALUES (5, 2300005, 'SEMAPHORE', 36, NULL, NULL, 'COMPANY', NULL, '[{"vesselName": "Mr le gérant", "operatorName": "Ma société"}]', '0104000020E6100000010000000101000000417927B8BBBBD73F06D9D38A46E24840', 'Guadeloupe', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, '2023-12-08 17:27:58.191835', 6, false, false, NULL, NULL, NULL, NULL, NULL, NULL); +INSERT INTO public.reportings VALUES (6, 2300006, 'SEMAPHORE', 36, NULL, NULL, 'COMPANY', NULL, '[{"vesselName": "Héron", "operatorName": "La sociéter"}]', '0104000020E6100000010000000101000000A22CD736208DF9BF242A543717D44540', 'Guadeloupe', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', 'Police des mouillages', '{ZMEL}', NULL, true, true, '2023-12-08 17:12:58.191835', 6, false, false, 'ABC', 34, '2023-12-08 18:12:58.191835', NULL, 'b8007c8a-5135-4bc3-816f-c69c7b75d807', 12); +INSERT INTO public.reportings VALUES (7, 2300007, 'CONTROL_UNIT', NULL, 10001, NULL, 'COMPANY', NULL, '[{"vesselName": "Mr le gérant", "operatorName": "Good Company"}]', '0104000020E6100000010000000101000000BDAE0F9A19C010C068D780A5708E4740', 'NAMO', 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, '2023-12-08 16:57:58.191835', 6, false, false, 'DEF', 34, '2023-12-08 18:02:58.191835', NULL, NULL, NULL); +INSERT INTO public.reportings VALUES (8, 2300008, 'CONTROL_UNIT', NULL, 10001, NULL, 'COMPANY', NULL, '[{"vesselName": "Mr le gérant", "operatorName": "Good Company"}]', '0104000020E61000000100000001010000005BE1449141C0F5BF89869C29BA034740', 'NAMO', 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, '2023-12-08 16:57:58.191835', 6, false, false, 'GHI', 38, '2023-12-08 18:02:58.191835', NULL, NULL, NULL); /* reporting linked to a surveillance */ @@ -178,3 +23,10 @@ INSERT INTO reportings (id, reporting_id, source_type, semaphore_id, control_uni SELECT setval('reportings_id_seq', (SELECT max(id) FROM reportings), true); CREATE SEQUENCE IF NOT EXISTS reportings_2023_seq; SELECT setval('reportings_2023_seq', (SELECT max(id) FROM reportings), true); + +INSERT INTO public.reportings_control_plan_sub_themes VALUES (1, 62); +INSERT INTO public.reportings_control_plan_sub_themes VALUES (1, 27); +INSERT INTO public.reportings_control_plan_sub_themes VALUES (2, 82); +INSERT INTO public.reportings_control_plan_sub_themes VALUES (3, 82); +INSERT INTO public.reportings_control_plan_sub_themes VALUES (4, 25); +INSERT INTO public.reportings_control_plan_sub_themes VALUES (6, 82); diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/CreateOrUpdateReportingUTests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/CreateOrUpdateReportingUTests.kt index 53b2406a7..ca2211851 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/CreateOrUpdateReportingUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/CreateOrUpdateReportingUTests.kt @@ -81,8 +81,8 @@ class CreateOrUpdateReportingUTests { seaFront = "Facade 1", description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, @@ -104,8 +104,8 @@ class CreateOrUpdateReportingUTests { seaFront = "Facade 1", description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, @@ -126,8 +126,8 @@ class CreateOrUpdateReportingUTests { seaFront = "Facade 1", description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, @@ -149,8 +149,8 @@ class CreateOrUpdateReportingUTests { seaFront = "Facade 1", description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, @@ -241,8 +241,8 @@ class CreateOrUpdateReportingUTests { geom = polygon, description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, @@ -287,8 +287,8 @@ class CreateOrUpdateReportingUTests { geom = polygon, description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, @@ -333,8 +333,8 @@ class CreateOrUpdateReportingUTests { geom = polygon, description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, @@ -354,8 +354,8 @@ class CreateOrUpdateReportingUTests { geom = polygon, description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, @@ -373,8 +373,8 @@ class CreateOrUpdateReportingUTests { geom = polygon, description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, @@ -449,8 +449,8 @@ class CreateOrUpdateReportingUTests { geom = polygon, description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, @@ -478,8 +478,8 @@ class CreateOrUpdateReportingUTests { geom = polygon, description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 1, + subThemeIds = listOf(10, 11), actionTaken = "actions effectuées blabal ", isControlRequired = true, hasNoUnitAvailable = true, diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlUnit/CanDeleteControlUnitUTests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlUnit/CanDeleteControlUnitUTests.kt index 68ce74a0f..7b2dc1e62 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlUnit/CanDeleteControlUnitUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlUnit/CanDeleteControlUnitUTests.kt @@ -90,8 +90,8 @@ class CanDeleteControlUnitUTests { seaFront = null, description = null, reportType = null, - theme = null, - subThemes = null, + themeId = null, + subThemeIds = null, actionTaken = null, isControlRequired = null, hasNoUnitAvailable = null, diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/TestUtils.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/TestUtils.kt index f24c94dfb..a4a01f5e2 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/TestUtils.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/TestUtils.kt @@ -29,8 +29,8 @@ object TestUtils { seaFront = "Facade 1", description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 12, + subThemeIds = listOf(82), actionTaken = "actions effectuées blabla", isControlRequired = true, hasNoUnitAvailable = true, @@ -65,8 +65,8 @@ object TestUtils { seaFront = "Facade 1", description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 12, + subThemeIds = listOf(82), actionTaken = "actions effectuées blabla", isControlRequired = true, hasNoUnitAvailable = true, diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt index 2008e38a1..9d889c67b 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt @@ -244,8 +244,8 @@ class MissionsControllerITests { reportType = ReportingTypeEnum .INFRACTION_SUSPICION, - theme = "Theme", - subThemes = listOf("SubTheme"), + themeId = 12, + subThemeIds = listOf(82), actionTaken = "ActionTaken", isControlRequired = true, hasNoUnitAvailable = true, @@ -573,8 +573,8 @@ class MissionsControllerITests { reportType = ReportingTypeEnum .INFRACTION_SUSPICION, - theme = "Theme", - subThemes = listOf("SubTheme"), + themeId = 12, + subThemeIds = listOf(82), actionTaken = "ActionTaken", isControlRequired = true, hasNoUnitAvailable = true, diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ReportingsControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ReportingsControllerITests.kt index 338bd5b42..f741ee1e8 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ReportingsControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ReportingsControllerITests.kt @@ -82,8 +82,8 @@ class ReportingsControllerITests { seaFront = "Facade 1", description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 12, + subThemeIds = listOf(64, 82), actionTaken = "actions effectuées blabla", isControlRequired = true, hasNoUnitAvailable = true, @@ -117,8 +117,8 @@ class ReportingsControllerITests { geom = polygon, description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 12, + subThemeIds = listOf(64, 82), actionTaken = "actions effectuées blabla", isControlRequired = true, hasNoUnitAvailable = true, @@ -155,9 +155,9 @@ class ReportingsControllerITests { .andExpect(jsonPath("$.seaFront").value("Facade 1")) .andExpect(jsonPath("$.description").value("description")) .andExpect(jsonPath("$.reportType").value("INFRACTION_SUSPICION")) - .andExpect(jsonPath("$.theme").value("theme")) - .andExpect(jsonPath("$.subThemes[0]").value("subTheme1")) - .andExpect(jsonPath("$.subThemes[1]").value("subTheme2")) + .andExpect(jsonPath("$.themeId").value(12)) + .andExpect(jsonPath("$.subThemeIds[0]").value(64)) + .andExpect(jsonPath("$.subThemeIds[1]").value(82)) .andExpect( jsonPath("$.actionTaken").value("actions effectuées blabla"), ) @@ -188,8 +188,8 @@ class ReportingsControllerITests { seaFront = "Facade 1", description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 12, + subThemeIds = listOf(64, 82), actionTaken = "actions effectuées blabla", isControlRequired = true, hasNoUnitAvailable = true, @@ -234,9 +234,9 @@ class ReportingsControllerITests { .andExpect(jsonPath("$.seaFront").value("Facade 1")) .andExpect(jsonPath("$.description").value("description")) .andExpect(jsonPath("$.reportType").value("INFRACTION_SUSPICION")) - .andExpect(jsonPath("$.theme").value("theme")) - .andExpect(jsonPath("$.subThemes[0]").value("subTheme1")) - .andExpect(jsonPath("$.subThemes[1]").value("subTheme2")) + .andExpect(jsonPath("$.themeId").value(12)) + .andExpect(jsonPath("$.subThemeIds[0]").value(64)) + .andExpect(jsonPath("$.subThemeIds[1]").value(82)) .andExpect( jsonPath("$.actionTaken").value("actions effectuées blabla"), ) @@ -266,8 +266,8 @@ class ReportingsControllerITests { seaFront = "Facade 1", description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 12, + subThemeIds = listOf(64, 82), actionTaken = "actions effectuées blabla", isControlRequired = true, hasNoUnitAvailable = true, @@ -324,8 +324,8 @@ class ReportingsControllerITests { seaFront = "Facade 1", description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = listOf("subTheme1", "subTheme2"), + themeId = 12, + subThemeIds = listOf(64, 82), actionTaken = "actions effectuées blabla", isControlRequired = true, hasNoUnitAvailable = true, @@ -359,12 +359,8 @@ class ReportingsControllerITests { geom = polygon, description = "description", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "theme", - subThemes = - listOf( - "subTheme1", - "subTheme2", - ), + themeId = 12, + subThemeIds = listOf(64, 82), actionTaken = "actions effectuées blabla", isControlRequired = true, hasNoUnitAvailable = true, @@ -400,9 +396,9 @@ class ReportingsControllerITests { .andExpect(jsonPath("$.seaFront").value("Facade 1")) .andExpect(jsonPath("$.description").value("description")) .andExpect(jsonPath("$.reportType").value("INFRACTION_SUSPICION")) - .andExpect(jsonPath("$.theme").value("theme")) - .andExpect(jsonPath("$.subThemes[0]").value("subTheme1")) - .andExpect(jsonPath("$.subThemes[1]").value("subTheme2")) + .andExpect(jsonPath("$.themeId").value(12)) + .andExpect(jsonPath("$.subThemeIds[0]").value(64)) + .andExpect(jsonPath("$.subThemeIds[1]").value(82)) .andExpect( jsonPath("$.actionTaken").value("actions effectuées blabla"), ) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepositoryITests.kt.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepositoryITests.kt.kt index 0d9fb4564..7dd9a5276 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepositoryITests.kt.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepositoryITests.kt.kt @@ -261,8 +261,8 @@ class JpaReportingRepositoryITests : AbstractDBTests() { seaFront = "NAMO", description = "Test reporting", reportType = ReportingTypeEnum.INFRACTION_SUSPICION, - theme = "Police des mouillages", - subThemes = listOf("ZMEL"), + themeId = 12, + subThemeIds = listOf(82), actionTaken = "Aucune", isControlRequired = false, hasNoUnitAvailable = false, @@ -289,8 +289,8 @@ class JpaReportingRepositoryITests : AbstractDBTests() { assertThat(reportingDTO.reporting.description).isEqualTo("Test reporting") assertThat(reportingDTO.reporting.reportType) .isEqualTo(ReportingTypeEnum.INFRACTION_SUSPICION) - assertThat(reportingDTO.reporting.theme).isEqualTo("Police des mouillages") - assertThat(reportingDTO.reporting.subThemes).isEqualTo(listOf("ZMEL")) + assertThat(reportingDTO.reporting.themeId).isEqualTo(12) + assertThat(reportingDTO.reporting.subThemeIds).isEqualTo(listOf(82)) assertThat(reportingDTO.reporting.actionTaken).isEqualTo("Aucune") assertThat(reportingDTO.reporting.isControlRequired).isEqualTo(false) assertThat(reportingDTO.reporting.hasNoUnitAvailable).isEqualTo(false) From 8c20d22f5f1b5a2d201048377522814c33b67cb0 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:51 +0100 Subject: [PATCH 17/53] fix table name + add tests --- .../model/ControlPlanSubThemeModel.kt | 2 +- .../internal/V0.103__create_action_theme.sql | 18 ++++++------- ...6.08__insert_dummy_control_plan_themes.sql | 12 ++++----- .../JpaControlPlanTagRepositoryITests.kt | 25 +++++++++++++++++++ .../JpaControlPlanThemeRepositoryITests.kt | 22 ++++++++++++++++ 5 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt index 5458bae6b..bc035154a 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt @@ -15,7 +15,7 @@ import org.hibernate.annotations.Cache import org.hibernate.annotations.CacheConcurrencyStrategy @Entity -@Table(name = "control_plan_subthemes") +@Table(name = "control_plan_sub_themes") @Cache( usage = CacheConcurrencyStrategy.READ_WRITE, ) diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index 933d52f0f..c87f2c776 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -5,13 +5,13 @@ CREATE TABLE control_plan_themes ( theme text UNIQUE NOT NULL ); -CREATE TABLE control_plan_subthemes ( +CREATE TABLE control_plan_sub_themes ( id serial PRIMARY KEY, subtheme text, theme_id int REFERENCES control_plan_themes(id), year int ); -CREATE INDEX idx_control_plan_subthemes_year ON control_plan_subthemes USING btree(year); +CREATE INDEX idx_control_plan_sub_themes_year ON control_plan_sub_themes USING btree(year); CREATE TABLE control_plan_tags ( @@ -32,7 +32,7 @@ CREATE TABLE env_actions_control_plan_sub_themes ( env_action_id uuid, subtheme_id integer, foreign key (env_action_id) references env_actions(id), - foreign key (subtheme_id) references control_plan_subthemes(id), + foreign key (subtheme_id) references control_plan_sub_themes(id), primary key (env_action_id, subtheme_id) ); @@ -48,13 +48,13 @@ CREATE TABLE reportings_control_plan_sub_themes ( reporting_id integer, subtheme_id integer, foreign key (reporting_id) references reportings(id), - foreign key (subtheme_id) references control_plan_subthemes(id), + foreign key (subtheme_id) references control_plan_sub_themes(id), primary key (reporting_id, subtheme_id) ); COMMENT ON TABLE reportings_control_plan_sub_themes IS 'Table de jointure entre les signalements et les sous-thèmes du plan de contrôle'; COMMENT ON TABLE control_plan_themes IS 'Table des thèmes du plan de contrôle'; -COMMENT ON TABLE control_plan_subthemes IS 'Table des sous-thèmes du plan de contrôle versionnés par année'; +COMMENT ON TABLE control_plan_sub_themes IS 'Table des sous-thèmes du plan de contrôle versionnés par année'; COMMENT ON TABLE control_plan_tags IS 'Table des tags du plan de contrôle reliés aux thématiques'; COMMENT ON TABLE env_actions_control_plan_sub_themes IS 'Table de jointure entre les actions et les sous-thèmes du plan de contrôle'; COMMENT ON TABLE env_actions_control_plan_tags IS 'Table de jointure entre les actions et les tags reliées aux thématiques du plan de contrôle'; @@ -67,7 +67,7 @@ INSERT INTO control_plan_themes (theme) SELECT distinct theme_level_1 FROM control_themes ORDER BY theme_level_1 ; -INSERT INTO control_plan_subthemes (subtheme, theme_id, year) +INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) SELECT distinct theme_level_2, t.id, 2023 FROM control_themes c JOIN control_plan_themes t ON t.theme = theme_level_1 WHERE theme_level_2 IS NOT NULL ORDER BY theme_level_2 @@ -103,7 +103,7 @@ INSERT INTO env_actions_control_plan_sub_themes (env_action_id, subtheme_id) ) SELECT themes.env_action_id, sbt.id FROM themes, - control_plan_subthemes sbt, + control_plan_sub_themes sbt, control_plan_themes th WHERE sbt.subtheme = themes.subtheme AND sbt.theme_id = th.id @@ -150,7 +150,7 @@ INSERT INTO reportings_control_plan_sub_themes (reporting_id, subtheme_id) SELECT rt.id, sbt.id FROM reportingthemes rt, public.control_plan_themes as th, - public.control_plan_subthemes as sbt + public.control_plan_sub_themes as sbt WHERE th.id = sbt.theme_id AND rt.theme = th.theme AND rt.subtheme = sbt.subtheme @@ -160,4 +160,4 @@ INSERT INTO reportings_control_plan_sub_themes (reporting_id, subtheme_id) UPDATE reportings SET control_plan_theme_id = th.id FROM control_plan_themes as th - WHERE th.theme = reportings.theme; \ No newline at end of file + WHERE th.theme = reportings.theme; diff --git a/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql b/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql index 0eb8fb447..913bc40cc 100644 --- a/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql +++ b/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql @@ -2,13 +2,13 @@ INSERT INTO control_plan_themes (id, theme) VALUES (100001, 'Mouillage Individuel'); INSERT INTO control_plan_themes (id, theme) VALUES (100002, 'Rejet'); -INSERT INTO control_plan_subthemes (subtheme, theme_id, year) VALUES ('Mouillage réglementé par arrêté', 100001, 2024); -INSERT INTO control_plan_subthemes (subtheme, theme_id, year) VALUES ('Mouillage réglementé par AMP', 100001, 2024); -INSERT INTO control_plan_subthemes (subtheme, theme_id, year) VALUES ('Mouillage avec AOT individuelle', 100001, 2024); -INSERT INTO control_plan_subthemes (subtheme, theme_id, year) VALUES ('Autre mouillage', 100001, 2024); -INSERT INTO control_plan_subthemes (subtheme, theme_id, year) VALUES ('Jet de déchet (macro déchet)', 100002, 2024); +INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Mouillage réglementé par arrêté', 100001, 2024); +INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Mouillage réglementé par AMP', 100001, 2024); +INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Mouillage avec AOT individuelle', 100001, 2024); +INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Autre mouillage', 100001, 2024); +INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Jet de déchet (macro déchet)', 100002, 2024); -INSERT INTO control_plan_subthemes (subtheme, theme_id, year) +INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) SELECT 'Destruction, capture, arrachage', id, 2024 FROM control_plan_themes WHERE theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt new file mode 100644 index 000000000..24c364fad --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt @@ -0,0 +1,25 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +class JpaControlPlanTagRepositoryITests : AbstractDBTests() { + @Autowired + private lateinit var jpaControlPlanTagRepository: JpaControlPlanTagRepository + + @Test + fun `findByYear Should return all control plan tags for a specific year`() { + // When + val requestedControlPlanTagsFor2023 = jpaControlPlanTagRepository.findByYear(2023) + val requestedControlPlanTagsFor2024 = jpaControlPlanTagRepository.findByYear(2024) + // Then + assertThat(requestedControlPlanTagsFor2023.size).isEqualTo(48) + assertThat(requestedControlPlanTagsFor2024.size).isEqualTo(6) + assertThat(requestedControlPlanTagsFor2024[5].id).isEqualTo(6) + assertThat(requestedControlPlanTagsFor2024[5].themeId).isEqualTo(11) + assertThat(requestedControlPlanTagsFor2024[5].tag).isEqualTo( + "Reptiles", + ) + } +} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt new file mode 100644 index 000000000..89738672c --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt @@ -0,0 +1,22 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +class JpaControlPlanThemeRepositoryITests : AbstractDBTests() { + @Autowired + private lateinit var jpaControlPlanThemeRepository: JpaControlPlanThemeRepository + + @Test + fun `findByYear Should return all control plan theme for a specific year`() { + // When + val requestedControlPlanThemesFor2023 = jpaControlPlanThemeRepository.findByYear(2023) + val requestedControlPlanThemesFor2024 = jpaControlPlanThemeRepository.findByYear(2024) + // Then + assertThat(requestedControlPlanThemesFor2023.size).isEqualTo(83) + assertThat(requestedControlPlanThemesFor2024.size).isEqualTo(6) + assertThat(requestedControlPlanThemesFor2024[5].id).isEqualTo(100002) + assertThat(requestedControlPlanThemesFor2024[5].theme).isEqualTo("Rejet") + } +} From eff219617bcaf7a17f5990773cdda27c3131413e Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:51 +0100 Subject: [PATCH 18/53] Return ControlPlanThemes for every year --- .../IControlPlanSubThemeRepository.kt | 2 +- .../repositories/IControlPlanTagRepository.kt | 2 +- .../repositories/IControlPlanThemeRepository.kt | 2 +- ...tControlPlansByYear.kt => GetControlPlans.kt} | 16 ++++++++-------- .../bff/outputs/ControlPlanSubThemeDataOutput.kt | 2 ++ .../api/endpoints/bff/ControlPlansController.kt | 16 ++++++---------- .../JpaControlPlanSubThemeRepository.kt | 4 ++-- .../repositories/JpaControlPlanTagRepository.kt | 4 ++-- .../JpaControlPlanThemeRepository.kt | 4 ++-- .../IDBControlPlanSubThemeRepository.kt | 4 +--- .../interfaces/IDBControlPlanTagRepository.kt | 15 +-------------- .../interfaces/IDBControlPlanThemeRepository.kt | 14 +------------- ...ansByYearUTest.kt => GetControlPlansUTest.kt} | 14 +++++++------- .../bff/ControlPlansControllerITests.kt | 10 +++++----- .../JpaControlPlanSubThemeRepositoryITests.kt | 16 +++++++--------- .../JpaControlPlanTagRepositoryITests.kt | 16 +++++++--------- .../JpaControlPlanThemeRepositoryITests.kt | 12 +++++------- 17 files changed, 59 insertions(+), 94 deletions(-) rename backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/{GetControlPlansByYear.kt => GetControlPlans.kt} (74%) rename backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/{GetControlPlansByYearUTest.kt => GetControlPlansUTest.kt} (85%) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt index b5833f821..aba64dc6e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt @@ -3,5 +3,5 @@ package fr.gouv.cacem.monitorenv.domain.repositories import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity interface IControlPlanSubThemeRepository { - fun findByYear(year: Int): List + fun findAll(): List } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt index f4c54a1c5..dae4b69d0 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt @@ -3,5 +3,5 @@ package fr.gouv.cacem.monitorenv.domain.repositories import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity interface IControlPlanTagRepository { - fun findByYear(year: Int): List + fun findAll(): List } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt index 4724bc020..95e65ed98 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt @@ -3,5 +3,5 @@ package fr.gouv.cacem.monitorenv.domain.repositories import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity interface IControlPlanThemeRepository { - fun findByYear(year: Int): List + fun findAll(): List } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlans.kt similarity index 74% rename from backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt rename to backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlans.kt index 86d65775e..199df21c7 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlans.kt @@ -10,22 +10,22 @@ import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository import org.slf4j.LoggerFactory @UseCase -class GetControlPlansByYear( +class GetControlPlans( private val controlPlanThemeRepository: IControlPlanThemeRepository, private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository, private val controlPlanTagRepository: IControlPlanTagRepository, ) { - private val logger = LoggerFactory.getLogger(GetControlPlansByYear::class.java) - fun execute(year: Int): ControlPlanByYear { - val controlPlanThemes = controlPlanThemeRepository.findByYear(year) - val controlPlanSubThemes = controlPlanSubThemeRepository.findByYear(year) - val controlPlanTags = controlPlanTagRepository.findByYear(year) - logger.info("Found ${controlPlanSubThemes.size} control plan subthemes for year $year") + private val logger = LoggerFactory.getLogger(GetControlPlans::class.java) + fun execute(): ControlPlanThemes { + val controlPlanThemes = controlPlanThemeRepository.findAll() + val controlPlanSubThemes = controlPlanSubThemeRepository.findAll() + val controlPlanTags = controlPlanTagRepository.findAll() + logger.info("Found ${controlPlanThemes.size} control plan themes, ${controlPlanSubThemes.size} subthemes, and ${controlPlanTags.size} tags ") return Triple(controlPlanThemes, controlPlanSubThemes, controlPlanTags) } } -typealias ControlPlanByYear = Triple< +typealias ControlPlanThemes = Triple< List, List, List,> diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt index b653690e2..2c5ce4f14 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt @@ -6,6 +6,7 @@ data class ControlPlanSubThemeDataOutput( val id: Int, val themeId: Int, val subTheme: String, + val year: Int, ) { companion object { fun fromControlPlanSubThemeEntity(controlPlanSubTheme: ControlPlanSubThemeEntity) = @@ -13,6 +14,7 @@ data class ControlPlanSubThemeDataOutput( id = controlPlanSubTheme.id, themeId = controlPlanSubTheme.themeId, subTheme = controlPlanSubTheme.subTheme, + year = controlPlanSubTheme.year, ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt index 480e8fb4b..fa187ebaf 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt @@ -1,6 +1,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff -import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlansByYear +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlans import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.ControlPlanDataOutput import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.tags.Tag @@ -14,17 +14,13 @@ import org.springframework.web.bind.annotation.RestController @RequestMapping("/bff/v1/control_plans") @Tag(name = "Control Plan Themes, SubThemes and tags", description = "API des sous thématiques des plan de contrôle") class ControlPlansController( - private val getControlPlansByYear: GetControlPlansByYear, + private val getControlPlansByYear: GetControlPlans, ) { - @GetMapping("/{year}") - @Operation(summary = "Get control plan themes, subthemes and tags and allowed tags for a given year") - fun getAll( - @PathParam("validity year of the control plan themes") - @PathVariable(name = "year") - year: Int, - ): ControlPlanDataOutput { - val controlPlan = getControlPlansByYear.execute(year) + @GetMapping("/") + @Operation(summary = "Get control plan themes, subthemes and tags and allowed tags") + fun getAll(): ControlPlanDataOutput { + val controlPlan = getControlPlansByYear.execute() return ControlPlanDataOutput.fromControlPlanEntities( themes = controlPlan.first, subThemes = controlPlan.second, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt index 47ce1b298..ef7a79e46 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt @@ -9,7 +9,7 @@ import org.springframework.stereotype.Repository class JpaControlPlanSubThemeRepository( private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, ) : IControlPlanSubThemeRepository { - override fun findByYear(year: Int): List { - return dbControlPlanSubThemeRepository.findByYearOrderById(year).map { it.toControlPlanSubThemeEntity() } + override fun findAll(): List { + return dbControlPlanSubThemeRepository.findAll().map { it.toControlPlanSubThemeEntity() } } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt index 6192c7586..0f444a78e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt @@ -9,7 +9,7 @@ import org.springframework.stereotype.Repository class JpaControlPlanTagRepository( private val dbControlPlanTagRepository: IDBControlPlanTagRepository, ) : IControlPlanTagRepository { - override fun findByYear(year: Int): List { - return dbControlPlanTagRepository.findByYearOrderById(year).map { it.toControlPlanTagEntity() } + override fun findAll(): List { + return dbControlPlanTagRepository.findAll().map { it.toControlPlanTagEntity() } } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt index ee9ef244b..519cb1cd4 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt @@ -9,7 +9,7 @@ import org.springframework.stereotype.Repository class JpaControlPlanThemeRepository( private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, ) : IControlPlanThemeRepository { - override fun findByYear(year: Int): List { - return dbControlPlanThemeRepository.findByYearOrderById(year).map { it.toControlPlanThemeEntity() } + override fun findAll(): List { + return dbControlPlanThemeRepository.findAll().map { it.toControlPlanThemeEntity() } } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt index 21fad8c5e..c04018678 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt @@ -3,6 +3,4 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanSubThemeModel import org.springframework.data.jpa.repository.JpaRepository -interface IDBControlPlanSubThemeRepository : JpaRepository { - fun findByYearOrderById(year: Int): List -} +interface IDBControlPlanSubThemeRepository : JpaRepository diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt index 64edcc252..985ab7e06 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt @@ -4,17 +4,4 @@ import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanTagMode import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query -interface IDBControlPlanTagRepository : JpaRepository { - @Query( - value = """ - SELECT tags.* - FROM control_plan_tags tags, control_plan_sub_themes s, control_plan_themes th - WHERE tags.theme_id = th.id - AND th.id = s.theme_id - AND s.year = :year - ORDER BY tags.id ASC - """, - nativeQuery = true, - ) - fun findByYearOrderById(year: Int): List -} +interface IDBControlPlanTagRepository : JpaRepository diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt index f3bd070af..6b7188779 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt @@ -4,16 +4,4 @@ import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanThemeMo import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query -interface IDBControlPlanThemeRepository : JpaRepository { - @Query( - value = """ - SELECT th.* - FROM control_plan_themes th, control_plan_sub_themes s - WHERE th.id = s.theme_id - AND s.year = :year - ORDER BY th.id ASC - """, - nativeQuery = true, - ) - fun findByYearOrderById(year: Int): List -} +interface IDBControlPlanThemeRepository : JpaRepository diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansUTest.kt similarity index 85% rename from backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt rename to backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansUTest.kt index 54a797616..049ee669c 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansUTest.kt @@ -13,13 +13,13 @@ import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.test.context.junit.jupiter.SpringExtension @ExtendWith(SpringExtension::class) -class GetControlPlansByYearUTest { +class GetControlPlansUTest { @MockBean private lateinit var controlPlanSubThemeRepository: IControlPlanSubThemeRepository private lateinit var controlPlanThemeRepository: IControlPlanThemeRepository private lateinit var controlPlanTagRepository: IControlPlanTagRepository - fun `execute should return all ControlPlanThemes, ControlPlanSubThemes and ControlPlanTags for the given year`() { + fun `execute should return all ControlPlanThemes, ControlPlanSubThemes and ControlPlanTags`() { val controlPlanThemes = listOf( ControlPlanThemeEntity( id = 1, @@ -57,15 +57,15 @@ class GetControlPlansByYearUTest { ), ) - given(controlPlanThemeRepository.findByYear(2023)).willReturn(controlPlanThemes) - given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) - given(controlPlanTagRepository.findByYear(2023)).willReturn(controlPlanTags) + given(controlPlanThemeRepository.findAll()).willReturn(controlPlanThemes) + given(controlPlanSubThemeRepository.findAll()).willReturn(controlPlanSubThemes) + given(controlPlanTagRepository.findAll()).willReturn(controlPlanTags) - val result = GetControlPlansByYear( + val result = GetControlPlans( controlPlanThemeRepository = controlPlanThemeRepository, controlPlanSubThemeRepository = controlPlanSubThemeRepository, controlPlanTagRepository = controlPlanTagRepository, - ).execute(2023) + ).execute() assertThat(result.first.size).isEqualTo(2) assertThat(result).isEqualTo(controlPlanSubThemes) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt index 61eec182a..f9e447c02 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt @@ -5,7 +5,7 @@ import fr.gouv.cacem.monitorenv.config.WebSecurityConfig import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity -import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlansByYear +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlans import org.junit.jupiter.api.Test import org.mockito.BDDMockito import org.springframework.beans.factory.annotation.Autowired @@ -24,7 +24,7 @@ class ControlPlansControllerITests { private lateinit var mockMvc: MockMvc @MockBean - private lateinit var getControlPlansByYear: GetControlPlansByYear + private lateinit var getControlPlans: GetControlPlans @Test fun `Should get all control plan themes`() { @@ -53,9 +53,9 @@ class ControlPlansControllerITests { listOf(controlPlanSubTheme1), listOf(controlPlanTag), ) - BDDMockito.given(getControlPlansByYear.execute(2024)).willReturn(controlPlan) + BDDMockito.given(getControlPlans.execute()).willReturn(controlPlan) // When - mockMvc.perform(get("/bff/v1/control_plans/2024")) + mockMvc.perform(get("/bff/v1/control_plans/")) // Then .andExpect(status().isOk) .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) @@ -67,6 +67,6 @@ class ControlPlansControllerITests { .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) - verify(getControlPlansByYear).execute(2024) + verify(getControlPlans).execute() } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt index 279363026..1ef4eae62 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt @@ -9,19 +9,17 @@ class JpaControlPlanSubThemeRepositoryITests : AbstractDBTests() { private lateinit var jpaControlPlanSubThemeRepository: JpaControlPlanSubThemeRepository @Test - fun `findByYear Should return all control plan theme for a specific year`() { + fun `findAll Should return all control plan subthemes `() { // When - val requestedControlPlanSubThemesFor2023 = jpaControlPlanSubThemeRepository.findByYear(2023) - val requestedControlPlanSubThemesFor2024 = jpaControlPlanSubThemeRepository.findByYear(2024) + val requestedControlPlanSubThemes = jpaControlPlanSubThemeRepository.findAll() // Then - assertThat(requestedControlPlanSubThemesFor2023.size).isEqualTo(83) - assertThat(requestedControlPlanSubThemesFor2024.size).isEqualTo(6) - assertThat(requestedControlPlanSubThemesFor2024[5].id).isEqualTo(89) - assertThat(requestedControlPlanSubThemesFor2024[5].themeId).isEqualTo(11) - assertThat(requestedControlPlanSubThemesFor2024[5].subTheme).isEqualTo( + assertThat(requestedControlPlanSubThemes.size).isEqualTo(6) + assertThat(requestedControlPlanSubThemes[5].id).isEqualTo(6) + assertThat(requestedControlPlanSubThemes[5].themeId).isEqualTo(11) + assertThat(requestedControlPlanSubThemes[5].subTheme).isEqualTo( "Destruction, capture, arrachage", ) - assertThat(requestedControlPlanSubThemesFor2024[5].year).isEqualTo(2024) + assertThat(requestedControlPlanSubThemes[5].year).isEqualTo(2024) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt index 24c364fad..8fc78346a 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt @@ -9,17 +9,15 @@ class JpaControlPlanTagRepositoryITests : AbstractDBTests() { private lateinit var jpaControlPlanTagRepository: JpaControlPlanTagRepository @Test - fun `findByYear Should return all control plan tags for a specific year`() { + fun `findAll Should return all control plan tags`() { // When - val requestedControlPlanTagsFor2023 = jpaControlPlanTagRepository.findByYear(2023) - val requestedControlPlanTagsFor2024 = jpaControlPlanTagRepository.findByYear(2024) + val requestedControlPlanTags = jpaControlPlanTagRepository.findAll() // Then - assertThat(requestedControlPlanTagsFor2023.size).isEqualTo(48) - assertThat(requestedControlPlanTagsFor2024.size).isEqualTo(6) - assertThat(requestedControlPlanTagsFor2024[5].id).isEqualTo(6) - assertThat(requestedControlPlanTagsFor2024[5].themeId).isEqualTo(11) - assertThat(requestedControlPlanTagsFor2024[5].tag).isEqualTo( - "Reptiles", + assertThat(requestedControlPlanTags.size).isEqualTo(6) + assertThat(requestedControlPlanTags[5].id).isEqualTo(6) + assertThat(requestedControlPlanTags[5].themeId).isEqualTo(11) + assertThat(requestedControlPlanTags[5].tag).isEqualTo( + "Mammifères marins", ) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt index 89738672c..04ccc21b9 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt @@ -9,14 +9,12 @@ class JpaControlPlanThemeRepositoryITests : AbstractDBTests() { private lateinit var jpaControlPlanThemeRepository: JpaControlPlanThemeRepository @Test - fun `findByYear Should return all control plan theme for a specific year`() { + fun `findAll Should return all control plan themes`() { // When - val requestedControlPlanThemesFor2023 = jpaControlPlanThemeRepository.findByYear(2023) - val requestedControlPlanThemesFor2024 = jpaControlPlanThemeRepository.findByYear(2024) + val requestedControlPlanThemes = jpaControlPlanThemeRepository.findAll() // Then - assertThat(requestedControlPlanThemesFor2023.size).isEqualTo(83) - assertThat(requestedControlPlanThemesFor2024.size).isEqualTo(6) - assertThat(requestedControlPlanThemesFor2024[5].id).isEqualTo(100002) - assertThat(requestedControlPlanThemesFor2024[5].theme).isEqualTo("Rejet") + assertThat(requestedControlPlanThemes.size).isEqualTo(22) + assertThat(requestedControlPlanThemes[5].id).isEqualTo(6) + assertThat(requestedControlPlanThemes[5].theme).isEqualTo("Divers") } } From 562e0cb3ba397b2a3a496860fda6c1907b38cac0 Mon Sep 17 00:00:00 2001 From: Claire Dagan Date: Thu, 14 Dec 2023 17:37:51 +0100 Subject: [PATCH 19/53] [ControlPlans] re-add api to get control plans by year --- .../IControlPlanSubThemeRepository.kt | 1 + .../repositories/IControlPlanTagRepository.kt | 1 + .../IControlPlanThemeRepository.kt | 1 + .../use_cases/controlPlan/GetControlPlans.kt | 4 +- .../controlPlan/GetControlPlansByYear.kt | 33 +++++ .../endpoints/bff/ControlPlansController.kt | 29 +++- .../JpaControlPlanSubThemeRepository.kt | 5 + .../JpaControlPlanTagRepository.kt | 5 + .../JpaControlPlanThemeRepository.kt | 5 + .../IDBControlPlanSubThemeRepository.kt | 4 +- .../interfaces/IDBControlPlanTagRepository.kt | 17 ++- .../IDBControlPlanThemeRepository.kt | 15 ++- .../controlPlan/GetControlPlansByYearUTest.kt | 77 +++++++++++ .../bff/ControlPlansControllerITests.kt | 125 +++++++++++++----- .../JpaControlPlanSubThemeRepositoryITests.kt | 30 ++++- .../JpaControlPlanTagRepositoryITests.kt | 26 +++- .../JpaControlPlanThemeRepositoryITests.kt | 15 ++- 17 files changed, 343 insertions(+), 50 deletions(-) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt index aba64dc6e..9e5392eda 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanSubThemeRepository.kt @@ -4,4 +4,5 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeE interface IControlPlanSubThemeRepository { fun findAll(): List + fun findByYear(year: Int): List } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt index dae4b69d0..4df23ad13 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanTagRepository.kt @@ -4,4 +4,5 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity interface IControlPlanTagRepository { fun findAll(): List + fun findByYear(year: Int): List } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt index 95e65ed98..413466018 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt @@ -4,4 +4,5 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEnti interface IControlPlanThemeRepository { fun findAll(): List + fun findByYear(year: Int): List } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlans.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlans.kt index 199df21c7..603a5bc3d 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlans.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlans.kt @@ -20,7 +20,9 @@ class GetControlPlans( val controlPlanThemes = controlPlanThemeRepository.findAll() val controlPlanSubThemes = controlPlanSubThemeRepository.findAll() val controlPlanTags = controlPlanTagRepository.findAll() - logger.info("Found ${controlPlanThemes.size} control plan themes, ${controlPlanSubThemes.size} subthemes, and ${controlPlanTags.size} tags ") + logger.info( + "Found ${controlPlanThemes.size} control plan themes, ${controlPlanSubThemes.size} subthemes, and ${controlPlanTags.size} tags ", + ) return Triple(controlPlanThemes, controlPlanSubThemes, controlPlanTags) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt new file mode 100644 index 000000000..9881f6668 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt @@ -0,0 +1,33 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan + +import fr.gouv.cacem.monitorenv.config.UseCase +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanTagRepository +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository +import org.slf4j.LoggerFactory + +@UseCase +class GetControlPlansByYear( + private val controlPlanThemeRepository: IControlPlanThemeRepository, + private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository, + private val controlPlanTagRepository: IControlPlanTagRepository, +) { + private val logger = LoggerFactory.getLogger(GetControlPlansByYear::class.java) + fun execute(year: Int): ControlPlanByYear { + val controlPlanThemes = controlPlanThemeRepository.findByYear(year) + val controlPlanSubThemes = controlPlanSubThemeRepository.findByYear(year) + val controlPlanTags = controlPlanTagRepository.findByYear(year) + logger.info("Found ${controlPlanSubThemes.size} control plan subthemes for year $year") + return Triple(controlPlanThemes, controlPlanSubThemes, controlPlanTags) + } +} + +typealias ControlPlanByYear = + Triple< + List, + List, + List, + > diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt index fa187ebaf..be8dd55c3 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt @@ -1,6 +1,7 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlans +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlansByYear import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.ControlPlanDataOutput import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.tags.Tag @@ -12,15 +13,37 @@ import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/bff/v1/control_plans") -@Tag(name = "Control Plan Themes, SubThemes and tags", description = "API des sous thématiques des plan de contrôle") +@Tag( + name = "Control Plan Themes, SubThemes and tags", + description = "API des sous thématiques des plan de contrôle", +) class ControlPlansController( - private val getControlPlansByYear: GetControlPlans, + private val getControlPlans: GetControlPlans, + private val getControlPlansByYear: GetControlPlansByYear, ) { @GetMapping("/") @Operation(summary = "Get control plan themes, subthemes and tags and allowed tags") fun getAll(): ControlPlanDataOutput { - val controlPlan = getControlPlansByYear.execute() + val controlPlan = getControlPlans.execute() + return ControlPlanDataOutput.fromControlPlanEntities( + themes = controlPlan.first, + subThemes = controlPlan.second, + tags = controlPlan.third, + ) + } + + @GetMapping("/{year}") + @Operation( + summary = + "Get control plan themes, subthemes and tags and allowed tags for a given year", + ) + fun getAll( + @PathParam("validity year of the control plan themes") + @PathVariable(name = "year") + year: Int, + ): ControlPlanDataOutput { + val controlPlan = getControlPlansByYear.execute(year) return ControlPlanDataOutput.fromControlPlanEntities( themes = controlPlan.first, subThemes = controlPlan.second, diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt index ef7a79e46..f73e74ec0 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt @@ -12,4 +12,9 @@ class JpaControlPlanSubThemeRepository( override fun findAll(): List { return dbControlPlanSubThemeRepository.findAll().map { it.toControlPlanSubThemeEntity() } } + override fun findByYear(year: Int): List { + return dbControlPlanSubThemeRepository.findByYearOrderById(year).map { + it.toControlPlanSubThemeEntity() + } + } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt index 0f444a78e..5da1764cc 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt @@ -12,4 +12,9 @@ class JpaControlPlanTagRepository( override fun findAll(): List { return dbControlPlanTagRepository.findAll().map { it.toControlPlanTagEntity() } } + override fun findByYear(year: Int): List { + return dbControlPlanTagRepository.findByYearOrderById(year).map { + it.toControlPlanTagEntity() + } + } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt index 519cb1cd4..1826e74a8 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt @@ -12,4 +12,9 @@ class JpaControlPlanThemeRepository( override fun findAll(): List { return dbControlPlanThemeRepository.findAll().map { it.toControlPlanThemeEntity() } } + override fun findByYear(year: Int): List { + return dbControlPlanThemeRepository.findByYearOrderById(year).map { + it.toControlPlanThemeEntity() + } + } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt index c04018678..21fad8c5e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt @@ -3,4 +3,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanSubThemeModel import org.springframework.data.jpa.repository.JpaRepository -interface IDBControlPlanSubThemeRepository : JpaRepository +interface IDBControlPlanSubThemeRepository : JpaRepository { + fun findByYearOrderById(year: Int): List +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt index 985ab7e06..371bed3fc 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt @@ -4,4 +4,19 @@ import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanTagMode import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query -interface IDBControlPlanTagRepository : JpaRepository +interface IDBControlPlanTagRepository : JpaRepository { + + @Query( + value = + """ + SELECT tags.* + FROM control_plan_tags tags, control_plan_sub_themes s, control_plan_themes th + WHERE tags.theme_id = th.id + AND th.id = s.theme_id + AND s.year = :year + ORDER BY tags.id ASC + """, + nativeQuery = true, + ) + fun findByYearOrderById(year: Int): List +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt index 6b7188779..9de8bb05f 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt @@ -4,4 +4,17 @@ import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanThemeMo import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query -interface IDBControlPlanThemeRepository : JpaRepository +interface IDBControlPlanThemeRepository : JpaRepository { + @Query( + value = + """ + SELECT th.* + FROM control_plan_themes th, control_plan_sub_themes s + WHERE th.id = s.theme_id + AND s.year = :year + ORDER BY th.id ASC + """, + nativeQuery = true, + ) + fun findByYearOrderById(year: Int): List +} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt new file mode 100644 index 000000000..b537b15a1 --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt @@ -0,0 +1,77 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan + +import com.nhaarman.mockitokotlin2.given +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanTagRepository +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.junit.jupiter.SpringExtension + +@ExtendWith(SpringExtension::class) +class GetControlPlansByYearUTest { + @MockBean private lateinit var controlPlanSubThemeRepository: IControlPlanSubThemeRepository + private lateinit var controlPlanThemeRepository: IControlPlanThemeRepository + private lateinit var controlPlanTagRepository: IControlPlanTagRepository + + fun `execute should return all ControlPlanThemes, ControlPlanSubThemes and ControlPlanTags for the given year`() { + val controlPlanThemes = + listOf( + ControlPlanThemeEntity( + id = 1, + theme = "ControlPlanTheme Name", + ), + ControlPlanThemeEntity( + id = 2, + theme = "ControlPlanTheme Name 2", + ), + ) + val controlPlanSubThemes = + listOf( + ControlPlanSubThemeEntity( + id = 1, + themeId = 1, + subTheme = "ControlPlanSubTheme Name", + year = 2023, + ), + ControlPlanSubThemeEntity( + id = 2, + themeId = 1, + subTheme = "ControlPlanSubTheme Name 2", + year = 2023, + ), + ) + val controlPlanTags = + listOf( + ControlPlanTagEntity( + id = 1, + tag = "ControlPlanTag Name", + themeId = 1, + ), + ControlPlanTagEntity( + id = 2, + tag = "ControlPlanTag Name 2", + themeId = 2, + ), + ) + + given(controlPlanThemeRepository.findByYear(2023)).willReturn(controlPlanThemes) + given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) + given(controlPlanTagRepository.findByYear(2023)).willReturn(controlPlanTags) + + val result = + GetControlPlansByYear( + controlPlanThemeRepository = controlPlanThemeRepository, + controlPlanSubThemeRepository = controlPlanSubThemeRepository, + controlPlanTagRepository = controlPlanTagRepository, + ) + .execute(2023) + + assertThat(result.first.size).isEqualTo(2) + assertThat(result).isEqualTo(controlPlanSubThemes) + } +} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt index f9e447c02..76059b4ff 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt @@ -6,6 +6,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeE import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanTagEntity import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlans +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlansByYear import org.junit.jupiter.api.Test import org.mockito.BDDMockito import org.springframework.beans.factory.annotation.Autowired @@ -20,39 +21,44 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status @Import(WebSecurityConfig::class) @WebMvcTest(value = [(ControlPlansController::class)]) class ControlPlansControllerITests { - @Autowired - private lateinit var mockMvc: MockMvc + @Autowired private lateinit var mockMvc: MockMvc - @MockBean - private lateinit var getControlPlans: GetControlPlans + @MockBean private lateinit var getControlPlansByYear: GetControlPlansByYear + + @MockBean private lateinit var getControlPlans: GetControlPlans @Test fun `Should get all control plan themes`() { // Given - val controlPlanTheme1 = ControlPlanThemeEntity( - id = 1, - theme = "Theme Police des mouillages", - ) - val controlPlanTheme2 = ControlPlanThemeEntity( - id = 2, - theme = "Theme Protection des espèces", - ) - val controlPlanSubTheme1 = ControlPlanSubThemeEntity( - id = 10, - themeId = 1, - subTheme = "SubTheme ZMEL", - year = 2024, - ) - val controlPlanTag = ControlPlanTagEntity( - id = 100, - themeId = 2, - tag = "Tag Bichique", - ) - val controlPlan = Triple( - listOf(controlPlanTheme1, controlPlanTheme2), - listOf(controlPlanSubTheme1), - listOf(controlPlanTag), - ) + val controlPlanTheme1 = + ControlPlanThemeEntity( + id = 1, + theme = "Theme Police des mouillages", + ) + val controlPlanTheme2 = + ControlPlanThemeEntity( + id = 2, + theme = "Theme Protection des espèces", + ) + val controlPlanSubTheme1 = + ControlPlanSubThemeEntity( + id = 10, + themeId = 1, + subTheme = "SubTheme ZMEL", + year = 2024, + ) + val controlPlanTag = + ControlPlanTagEntity( + id = 100, + themeId = 2, + tag = "Tag Bichique", + ) + val controlPlan = + Triple( + listOf(controlPlanTheme1, controlPlanTheme2), + listOf(controlPlanSubTheme1), + listOf(controlPlanTag), + ) BDDMockito.given(getControlPlans.execute()).willReturn(controlPlan) // When mockMvc.perform(get("/bff/v1/control_plans/")) @@ -61,12 +67,71 @@ class ControlPlansControllerITests { .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) - .andExpect(jsonPath("$.subThemes[\"10\"].subTheme").value(controlPlanSubTheme1.subTheme)) - .andExpect(jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId)) + .andExpect( + jsonPath("$.subThemes[\"10\"].subTheme") + .value(controlPlanSubTheme1.subTheme), + ) + .andExpect( + jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId), + ) .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) verify(getControlPlans).execute() } + + @Test + fun `Should get all control plan themes by year`() { + // Given + val controlPlanTheme1 = + ControlPlanThemeEntity( + id = 1, + theme = "Theme Police des mouillages", + ) + val controlPlanTheme2 = + ControlPlanThemeEntity( + id = 2, + theme = "Theme Protection des espèces", + ) + val controlPlanSubTheme1 = + ControlPlanSubThemeEntity( + id = 10, + themeId = 1, + subTheme = "SubTheme ZMEL", + year = 2024, + ) + val controlPlanTag = + ControlPlanTagEntity( + id = 100, + themeId = 2, + tag = "Tag Bichique", + ) + val controlPlan = + Triple( + listOf(controlPlanTheme1, controlPlanTheme2), + listOf(controlPlanSubTheme1), + listOf(controlPlanTag), + ) + BDDMockito.given(getControlPlansByYear.execute(2024)).willReturn(controlPlan) + // When + mockMvc.perform(get("/bff/v1/control_plans/2024")) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) + .andExpect( + jsonPath("$.subThemes[\"10\"].subTheme") + .value(controlPlanSubTheme1.subTheme), + ) + .andExpect( + jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId), + ) + .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) + .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) + .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) + + verify(getControlPlansByYear).execute(2024) + } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt index 1ef4eae62..c70f63096 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt @@ -13,13 +13,31 @@ class JpaControlPlanSubThemeRepositoryITests : AbstractDBTests() { // When val requestedControlPlanSubThemes = jpaControlPlanSubThemeRepository.findAll() // Then - assertThat(requestedControlPlanSubThemes.size).isEqualTo(6) + assertThat(requestedControlPlanSubThemes.size).isEqualTo(89) assertThat(requestedControlPlanSubThemes[5].id).isEqualTo(6) - assertThat(requestedControlPlanSubThemes[5].themeId).isEqualTo(11) - assertThat(requestedControlPlanSubThemes[5].subTheme).isEqualTo( - "Destruction, capture, arrachage", - ) + assertThat(requestedControlPlanSubThemes[5].themeId).isEqualTo(4) + assertThat(requestedControlPlanSubThemes[5].subTheme) + .isEqualTo( + "Atteinte aux biens culturels", + ) - assertThat(requestedControlPlanSubThemes[5].year).isEqualTo(2024) + assertThat(requestedControlPlanSubThemes[5].year).isEqualTo(2023) + } + + fun `findByYear Should return all control plan theme for a specific year`() { + // When + val requestedControlPlanSubThemesFor2023 = jpaControlPlanSubThemeRepository.findByYear(2023) + val requestedControlPlanSubThemesFor2024 = jpaControlPlanSubThemeRepository.findByYear(2024) + // Then + assertThat(requestedControlPlanSubThemesFor2023.size).isEqualTo(83) + assertThat(requestedControlPlanSubThemesFor2024.size).isEqualTo(6) + assertThat(requestedControlPlanSubThemesFor2024[5].id).isEqualTo(6) + assertThat(requestedControlPlanSubThemesFor2024[5].themeId).isEqualTo(11) + assertThat(requestedControlPlanSubThemesFor2024[5].subTheme) + .isEqualTo( + "Destruction, capture, arrachage", + ) + + assertThat(requestedControlPlanSubThemesFor2024[5].year).isEqualTo(2024) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt index 8fc78346a..c7e2d2edd 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt @@ -5,8 +5,7 @@ import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired class JpaControlPlanTagRepositoryITests : AbstractDBTests() { - @Autowired - private lateinit var jpaControlPlanTagRepository: JpaControlPlanTagRepository + @Autowired private lateinit var jpaControlPlanTagRepository: JpaControlPlanTagRepository @Test fun `findAll Should return all control plan tags`() { @@ -16,8 +15,25 @@ class JpaControlPlanTagRepositoryITests : AbstractDBTests() { assertThat(requestedControlPlanTags.size).isEqualTo(6) assertThat(requestedControlPlanTags[5].id).isEqualTo(6) assertThat(requestedControlPlanTags[5].themeId).isEqualTo(11) - assertThat(requestedControlPlanTags[5].tag).isEqualTo( - "Mammifères marins", - ) + assertThat(requestedControlPlanTags[5].tag) + .isEqualTo( + "Mammifères marins", + ) + } + + @Test + fun `findByYear Should return all control plan tags for a specific year`() { + // When + val requestedControlPlanTagsFor2023 = jpaControlPlanTagRepository.findByYear(2023) + val requestedControlPlanTagsFor2024 = jpaControlPlanTagRepository.findByYear(2024) + // Then + assertThat(requestedControlPlanTagsFor2023.size).isEqualTo(48) + assertThat(requestedControlPlanTagsFor2024.size).isEqualTo(6) + assertThat(requestedControlPlanTagsFor2024[5].id).isEqualTo(6) + assertThat(requestedControlPlanTagsFor2024[5].themeId).isEqualTo(11) + assertThat(requestedControlPlanTagsFor2024[5].tag) + .isEqualTo( + "Mammifères marins", + ) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt index 04ccc21b9..b5895234f 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt @@ -5,8 +5,7 @@ import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired class JpaControlPlanThemeRepositoryITests : AbstractDBTests() { - @Autowired - private lateinit var jpaControlPlanThemeRepository: JpaControlPlanThemeRepository + @Autowired private lateinit var jpaControlPlanThemeRepository: JpaControlPlanThemeRepository @Test fun `findAll Should return all control plan themes`() { @@ -17,4 +16,16 @@ class JpaControlPlanThemeRepositoryITests : AbstractDBTests() { assertThat(requestedControlPlanThemes[5].id).isEqualTo(6) assertThat(requestedControlPlanThemes[5].theme).isEqualTo("Divers") } + + @Test + fun `findByYear Should return all control plan theme for a specific year`() { + // When + val requestedControlPlanThemesFor2023 = jpaControlPlanThemeRepository.findByYear(2023) + val requestedControlPlanThemesFor2024 = jpaControlPlanThemeRepository.findByYear(2024) + // Then + assertThat(requestedControlPlanThemesFor2023.size).isEqualTo(83) + assertThat(requestedControlPlanThemesFor2024.size).isEqualTo(6) + assertThat(requestedControlPlanThemesFor2024[5].id).isEqualTo(100002) + assertThat(requestedControlPlanThemesFor2024[5].theme).isEqualTo("Rejet") + } } From c9321e89476547637097fcfaa6df8fc38ecd35be Mon Sep 17 00:00:00 2001 From: Claire Dagan Date: Thu, 14 Dec 2023 17:37:51 +0100 Subject: [PATCH 20/53] [ControlPlans] fix controlPlans controller --- .../infrastructure/api/endpoints/bff/ControlPlansController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt index be8dd55c3..11766d42f 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt @@ -38,7 +38,7 @@ class ControlPlansController( summary = "Get control plan themes, subthemes and tags and allowed tags for a given year", ) - fun getAll( + fun getControlPlansByYear( @PathParam("validity year of the control plan themes") @PathVariable(name = "year") year: Int, From eab9818aa57db4fc2f51a941ce0cf739388e831a Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:51 +0100 Subject: [PATCH 21/53] fix after rebase --- .../use_cases/missions/GetMissionsUTests.kt | 155 +++++++++--------- 1 file changed, 82 insertions(+), 73 deletions(-) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissionsUTests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissionsUTests.kt index c68c39b83..dcc399ea3 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissionsUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissionsUTests.kt @@ -1,18 +1,18 @@ package fr.gouv.cacem.monitorenv.domain.use_cases.missions +import com.nhaarman.mockitokotlin2.anyOrNull import com.nhaarman.mockitokotlin2.given -import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionEntity -import fr.gouv.cacem.monitorenv.domain.repositories.IMissionRepository import fr.gouv.cacem.monitorenv.domain.entities.controlUnit.LegacyControlUnitEntity -import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionTypeEnum +import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionSourceEnum -import java.time.ZonedDateTime +import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionTypeEnum +import fr.gouv.cacem.monitorenv.domain.repositories.IMissionRepository import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.test.context.junit.jupiter.SpringExtension -import com.nhaarman.mockitokotlin2.anyOrNull +import java.time.ZonedDateTime @ExtendWith(SpringExtension::class) class GetMissionsUTests { @@ -20,27 +20,27 @@ class GetMissionsUTests { private lateinit var missionRepository: IMissionRepository private val controlUnit1: LegacyControlUnitEntity = LegacyControlUnitEntity( - id = 1, - administration = "whatever", - isArchived = false, - name = "whatever", - resources = listOf(), + id = 1, + administration = "whatever", + isArchived = false, + name = "whatever", + resources = listOf(), ) private val controlUnit2: LegacyControlUnitEntity = LegacyControlUnitEntity( - id = 2, - administration = "whatever", - isArchived = false, - name = "whatever", - resources = listOf(), + id = 2, + administration = "whatever", + isArchived = false, + name = "whatever", + resources = listOf(), ) private val controlUnit3: LegacyControlUnitEntity = LegacyControlUnitEntity( - id = 3, - administration = "whatever", - isArchived = false, - name = "whatever", - resources = listOf(), + id = 3, + administration = "whatever", + isArchived = false, + name = "whatever", + resources = listOf(), ) private val mission1 = @@ -54,7 +54,7 @@ class GetMissionsUTests { hasMissionOrder = false, isUnderJdp = false, isGeometryComputedFromControls = false, - controlUnits = listOf(controlUnit1, controlUnit2) + controlUnits = listOf(controlUnit1, controlUnit2), ) private val mission2 = @@ -68,23 +68,25 @@ class GetMissionsUTests { hasMissionOrder = false, isUnderJdp = false, isGeometryComputedFromControls = false, - controlUnits = listOf(controlUnit1, controlUnit3) + controlUnits = listOf(controlUnit1, controlUnit3), ) @Test fun `execute should return all missions when filter for controlUnits is null`() { - given(missionRepository.findAll( - startedAfter = anyOrNull(), - startedBefore = anyOrNull(), - missionSources = anyOrNull(), - missionTypes = anyOrNull(), - missionStatuses = anyOrNull(), - seaFronts = anyOrNull(), - pageable = anyOrNull(), - )).willReturn(listOf(mission1, mission2)) + given( + missionRepository.findAll( + startedAfter = anyOrNull(), + startedBefore = anyOrNull(), + missionSources = anyOrNull(), + missionTypes = anyOrNull(), + missionStatuses = anyOrNull(), + seaFronts = anyOrNull(), + pageable = anyOrNull(), + ), + ).willReturn(listOf(mission1, mission2)) val result = GetMissions(missionRepository).execute( - controlUnits = null + controlUnits = null, ) assertThat(result.size).isEqualTo(2) @@ -92,18 +94,20 @@ class GetMissionsUTests { @Test fun `execute should return all missions when filter for controlUnits is an empty list`() { - given(missionRepository.findAll( - startedAfter = anyOrNull(), - startedBefore = anyOrNull(), - missionSources = anyOrNull(), - missionTypes = anyOrNull(), - missionStatuses = anyOrNull(), - seaFronts = anyOrNull(), - pageable = anyOrNull(), - )).willReturn(listOf(mission1, mission2)) + given( + missionRepository.findAll( + startedAfter = anyOrNull(), + startedBefore = anyOrNull(), + missionSources = anyOrNull(), + missionTypes = anyOrNull(), + missionStatuses = anyOrNull(), + seaFronts = anyOrNull(), + pageable = anyOrNull(), + ), + ).willReturn(listOf(mission1, mission2)) val result = GetMissions(missionRepository).execute( - controlUnits = listOf() + controlUnits = listOf(), ) assertThat(result.size).isEqualTo(2) @@ -111,18 +115,20 @@ class GetMissionsUTests { @Test fun `execute should only one missions when the controlUnits input matches 1 mission`() { - given(missionRepository.findAll( - startedAfter = anyOrNull(), - startedBefore = anyOrNull(), - missionSources = anyOrNull(), - missionTypes = anyOrNull(), - missionStatuses = anyOrNull(), - seaFronts = anyOrNull(), - pageable = anyOrNull(), - )).willReturn(listOf(mission1, mission2)) + given( + missionRepository.findAll( + startedAfter = anyOrNull(), + startedBefore = anyOrNull(), + missionSources = anyOrNull(), + missionTypes = anyOrNull(), + missionStatuses = anyOrNull(), + seaFronts = anyOrNull(), + pageable = anyOrNull(), + ), + ).willReturn(listOf(mission1, mission2)) val result = GetMissions(missionRepository).execute( - controlUnits = listOf(controlUnit2.id) + controlUnits = listOf(controlUnit2.id), ) assertThat(result.size).isEqualTo(1) @@ -131,18 +137,20 @@ class GetMissionsUTests { @Test fun `execute should only two missions when the same controlUnits input matches 2 missions`() { - given(missionRepository.findAll( - startedAfter = anyOrNull(), - startedBefore = anyOrNull(), - missionSources = anyOrNull(), - missionTypes = anyOrNull(), - missionStatuses = anyOrNull(), - seaFronts = anyOrNull(), - pageable = anyOrNull(), - )).willReturn(listOf(mission1, mission2)) + given( + missionRepository.findAll( + startedAfter = anyOrNull(), + startedBefore = anyOrNull(), + missionSources = anyOrNull(), + missionTypes = anyOrNull(), + missionStatuses = anyOrNull(), + seaFronts = anyOrNull(), + pageable = anyOrNull(), + ), + ).willReturn(listOf(mission1, mission2)) val result = GetMissions(missionRepository).execute( - controlUnits = listOf(controlUnit1.id) + controlUnits = listOf(controlUnit1.id), ) assertThat(result.size).isEqualTo(2) @@ -150,21 +158,22 @@ class GetMissionsUTests { @Test fun `execute should return filtered missions matching multiple controlUnits input`() { - given(missionRepository.findAll( - startedAfter = anyOrNull(), - startedBefore = anyOrNull(), - missionSources = anyOrNull(), - missionTypes = anyOrNull(), - missionStatuses = anyOrNull(), - seaFronts = anyOrNull(), - pageable = anyOrNull(), - )).willReturn(listOf(mission1, mission2)) + given( + missionRepository.findAll( + startedAfter = anyOrNull(), + startedBefore = anyOrNull(), + missionSources = anyOrNull(), + missionTypes = anyOrNull(), + missionStatuses = anyOrNull(), + seaFronts = anyOrNull(), + pageable = anyOrNull(), + ), + ).willReturn(listOf(mission1, mission2)) val result = GetMissions(missionRepository).execute( - controlUnits = listOf(controlUnit2.id, controlUnit3.id) + controlUnits = listOf(controlUnit2.id, controlUnit3.id), ) assertThat(result.size).isEqualTo(2) } - } From bec61cee3f9fc04e45657197345b7db808ba8e90 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Thu, 14 Dec 2023 17:37:51 +0100 Subject: [PATCH 22/53] fix after review --- .../repositories/JpaReportingRepository.kt | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt index 871fba790..059b2a6c7 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt @@ -139,16 +139,29 @@ class JpaReportingRepository( // to simplify the understandability of the code, we do the same steps for creation and update // even if it is not necessary for update // first save (ensure id is set) - val reportingModel = dbReportingRepository.save( - ReportingModel.fromReportingEntity( + var reportingModel: ReportingModel + + if (reporting.id == null) { + reportingModel = dbReportingRepository.save( + ReportingModel.fromReportingEntity( + reporting = reporting, + semaphoreReference = semaphoreReference, + controlUnitReference = controlUnitReference, + missionReference = missionReference, + envActionReference = envActionReference, + controlPlanThemeReference = controlPlanThemeReference, + ), + ) + } else { + reportingModel = ReportingModel.fromReportingEntity( reporting = reporting, semaphoreReference = semaphoreReference, controlUnitReference = controlUnitReference, missionReference = missionReference, envActionReference = envActionReference, controlPlanThemeReference = controlPlanThemeReference, - ), - ) + ) + } // set controlPlanSubThemes and save again (and flush) controlPlanSubThemesReferenceList?.forEach { it -> From 7de92bbffe8a189517346cfdf3b69a352436dcc3 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Wed, 29 Nov 2023 11:45:55 +0100 Subject: [PATCH 23/53] add test for ControlPlanThemesController --- .../endpoints/bff/ControlThemesController.kt | 12 ++--- .../bff/ControlPlanThemesControllerITests.kt | 51 +++++++++++++++++++ 2 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt index fe39e6cb8..73fc7194d 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt @@ -11,13 +11,13 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -@Deprecated("Use ControlPlanSubThemesController instead") +@Deprecated("Use ControlPlanThemesController instead") @RestController @RequestMapping("/bff/v1/controlthemes") @Tag(name = "BFF.Control Themes", description = "API control themes") class ControlThemesController( - private val getAllControlThemes: GetAllControlThemes, - private val getControlThemeById: GetControlThemeById, + private val getAllControlThemes: GetAllControlThemes, + private val getControlThemeById: GetControlThemeById, ) { @GetMapping("") @@ -30,9 +30,9 @@ class ControlThemesController( @GetMapping("/{controlThemeId}") @Operation(summary = "Get regulatory area by Id") fun getControlThemeByIdController( - @PathParam("controlTheme id") - @PathVariable(name = "controlThemeId") - controlThemeId: Int, + @PathParam("controlTheme id") + @PathVariable(name = "controlThemeId") + controlThemeId: Int, ): ControlThemeDataOutput { val controlTheme = getControlThemeById.execute(controlThemeId = controlThemeId) return ControlThemeDataOutput.fromControlThemeEntity(controlTheme) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt new file mode 100644 index 000000000..35c99e37e --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt @@ -0,0 +1,51 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff + +import com.nhaarman.mockitokotlin2.verify +import fr.gouv.cacem.monitorenv.config.WebSecurityConfig +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanThemes.GetControlPlanThemesByYear +import org.junit.jupiter.api.Test +import org.mockito.BDDMockito +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.context.annotation.Import +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status + +@Import(WebSecurityConfig::class) +@WebMvcTest(value = [(ControlPlanThemesController::class)]) +class ControlPlanThemesControllerITests { + @Autowired + private lateinit var mockMvc: MockMvc + + @MockBean + private lateinit var getControlPlanThemesByYear: GetControlPlanThemesByYear + + @Test + fun `Should get all control plan themes`() { + // Given + val controlPlanTheme = ControlPlanThemeEntity( + id = 1, + theme = "Theme Police des mouillages", + subTheme = "Sous Theme Mouillage individuel", + allowedTags = listOf("tag1", "tag2"), + year = 2024, + ) + BDDMockito.given(getControlPlanThemesByYear.execute(2024)).willReturn(listOf(controlPlanTheme)) + // When + mockMvc.perform(get("/bff/v1/controlplanthemes/2024")) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$[0].id").value(controlPlanTheme.id)) + .andExpect(jsonPath("$[0].theme").value(controlPlanTheme.theme)) + .andExpect(jsonPath("$[0].subTheme").value(controlPlanTheme.subTheme)) + .andExpect(jsonPath("$[0].year").value(controlPlanTheme.year)) + .andExpect(jsonPath("$[0].allowedTags[0]").value(controlPlanTheme.allowedTags?.get(0))) + .andExpect(jsonPath("$[0].allowedTags[1]").value(controlPlanTheme.allowedTags?.get(1))) + + verify(getControlPlanThemesByYear).execute(2024) + } +} From 86b54941bcf6ac322e6875a6d8445c46e18d04fb Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Fri, 1 Dec 2023 14:58:31 +0100 Subject: [PATCH 24/53] wip --- .../EnvActionControlPlanSubThemeEntity.kt | 8 + .../mission/envAction/EnvActionEntity.kt | 40 +-- .../mission/envAction/EnvActionNoteEntity.kt | 14 +- .../envAction/EnvActionNoteProperties.kt | 22 +- .../envAction/EnvActionSurveillanceEntity.kt | 31 +- .../EnvActionSurveillanceProperties.kt | 57 ++-- .../EnvActionControlEntity.kt | 45 ++- .../EnvActionControlProperties.kt | 93 +++--- .../domain/mappers/EnvActionMapper.kt | 140 ++++----- .../IControlPlanThemeRepository.kt | 8 - .../GetControlPlanSubThemesByYear.kt | 16 + .../missions/MissionEnvActionDataInput.kt | 152 +++++----- .../outputs/ControlPlanSubThemeDataOutput.kt | 20 +- .../bff/outputs/ControlPlanThemeDataOutput.kt | 19 -- .../MissionEnvActionControlDataOutput.kt | 108 +++---- .../MissionEnvActionSubThemeDataOutput.kt | 22 ++ .../endpoints/bff/ControlThemesController.kt | 2 +- .../model/ControlPlanSubThemeModel.kt | 39 ++- .../database/model/EnvActionModel.kt | 273 +++++++++--------- .../database/model/EnvActionsSubThemeModel.kt | 68 +++++ .../JpaControlPlanSubThemeRepository.kt | 2 +- .../JpaControlPlanThemeRepository.kt | 20 -- .../IDBControlPlanSubThemeRepository.kt | 7 - .../IDBControlPlanThemeRepository.kt | 20 -- .../GetControlPlanSubThemesByYearUTest.kt | 41 +++ ...> ControlPlanSubThemesControllerITests.kt} | 30 +- .../JpaControlPlanSubThemeRepositoryITests.kt | 12 +- .../JpaControlPlanThemeRepositoryITests.kt | 31 -- 28 files changed, 692 insertions(+), 648 deletions(-) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt rename backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/{ControlPlanThemesControllerITests.kt => ControlPlanSubThemesControllerITests.kt} (50%) delete mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt new file mode 100644 index 000000000..2fb3ef3ad --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt @@ -0,0 +1,8 @@ +package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction + +data class EnvActionControlPlanSubThemeEntity( + val subThemeId: Int, + val tags: List, + val theme: String, + val subTheme: String, +) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt index 13219a9a5..5b6f86efc 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt @@ -3,32 +3,32 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity -import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.UUID +import org.locationtech.jts.geom.Geometry @JsonTypeInfo( - use = JsonTypeInfo.Id.NAME, - include = JsonTypeInfo.As.PROPERTY, - property = "actionType", - visible = true, + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "actionType", + visible = true, ) @JsonSubTypes( - JsonSubTypes.Type(EnvActionControlEntity::class, name = "CONTROL"), - JsonSubTypes.Type(EnvActionSurveillanceEntity::class, name = "SURVEILLANCE"), - JsonSubTypes.Type(EnvActionNoteEntity::class, name = "NOTE"), + JsonSubTypes.Type(EnvActionControlEntity::class, name = "CONTROL"), + JsonSubTypes.Type(EnvActionSurveillanceEntity::class, name = "SURVEILLANCE"), + JsonSubTypes.Type(EnvActionNoteEntity::class, name = "NOTE"), ) abstract class EnvActionEntity( - open val id: UUID, - open val actionType: ActionTypeEnum, - open val actionEndDateTimeUtc: ZonedDateTime? = null, - open val actionStartDateTimeUtc: ZonedDateTime? = null, - open val controlPlans: List? = listOf(), - open val department: String? = null, - open val facade: String? = null, - open val geom: Geometry? = null, - open val isAdministrativeControl: Boolean? = null, - open val isComplianceWithWaterRegulationsControl: Boolean? = null, - open val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - open val isSeafarersControl: Boolean? = null, + open val id: UUID, + open val actionType: ActionTypeEnum, + open val actionEndDateTimeUtc: ZonedDateTime? = null, + open val actionStartDateTimeUtc: ZonedDateTime? = null, + open val controlPlans: List? = listOf(), + open val department: String? = null, + open val facade: String? = null, + open val geom: Geometry? = null, + open val isAdministrativeControl: Boolean? = null, + open val isComplianceWithWaterRegulationsControl: Boolean? = null, + open val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, + open val isSeafarersControl: Boolean? = null, ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteEntity.kt index ad79ba695..f3223c098 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteEntity.kt @@ -4,11 +4,11 @@ import java.time.ZonedDateTime import java.util.UUID data class EnvActionNoteEntity( - override val id: UUID, - override val actionStartDateTimeUtc: ZonedDateTime? = null, - val observations: String? = null, + override val id: UUID, + override val actionStartDateTimeUtc: ZonedDateTime? = null, + val observations: String? = null, ) : - EnvActionEntity( - actionType = ActionTypeEnum.NOTE, - id = id, - ) + EnvActionEntity( + actionType = ActionTypeEnum.NOTE, + id = id, + ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteProperties.kt index 36d6f9cde..8077d8d4a 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteProperties.kt @@ -4,21 +4,21 @@ import java.time.ZonedDateTime import java.util.* data class EnvActionNoteProperties( - val observations: String? = null, + val observations: String? = null, ) { fun toEnvActionNoteEntity( - id: UUID, - actionStartDateTimeUtc: ZonedDateTime?, + id: UUID, + actionStartDateTimeUtc: ZonedDateTime?, ) = - EnvActionNoteEntity( - id = id, - actionStartDateTimeUtc = actionStartDateTimeUtc, - observations = observations, - ) + EnvActionNoteEntity( + id = id, + actionStartDateTimeUtc = actionStartDateTimeUtc, + observations = observations, + ) companion object { fun fromEnvActionNoteEntity(envAction: EnvActionNoteEntity) = - EnvActionNoteProperties( - envAction.observations, - ) + EnvActionNoteProperties( + envAction.observations, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt index c83fb749e..10c288ec3 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt @@ -1,23 +1,22 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction -import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.UUID +import org.locationtech.jts.geom.Geometry data class EnvActionSurveillanceEntity( - override val id: UUID, - override val actionEndDateTimeUtc: ZonedDateTime? = null, - override val actionStartDateTimeUtc: ZonedDateTime? = null, - override val controlPlans: List? = listOf(), - override val geom: Geometry? = null, - override val facade: String? = null, - override val department: String? = null, - val coverMissionZone: Boolean? = null, - val observations: String? = null, - @Deprecated("Use controlPlan instead") - val themes: List? = listOf(), + override val id: UUID, + override val actionEndDateTimeUtc: ZonedDateTime? = null, + override val actionStartDateTimeUtc: ZonedDateTime? = null, + override val controlPlans: List? = listOf(), + override val geom: Geometry? = null, + override val facade: String? = null, + override val department: String? = null, + val coverMissionZone: Boolean? = null, + val observations: String? = null, + @Deprecated("Use controlPlan instead") val themes: List? = listOf(), ) : - EnvActionEntity( - actionType = ActionTypeEnum.SURVEILLANCE, - id = id, - ) + EnvActionEntity( + actionType = ActionTypeEnum.SURVEILLANCE, + id = id, + ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt index cfbf8e524..a3af9484d 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt @@ -1,42 +1,41 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction -import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.* +import org.locationtech.jts.geom.Geometry data class EnvActionSurveillanceProperties( - val coverMissionZone: Boolean? = null, - val observations: String? = null, - @Deprecated("Use controlPlans instead") - val themes: List? = listOf(), + val coverMissionZone: Boolean? = null, + val observations: String? = null, + @Deprecated("Use controlPlans instead") val themes: List? = listOf(), ) { fun toEnvActionSurveillanceEntity( - id: UUID, - actionStartDateTimeUtc: ZonedDateTime?, - actionEndDateTimeUtc: ZonedDateTime?, - controlPlans: List?, - department: String?, - facade: String?, - geom: Geometry?, + id: UUID, + actionStartDateTimeUtc: ZonedDateTime?, + actionEndDateTimeUtc: ZonedDateTime?, + controlPlans: List?, + department: String?, + facade: String?, + geom: Geometry?, ) = - EnvActionSurveillanceEntity( - id = id, - actionStartDateTimeUtc = actionStartDateTimeUtc, - actionEndDateTimeUtc = actionEndDateTimeUtc, - controlPlans = controlPlans, - coverMissionZone = coverMissionZone, - department = department, - facade = facade, - geom = geom, - observations = observations, - themes = themes, - ) + EnvActionSurveillanceEntity( + id = id, + actionStartDateTimeUtc = actionStartDateTimeUtc, + actionEndDateTimeUtc = actionEndDateTimeUtc, + controlPlans = controlPlans, + coverMissionZone = coverMissionZone, + department = department, + facade = facade, + geom = geom, + observations = observations, + themes = themes, + ) companion object { fun fromEnvActionSurveillanceEntity(envAction: EnvActionSurveillanceEntity) = - EnvActionSurveillanceProperties( - coverMissionZone = envAction.coverMissionZone, - observations = envAction.observations, - themes = envAction.themes, - ) + EnvActionSurveillanceProperties( + coverMissionZone = envAction.coverMissionZone, + observations = envAction.observations, + themes = envAction.themes, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt index 2a9fa4dec..fb52b98c7 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt @@ -6,31 +6,30 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionContr import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.InfractionEntity -import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.UUID +import org.locationtech.jts.geom.Geometry data class EnvActionControlEntity( - override val id: UUID, - override val actionEndDateTimeUtc: ZonedDateTime? = null, - override val actionStartDateTimeUtc: ZonedDateTime? = null, - override val controlPlans: List? = listOf(), - override val department: String? = null, - override val facade: String? = null, - override val geom: Geometry? = null, - override val isAdministrativeControl: Boolean? = null, - override val isComplianceWithWaterRegulationsControl: Boolean? = null, - override val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - override val isSeafarersControl: Boolean? = null, - val actionNumberOfControls: Int? = null, - val actionTargetType: ActionTargetTypeEnum? = null, - val infractions: List? = listOf(), - val observations: String? = null, - @Deprecated("Use controlPlan instead") - val themes: List? = listOf(), - val vehicleType: VehicleTypeEnum? = null, + override val id: UUID, + override val actionEndDateTimeUtc: ZonedDateTime? = null, + override val actionStartDateTimeUtc: ZonedDateTime? = null, + override val controlPlans: List? = listOf(), + override val department: String? = null, + override val facade: String? = null, + override val geom: Geometry? = null, + override val isAdministrativeControl: Boolean? = null, + override val isComplianceWithWaterRegulationsControl: Boolean? = null, + override val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, + override val isSeafarersControl: Boolean? = null, + val actionNumberOfControls: Int? = null, + val actionTargetType: ActionTargetTypeEnum? = null, + val infractions: List? = listOf(), + val observations: String? = null, + @Deprecated("Use controlPlan instead") val themes: List? = listOf(), + val vehicleType: VehicleTypeEnum? = null, ) : - EnvActionEntity( - id = id, - actionType = ActionTypeEnum.CONTROL, - ) + EnvActionEntity( + id = id, + actionType = ActionTypeEnum.CONTROL, + ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt index de2128807..aaeb43e46 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt @@ -4,61 +4,62 @@ import fr.gouv.cacem.monitorenv.domain.entities.VehicleTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.InfractionEntity -import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.UUID +import org.locationtech.jts.geom.Geometry data class EnvActionControlProperties( - val actionNumberOfControls: Int? = null, - val actionTargetType: ActionTargetTypeEnum? = null, - val infractions: List? = listOf(), - val observations: String? = null, - @Deprecated("Use controlPlans instead") - val themes: List? = listOf(), - val vehicleType: VehicleTypeEnum? = null, + val actionNumberOfControls: Int? = null, + val actionTargetType: ActionTargetTypeEnum? = null, + val infractions: List? = listOf(), + val observations: String? = null, + @Deprecated("Use controlPlans instead") val themes: List? = listOf(), + val vehicleType: VehicleTypeEnum? = null, ) { fun toEnvActionControlEntity( - id: UUID, - actionEndDateTimeUtc: ZonedDateTime?, - actionStartDateTimeUtc: ZonedDateTime?, - controlPlans: List?, - department: String?, - facade: String?, - geom: Geometry?, - isAdministrativeControl: Boolean?, - isComplianceWithWaterRegulationsControl: Boolean?, - isSafetyEquipmentAndStandardsComplianceControl: Boolean?, - isSeafarersControl: Boolean?, + id: UUID, + actionEndDateTimeUtc: ZonedDateTime?, + actionStartDateTimeUtc: ZonedDateTime?, + controlPlans: List?, + department: String?, + facade: String?, + geom: Geometry?, + isAdministrativeControl: Boolean?, + isComplianceWithWaterRegulationsControl: Boolean?, + isSafetyEquipmentAndStandardsComplianceControl: Boolean?, + isSeafarersControl: Boolean?, ) = - EnvActionControlEntity( - id = id, - actionEndDateTimeUtc = actionEndDateTimeUtc, - actionNumberOfControls = actionNumberOfControls, - actionStartDateTimeUtc = actionStartDateTimeUtc, - actionTargetType = actionTargetType, - controlPlans = controlPlans, - department = department, - facade = facade, - geom = geom, - infractions = infractions, - isAdministrativeControl = isAdministrativeControl, - isComplianceWithWaterRegulationsControl = isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = isSeafarersControl, - observations = observations, - themes = themes, - vehicleType = vehicleType, - ) + EnvActionControlEntity( + id = id, + actionEndDateTimeUtc = actionEndDateTimeUtc, + actionNumberOfControls = actionNumberOfControls, + actionStartDateTimeUtc = actionStartDateTimeUtc, + actionTargetType = actionTargetType, + controlPlans = controlPlans, + department = department, + facade = facade, + geom = geom, + infractions = infractions, + isAdministrativeControl = isAdministrativeControl, + isComplianceWithWaterRegulationsControl = + isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = isSeafarersControl, + observations = observations, + themes = themes, + vehicleType = vehicleType, + ) companion object { fun fromEnvActionControlEntity(envAction: EnvActionControlEntity) = - EnvActionControlProperties( - actionNumberOfControls = envAction.actionNumberOfControls, - actionTargetType = envAction.actionTargetType, - infractions = envAction.infractions, - observations = envAction.observations, - themes = envAction.themes, - vehicleType = envAction.vehicleType, - ) + EnvActionControlProperties( + actionNumberOfControls = envAction.actionNumberOfControls, + actionTargetType = envAction.actionTargetType, + infractions = envAction.infractions, + observations = envAction.observations, + themes = envAction.themes, + vehicleType = envAction.vehicleType, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt index dbed39f51..314c618d6 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt @@ -11,75 +11,77 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionSurve import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlProperties import fr.gouv.cacem.monitorenv.domain.exceptions.EntityConversionException -import org.locationtech.jts.geom.Geometry -import org.springframework.stereotype.Component import java.time.ZonedDateTime import java.util.UUID +import org.locationtech.jts.geom.Geometry +import org.springframework.stereotype.Component @Component object EnvActionMapper { private const val jsonbNullString = "null" fun getEnvActionEntityFromJSON( - mapper: ObjectMapper, - id: UUID, - actionEndDateTimeUtc: ZonedDateTime?, - actionType: ActionTypeEnum, - actionStartDateTimeUtc: ZonedDateTime?, - controlPlans: List?, - department: String?, - facade: String?, - geom: Geometry?, - isAdministrativeControl: Boolean?, - isComplianceWithWaterRegulationsControl: Boolean?, - isSafetyEquipmentAndStandardsComplianceControl: Boolean?, - isSeafarersControl: Boolean?, - value: String?, + mapper: ObjectMapper, + id: UUID, + actionEndDateTimeUtc: ZonedDateTime?, + actionType: ActionTypeEnum, + actionStartDateTimeUtc: ZonedDateTime?, + controlPlans: List?, + department: String?, + facade: String?, + geom: Geometry?, + isAdministrativeControl: Boolean?, + isComplianceWithWaterRegulationsControl: Boolean?, + isSafetyEquipmentAndStandardsComplianceControl: Boolean?, + isSeafarersControl: Boolean?, + value: String?, ): EnvActionEntity { return try { if (!value.isNullOrEmpty() && value != jsonbNullString) { when (actionType) { ActionTypeEnum.SURVEILLANCE -> - mapper.readValue( - value, - EnvActionSurveillanceProperties::class.java, - ) - .toEnvActionSurveillanceEntity( - id = id, - actionEndDateTimeUtc = actionEndDateTimeUtc, - actionStartDateTimeUtc = actionStartDateTimeUtc, - controlPlans = controlPlans, - department = department, - facade = facade, - geom = geom, - ) + mapper.readValue( + value, + EnvActionSurveillanceProperties::class.java, + ) + .toEnvActionSurveillanceEntity( + id = id, + actionEndDateTimeUtc = actionEndDateTimeUtc, + actionStartDateTimeUtc = actionStartDateTimeUtc, + controlPlans = controlPlans, + department = department, + facade = facade, + geom = geom, + ) ActionTypeEnum.CONTROL -> - mapper.readValue( - value, - EnvActionControlProperties::class.java, - ) - .toEnvActionControlEntity( - id = id, - actionEndDateTimeUtc = actionEndDateTimeUtc, - actionStartDateTimeUtc = actionStartDateTimeUtc, - controlPlans = controlPlans, - department = department, - facade = facade, - geom = geom, - isAdministrativeControl = isAdministrativeControl, - isComplianceWithWaterRegulationsControl = isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = isSeafarersControl, - ) + mapper.readValue( + value, + EnvActionControlProperties::class.java, + ) + .toEnvActionControlEntity( + id = id, + actionEndDateTimeUtc = actionEndDateTimeUtc, + actionStartDateTimeUtc = actionStartDateTimeUtc, + controlPlans = controlPlans, + department = department, + facade = facade, + geom = geom, + isAdministrativeControl = isAdministrativeControl, + isComplianceWithWaterRegulationsControl = + isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = isSeafarersControl, + ) ActionTypeEnum.NOTE -> - mapper.readValue( - value, - EnvActionNoteProperties::class.java, - ) - .toEnvActionNoteEntity( - id = id, - actionStartDateTimeUtc = actionStartDateTimeUtc, - ) + mapper.readValue( + value, + EnvActionNoteProperties::class.java, + ) + .toEnvActionNoteEntity( + id = id, + actionStartDateTimeUtc = actionStartDateTimeUtc, + ) } } else { throw EntityConversionException("No action value found.") @@ -93,23 +95,23 @@ object EnvActionMapper { return try { when (envAction.actionType) { ActionTypeEnum.SURVEILLANCE -> - mapper.writeValueAsString( - EnvActionSurveillanceProperties.fromEnvActionSurveillanceEntity( - envAction as EnvActionSurveillanceEntity, - ), - ) + mapper.writeValueAsString( + EnvActionSurveillanceProperties.fromEnvActionSurveillanceEntity( + envAction as EnvActionSurveillanceEntity, + ), + ) ActionTypeEnum.CONTROL -> - mapper.writeValueAsString( - EnvActionControlProperties.fromEnvActionControlEntity( - envAction as EnvActionControlEntity, - ), - ) + mapper.writeValueAsString( + EnvActionControlProperties.fromEnvActionControlEntity( + envAction as EnvActionControlEntity, + ), + ) ActionTypeEnum.NOTE -> - mapper.writeValueAsString( - EnvActionNoteProperties.fromEnvActionNoteEntity( - envAction as EnvActionNoteEntity, - ), - ) + mapper.writeValueAsString( + EnvActionNoteProperties.fromEnvActionNoteEntity( + envAction as EnvActionNoteEntity, + ), + ) } } catch (e: Exception) { throw EntityConversionException("Error while converting action to json $envAction", e) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt deleted file mode 100644 index 413466018..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.repositories - -import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity - -interface IControlPlanThemeRepository { - fun findAll(): List - fun findByYear(year: Int): List -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt new file mode 100644 index 000000000..a1d2b4309 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt @@ -0,0 +1,16 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes + +import fr.gouv.cacem.monitorenv.config.UseCase +import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository +import org.slf4j.LoggerFactory + +@UseCase +class GetControlPlanSubThemesByYear(private val ControlPlanSubThemeRepository: IControlPlanSubThemeRepository) { + private val logger = LoggerFactory.getLogger(GetControlPlanSubThemesByYear::class.java) + fun execute(year: Int): List { + val ControlPlanSubThemes = ControlPlanSubThemeRepository.findByYear(year) + logger.info("Found ${ControlPlanSubThemes.size} control plan (sub)themes for year $year") + return ControlPlanSubThemes + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt index 7ed1ddc0d..7cae0a424 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt @@ -8,59 +8,57 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionSurve import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.ActionTargetTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity -import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.Optional import java.util.UUID +import org.locationtech.jts.geom.Geometry data class MissionEnvActionDataInput( - val id: UUID, - val actionType: ActionTypeEnum, - val actionStartDateTimeUtc: ZonedDateTime? = null, + val id: UUID, + val actionType: ActionTypeEnum, + val actionStartDateTimeUtc: ZonedDateTime? = null, - // Common to all action Types - val observations: String? = null, + // Common to all action Types + val observations: String? = null, - // EnvActionControl + EnvSurveillance Properties - val actionEndDateTimeUtc: ZonedDateTime? = null, - val controlPlans: List? = null, + // EnvActionControl + EnvSurveillance Properties + val actionEndDateTimeUtc: ZonedDateTime? = null, + val controlPlans: List? = null, + @Deprecated("Use controlPlans instead") val themes: List? = null, + val department: String? = null, + val facade: String? = null, + val geom: Geometry? = null, - @Deprecated("Use controlPlans instead") - val themes: List? = null, - val department: String? = null, - val facade: String? = null, - val geom: Geometry? = null, + // EnvActionControl Properties + val actionNumberOfControls: Int? = null, + val actionTargetType: ActionTargetTypeEnum? = null, + val vehicleType: VehicleTypeEnum? = null, + val infractions: List? = listOf(), + val isAdministrativeControl: Boolean? = null, + val isComplianceWithWaterRegulationsControl: Boolean? = null, + val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, + val isSeafarersControl: Boolean? = null, - // EnvActionControl Properties - val actionNumberOfControls: Int? = null, - val actionTargetType: ActionTargetTypeEnum? = null, - val vehicleType: VehicleTypeEnum? = null, - val infractions: List? = listOf(), - val isAdministrativeControl: Boolean? = null, - val isComplianceWithWaterRegulationsControl: Boolean? = null, - val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - val isSeafarersControl: Boolean? = null, + // EnvActionSurveillance Properties + val coverMissionZone: Boolean? = null, - // EnvActionSurveillance Properties - val coverMissionZone: Boolean? = null, - - // complementary properties - val reportingIds: Optional>, + // complementary properties + val reportingIds: Optional>, ) { fun validate() { when (actionType) { ActionTypeEnum.CONTROL -> - require(this.reportingIds.isPresent && this.reportingIds.get().size < 2) { - "ReportingIds must not be null and maximum 1 id for Controls" - } + require(this.reportingIds.isPresent && this.reportingIds.get().size < 2) { + "ReportingIds must not be null and maximum 1 id for Controls" + } ActionTypeEnum.SURVEILLANCE -> - require(this.reportingIds.isPresent) { - "ReportingIds must not be null for Surveillance Action" - } + require(this.reportingIds.isPresent) { + "ReportingIds must not be null for Surveillance Action" + } ActionTypeEnum.NOTE -> - require( - !this.reportingIds.isPresent, - ) { "ReportingIds must not be present for Notes" } + require( + !this.reportingIds.isPresent, + ) { "ReportingIds must not be present for Notes" } } } @@ -69,47 +67,51 @@ data class MissionEnvActionDataInput( when (this.actionType) { ActionTypeEnum.CONTROL -> - return EnvActionControlEntity( - id = this.id, - actionEndDateTimeUtc = this.actionEndDateTimeUtc, - actionNumberOfControls = this.actionNumberOfControls, - actionTargetType = this.actionTargetType, - actionStartDateTimeUtc = this.actionStartDateTimeUtc, - controlPlans = this.controlPlans?.map { it.toEnvActionControlPlanEntity() }, - department = this.department, - facade = this.facade, - geom = this.geom, - infractions = this.infractions?.map { it.toInfractionEntity() }, - isAdministrativeControl = this.isAdministrativeControl, - isComplianceWithWaterRegulationsControl = - this.isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - this.isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = this.isSeafarersControl, - observations = this.observations, - themes = this.themes, - vehicleType = this.vehicleType, - ) + return EnvActionControlEntity( + id = this.id, + actionEndDateTimeUtc = this.actionEndDateTimeUtc, + actionNumberOfControls = this.actionNumberOfControls, + actionTargetType = this.actionTargetType, + actionStartDateTimeUtc = this.actionStartDateTimeUtc, + controlPlans = + this.controlPlans?.map { it.toEnvActionControlPlanEntity() }, + department = this.department, + facade = this.facade, + geom = this.geom, + infractions = this.infractions?.map { it.toInfractionEntity() }, + isAdministrativeControl = this.isAdministrativeControl, + isComplianceWithWaterRegulationsControl = + this.isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + this.isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = this.isSeafarersControl, + observations = this.observations, + themes = this.themes, + vehicleType = this.vehicleType, + ) ActionTypeEnum.SURVEILLANCE -> - return EnvActionSurveillanceEntity( - id = this.id, - actionStartDateTimeUtc = this.actionStartDateTimeUtc, - actionEndDateTimeUtc = this.actionEndDateTimeUtc, - controlPlans = this.controlPlans?.map { it.toEnvActionControlPlanEntity() }, - department = this.department, - facade = this.facade, - geom = this.geom, - themes = this.themes, - coverMissionZone = this.coverMissionZone, - observations = this.observations, - ) + return EnvActionSurveillanceEntity( + id = this.id, + actionStartDateTimeUtc = this.actionStartDateTimeUtc, + actionEndDateTimeUtc = this.actionEndDateTimeUtc, + controlPlans = + this.controlPlans?.map { it.toEnvActionControlPlanEntity() }, + department = this.department, + facade = this.facade, + geom = this.geom, + themes = this.themes, + coverMissionZone = this.coverMissionZone, + observations = this.observations, + ) ActionTypeEnum.NOTE -> - return EnvActionNoteEntity( - id = this.id, - actionStartDateTimeUtc = this.actionStartDateTimeUtc, - observations = this.observations, - ) + return EnvActionNoteEntity( + id = this.id, + actionStartDateTimeUtc = this.actionStartDateTimeUtc, + observations = this.observations, + ) else -> throw Exception("Action type not supported") } } } + +typealias ControlPlanSubThemeDataInput = Pair> diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt index 2c5ce4f14..f032df8ab 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt @@ -3,18 +3,18 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity data class ControlPlanSubThemeDataOutput( - val id: Int, - val themeId: Int, - val subTheme: String, - val year: Int, + val id: Int, + val themeId: Int, + val subTheme: String, + val year: Int, ) { companion object { fun fromControlPlanSubThemeEntity(controlPlanSubTheme: ControlPlanSubThemeEntity) = - ControlPlanSubThemeDataOutput( - id = controlPlanSubTheme.id, - themeId = controlPlanSubTheme.themeId, - subTheme = controlPlanSubTheme.subTheme, - year = controlPlanSubTheme.year, - ) + ControlPlanSubThemeDataOutput( + id = controlPlanSubTheme.id, + themeId = controlPlanSubTheme.themeId, + subTheme = controlPlanSubTheme.subTheme, + year = controlPlanSubTheme.year, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt deleted file mode 100644 index 53a22bfc0..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt +++ /dev/null @@ -1,19 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs - -import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity - -data class ControlPlanThemeDataOutput( - val id: Int, - val theme: String, -) { - companion object { - fun fromControlPlanThemeEntity( - controlPlanThemeEntity: ControlPlanThemeEntity, - ): ControlPlanThemeDataOutput { - return ControlPlanThemeDataOutput( - id = controlPlanThemeEntity.id, - theme = controlPlanThemeEntity.theme, - ) - } - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt index b5a2286b7..9615de67e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt @@ -6,66 +6,68 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.ActionTargetTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.InfractionEntity -import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.UUID +import org.locationtech.jts.geom.Geometry data class MissionEnvActionControlDataOutput( - override val id: UUID, - val actionEndDateTimeUtc: ZonedDateTime? = null, - val actionNumberOfControls: Int? = null, - override val actionStartDateTimeUtc: ZonedDateTime? = null, - val actionTargetType: ActionTargetTypeEnum? = null, - override val actionType: ActionTypeEnum = ActionTypeEnum.CONTROL, - val controlPlans: List? = listOf(), - val department: String? = null, - val facade: String? = null, - val geom: Geometry? = null, - val infractions: List? = listOf(), - val isAdministrativeControl: Boolean? = null, - val isComplianceWithWaterRegulationsControl: Boolean? = null, - val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - val isSeafarersControl: Boolean? = null, - val observations: String? = null, - val reportingIds: List, - @Deprecated("Use controlPlans instead") - val themes: List? = listOf(), - val vehicleType: VehicleTypeEnum? = null, + override val id: UUID, + val actionEndDateTimeUtc: ZonedDateTime? = null, + val actionNumberOfControls: Int? = null, + override val actionStartDateTimeUtc: ZonedDateTime? = null, + val actionTargetType: ActionTargetTypeEnum? = null, + override val actionType: ActionTypeEnum = ActionTypeEnum.CONTROL, + val controlPlans: List? = listOf(), + val department: String? = null, + val facade: String? = null, + val geom: Geometry? = null, + val infractions: List? = listOf(), + val isAdministrativeControl: Boolean? = null, + val isComplianceWithWaterRegulationsControl: Boolean? = null, + val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, + val isSeafarersControl: Boolean? = null, + val observations: String? = null, + val reportingIds: List, + @Deprecated("Use controlPlans instead") val themes: List? = listOf(), + val controlPlanSubThemes: List? = listOf(), + val vehicleType: VehicleTypeEnum? = null, ) : - MissionEnvActionDataOutput( - id = id, - actionStartDateTimeUtc = actionStartDateTimeUtc, - actionType = ActionTypeEnum.CONTROL, - ) { + MissionEnvActionDataOutput( + id = id, + actionStartDateTimeUtc = actionStartDateTimeUtc, + actionType = ActionTypeEnum.CONTROL, + ) { companion object { fun fromEnvActionControlEntity( - envActionControlEntity: EnvActionControlEntity, - reportingIds: List, + envActionControlEntity: EnvActionControlEntity, + reportingIds: List, ) = - MissionEnvActionControlDataOutput( - id = envActionControlEntity.id, - actionNumberOfControls = envActionControlEntity.actionNumberOfControls, - actionStartDateTimeUtc = envActionControlEntity.actionStartDateTimeUtc, - actionEndDateTimeUtc = envActionControlEntity.actionEndDateTimeUtc, - actionTargetType = envActionControlEntity.actionTargetType, - controlPlans = envActionControlEntity.controlPlans?.map { - MissionEnvActionControlPlanDataOutput.fromEnvActionControlPlanEntity(it) - }, - department = envActionControlEntity.department, - facade = envActionControlEntity.facade, - geom = envActionControlEntity.geom, - infractions = envActionControlEntity.infractions, - isAdministrativeControl = envActionControlEntity.isAdministrativeControl, - isComplianceWithWaterRegulationsControl = - envActionControlEntity.isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - envActionControlEntity - .isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = envActionControlEntity.isSeafarersControl, - observations = envActionControlEntity.observations, - themes = envActionControlEntity.themes, - vehicleType = envActionControlEntity.vehicleType, - reportingIds = reportingIds, - ) + MissionEnvActionControlDataOutput( + id = envActionControlEntity.id, + actionNumberOfControls = envActionControlEntity.actionNumberOfControls, + actionStartDateTimeUtc = envActionControlEntity.actionStartDateTimeUtc, + actionEndDateTimeUtc = envActionControlEntity.actionEndDateTimeUtc, + actionTargetType = envActionControlEntity.actionTargetType, + controlPlans = + envActionControlEntity.controlPlans?.map { + MissionEnvActionControlPlanDataOutput + .fromEnvActionControlPlanEntity(it) + }, + department = envActionControlEntity.department, + facade = envActionControlEntity.facade, + geom = envActionControlEntity.geom, + infractions = envActionControlEntity.infractions, + isAdministrativeControl = envActionControlEntity.isAdministrativeControl, + isComplianceWithWaterRegulationsControl = + envActionControlEntity.isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + envActionControlEntity + .isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = envActionControlEntity.isSeafarersControl, + observations = envActionControlEntity.observations, + themes = envActionControlEntity.themes, + vehicleType = envActionControlEntity.vehicleType, + reportingIds = reportingIds, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt new file mode 100644 index 000000000..a51a1ca3f --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt @@ -0,0 +1,22 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.missions + +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity + +data class MissionEnvActionSubThemeDataOutput( + val id: Int, + val subTheme: String, + val theme: String, + val tags: List, +) { + companion object { + fun fromEnvActionControlPlanSubThemeEntity( + envActionControlPlanSubThemeEntity: EnvActionControlPlanSubThemeEntity, + ) = + MissionEnvActionSubThemeDataOutput( + id = envActionControlPlanSubThemeEntity.subThemeId, + theme = envActionControlPlanSubThemeEntity.theme, + subTheme = envActionControlPlanSubThemeEntity.subTheme, + tags = envActionControlPlanSubThemeEntity.tags, + ) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt index 73fc7194d..65d3a0438 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt @@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -@Deprecated("Use ControlPlanThemesController instead") +@Deprecated("Use ControlPlanSubThemesController instead") @RestController @RequestMapping("/bff/v1/controlthemes") @Tag(name = "BFF.Control Themes", description = "API control themes") diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt index bc035154a..5ebc5c52a 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt @@ -17,31 +17,26 @@ import org.hibernate.annotations.CacheConcurrencyStrategy @Entity @Table(name = "control_plan_sub_themes") @Cache( - usage = CacheConcurrencyStrategy.READ_WRITE, + usage = CacheConcurrencyStrategy.READ_WRITE, ) class ControlPlanSubThemeModel( - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id", nullable = false, updatable = false) - val id: Int, - - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "theme_id") - val controlPlanTheme: ControlPlanThemeModel, - - @Column(name = "subtheme") - val subTheme: String, - - @Column(name = "year") - val year: Int, - + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false, updatable = false) + val id: Int, + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "theme_id") + val ControlPlanTheme: ControlPlanThemeModel, + @Column(name = "subtheme") val subTheme: String, + @Column(name = "year") val year: Int, ) { - fun toControlPlanSubThemeEntity() = ControlPlanSubThemeEntity( - id = id, - themeId = controlPlanTheme.id, - subTheme = subTheme, - year = year, - ) + fun toControlPlanSubThemeEntity() = + ControlPlanSubThemeEntity( + id = id, + themeId = controlPlanTheme.id, + subTheme = subTheme, + year = year, + ) override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt index e027bca8c..4b053a910 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt @@ -23,6 +23,9 @@ import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne import jakarta.persistence.OneToMany import jakarta.persistence.Table +import java.time.Instant +import java.time.ZoneOffset.UTC +import java.util.UUID import org.hibernate.Hibernate import org.hibernate.annotations.JdbcType import org.hibernate.annotations.Type @@ -30,170 +33,162 @@ import org.hibernate.type.descriptor.jdbc.UUIDJdbcType import org.locationtech.jts.geom.Geometry import org.n52.jackson.datatype.jts.GeometryDeserializer import org.n52.jackson.datatype.jts.GeometrySerializer -import java.time.Instant -import java.time.ZoneOffset.UTC -import java.util.UUID @JsonIdentityInfo( - generator = ObjectIdGenerators.PropertyGenerator::class, - property = "id", + generator = ObjectIdGenerators.PropertyGenerator::class, + property = "id", ) @Entity @Table(name = "env_actions") class EnvActionModel( - @Id - @JdbcType(UUIDJdbcType::class) - @Column(name = "id", nullable = false, updatable = false, columnDefinition = "uuid") - val id: UUID, - - @Column(name = "action_start_datetime_utc") - val actionStartDateTime: Instant? = null, - - @Column(name = "action_end_datetime_utc") - val actionEndDateTime: Instant? = null, - - @JsonSerialize(using = GeometrySerializer::class) - @JsonDeserialize(contentUsing = GeometryDeserializer::class) - @Column(name = "geom") - val geom: Geometry? = null, - - @Column(name = "action_type") - @Enumerated(EnumType.STRING) - val actionType: ActionTypeEnum, - - @Type(JsonBinaryType::class) - @Column(name = "value", columnDefinition = "jsonb") - val value: String, - - @Column(name = "facade") - val facade: String? = null, - - @Column(name = "department") - val department: String? = null, - - @ManyToOne(fetch = FetchType.LAZY, optional = false) - @JoinColumn(name = "mission_id") - @JsonBackReference - val mission: MissionModel, - - @Column(name = "is_administrative_control") - val isAdministrativeControl: Boolean? = null, - - @Column(name = "is_compliance_with_water_regulations_control") - val isComplianceWithWaterRegulationsControl: Boolean? = null, - - @Column(name = "is_safety_equipment_and_standards_compliance_control") - val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - - @Column(name = "is_seafarers_control") - val isSeafarersControl: Boolean? = null, - - @OneToMany( - fetch = FetchType.LAZY, - mappedBy = "attachedEnvAction", - ) - @JsonManagedReference - val attachedReporting: List? = listOf(), - - @OneToMany( - fetch = FetchType.EAGER, - cascade = [CascadeType.ALL], - orphanRemoval = true, - mappedBy = "envAction", - ) - val controlPlanThemes: MutableList? = ArrayList(), - - @OneToMany( - fetch = FetchType.EAGER, - cascade = [CascadeType.ALL], - orphanRemoval = true, - mappedBy = "envAction", - ) - val controlPlanSubThemes: MutableList? = ArrayList(), - - @OneToMany( - fetch = FetchType.EAGER, - cascade = [CascadeType.ALL], - orphanRemoval = true, - mappedBy = "envAction", - ) - val controlPlanTags: MutableList? = ArrayList(), + @Id + @JdbcType(UUIDJdbcType::class) + @Column(name = "id", nullable = false, updatable = false, columnDefinition = "uuid") + val id: UUID, + @Column(name = "action_start_datetime_utc") val actionStartDateTime: Instant? = null, + @Column(name = "action_end_datetime_utc") val actionEndDateTime: Instant? = null, + @JsonSerialize(using = GeometrySerializer::class) + @JsonDeserialize(contentUsing = GeometryDeserializer::class) + @Column(name = "geom") + val geom: Geometry? = null, + @Column(name = "action_type") @Enumerated(EnumType.STRING) val actionType: ActionTypeEnum, + @Type(JsonBinaryType::class) + @Column(name = "value", columnDefinition = "jsonb") + val value: String, + @Column(name = "facade") val facade: String? = null, + @Column(name = "department") val department: String? = null, + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "mission_id") + @JsonBackReference + val mission: MissionModel, + @Column(name = "is_administrative_control") val isAdministrativeControl: Boolean? = null, + @Column(name = "is_compliance_with_water_regulations_control") + val isComplianceWithWaterRegulationsControl: Boolean? = null, + @Column(name = "is_safety_equipment_and_standards_compliance_control") + val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, + @Column(name = "is_seafarers_control") val isSeafarersControl: Boolean? = null, + @OneToMany( + fetch = FetchType.LAZY, + mappedBy = "attachedEnvAction", + ) + @JsonManagedReference + val attachedReporting: List? = listOf(), + @OneToMany( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + orphanRemoval = true, + mappedBy = "envAction", + ) + val controlPlanThemes: MutableList? = ArrayList(), + @OneToMany( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + orphanRemoval = true, + mappedBy = "envAction", + ) + val controlPlanSubThemes: MutableList? = ArrayList(), + @OneToMany( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + orphanRemoval = true, + mappedBy = "envAction", + ) + val controlPlanTags: MutableList? = ArrayList(), ) { fun toActionEntity(mapper: ObjectMapper): EnvActionEntity { - val controlPlans = controlPlanThemes?.map { it -> - EnvActionControlPlanEntity( - themeId = it.id.themeId, - subThemeIds = controlPlanSubThemes?.filter { subTheme -> it.id.themeId == subTheme.controlPlanSubTheme?.controlPlanTheme?.id }?.map { it.id.subthemeId }, - tagIds = controlPlanTags?.filter { tag -> it.id.themeId == tag.controlPlanTag?.controlPlanTheme?.id }?.map { it.id.tagId }, - ) - } + val controlPlans = + controlPlanThemes?.map { it -> + EnvActionControlPlanEntity( + themeId = it.id.themeId, + subThemeIds = + controlPlanSubThemes + ?.filter { subTheme -> + it.id.themeId == + subTheme.controlPlanSubTheme + ?.controlPlanTheme + ?.id + } + ?.map { it.id.subthemeId }, + tagIds = + controlPlanTags + ?.filter { tag -> + it.id.themeId == + tag.controlPlanTag?.controlPlanTheme?.id + } + ?.map { it.id.tagId }, + ) + } return EnvActionMapper.getEnvActionEntityFromJSON( - mapper = mapper, - id = id, - actionEndDateTimeUtc = actionEndDateTime?.atZone(UTC), - actionType = actionType, - actionStartDateTimeUtc = actionStartDateTime?.atZone(UTC), - controlPlans = controlPlans, - department = department, - facade = facade, - geom = geom, - isAdministrativeControl = isAdministrativeControl, - isComplianceWithWaterRegulationsControl = isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = isSeafarersControl, - value = value, + mapper = mapper, + id = id, + actionEndDateTimeUtc = actionEndDateTime?.atZone(UTC), + actionType = actionType, + actionStartDateTimeUtc = actionStartDateTime?.atZone(UTC), + controlPlans = controlPlans, + department = department, + facade = facade, + geom = geom, + isAdministrativeControl = isAdministrativeControl, + isComplianceWithWaterRegulationsControl = isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = isSeafarersControl, + value = value, ) } companion object { fun fromEnvActionEntity( - action: EnvActionEntity, - mission: MissionModel, - controlPlanThemesReferenceModelMap: Map, - controlPlanSubThemesReferenceModelMap: Map, - controlPlanTagsReferenceModelMap: Map, - mapper: ObjectMapper, + action: EnvActionEntity, + mission: MissionModel, + controlPlanThemesReferenceModelMap: Map, + controlPlanSubThemesReferenceModelMap: Map, + controlPlanTagsReferenceModelMap: Map, + mapper: ObjectMapper, ): EnvActionModel { - val envActionModel = EnvActionModel( - id = action.id, - actionEndDateTime = action.actionEndDateTimeUtc?.toInstant(), - actionType = action.actionType, - actionStartDateTime = action.actionStartDateTimeUtc?.toInstant(), - department = action.department, - facade = action.facade, - isAdministrativeControl = action.isAdministrativeControl, - isComplianceWithWaterRegulationsControl = - action.isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - action.isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = action.isSeafarersControl, - mission = mission, - geom = action.geom, - value = EnvActionMapper.envActionEntityToJSON(mapper, action), - ) + val envActionModel = + EnvActionModel( + id = action.id, + actionEndDateTime = action.actionEndDateTimeUtc?.toInstant(), + actionType = action.actionType, + actionStartDateTime = action.actionStartDateTimeUtc?.toInstant(), + department = action.department, + facade = action.facade, + isAdministrativeControl = action.isAdministrativeControl, + isComplianceWithWaterRegulationsControl = + action.isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + action.isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = action.isSeafarersControl, + mission = mission, + geom = action.geom, + value = EnvActionMapper.envActionEntityToJSON(mapper, action), + ) action.controlPlans?.forEach { envActionModel.controlPlanThemes?.add( - EnvActionsControlPlanThemeModel.fromEnvActionControlPlanThemeEntity( - envAction = envActionModel, - controlPlanTheme = controlPlanThemesReferenceModelMap[it.themeId]!!, - ), + EnvActionsControlPlanThemeModel.fromEnvActionControlPlanThemeEntity( + envAction = envActionModel, + controlPlanTheme = controlPlanThemesReferenceModelMap[it.themeId]!!, + ), ) it.subThemeIds?.forEach { subThemeId -> envActionModel.controlPlanSubThemes?.add( - EnvActionsControlPlanSubThemeModel.fromEnvActionControlPlanSubThemeEntity( - envAction = envActionModel, - controlPlanSubTheme = controlPlanSubThemesReferenceModelMap[subThemeId]!!, - ), + EnvActionsControlPlanSubThemeModel + .fromEnvActionControlPlanSubThemeEntity( + envAction = envActionModel, + controlPlanSubTheme = + controlPlanSubThemesReferenceModelMap[ + subThemeId]!!, + ), ) } it.tagIds?.forEach { tagId -> envActionModel.controlPlanTags?.add( - EnvActionsControlPlanTagModel.fromEnvActionControlPlanTagEntity( - envAction = envActionModel, - controlPlanTag = controlPlanTagsReferenceModelMap[tagId]!!, - ), + EnvActionsControlPlanTagModel.fromEnvActionControlPlanTagEntity( + envAction = envActionModel, + controlPlanTag = controlPlanTagsReferenceModelMap[tagId]!!, + ), ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt new file mode 100644 index 000000000..78fb12a7e --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt @@ -0,0 +1,68 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.model + +import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity +import io.hypersistence.utils.hibernate.type.array.ListArrayType +import jakarta.persistence.Column +import jakarta.persistence.Embeddable +import jakarta.persistence.EmbeddedId +import jakarta.persistence.Entity +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne +import jakarta.persistence.MapsId +import jakarta.persistence.Table +import org.hibernate.annotations.Type +import java.io.Serializable +import java.util.UUID + +@Entity +@Table(name = "env_actions_subthemes") +data class EnvActionsSubThemeModel( + + @EmbeddedId + val id: EnvActionsSubThemePk, + + @ManyToOne + @MapsId("envActionId") + @JoinColumn(name = "env_action_id") + val envAction: EnvActionModel? = null, + + @ManyToOne + @MapsId("subthemeId") + @JoinColumn(name = "subtheme_id") + val controlPlanSubTheme: ControlPlanSubThemeModel? = null, + + @Column(name = "tags") + @Type(ListArrayType::class) + val tags: List? = null, +) { + fun toEnvActionControlPlanSubThemeEntity(): EnvActionControlPlanSubThemeEntity { + require(controlPlanSubTheme != null) { "controlPlanSubTheme must not be null when converting to Entity" } + return EnvActionControlPlanSubThemeEntity( + subThemeId = controlPlanSubTheme.id, + theme = controlPlanSubTheme.ControlPlanTheme.theme, + subTheme = controlPlanSubTheme.subTheme, + tags = tags ?: emptyList(), + ) + } + companion object { + fun fromEnvActionControlPlanSubThemeEntity( + envActionId: UUID, + envActionControlPlanSubTheme: EnvActionControlPlanSubThemeEntity, + ) = EnvActionsSubThemeModel( + id = EnvActionsSubThemePk( + envActionId = envActionId, + subthemeId = envActionControlPlanSubTheme.subThemeId, + ), + tags = envActionControlPlanSubTheme.tags, + ) + } +} + +@Embeddable +data class EnvActionsSubThemePk( + @Column(name = "env_action_id") + val envActionId: UUID, + + @Column(name = "subtheme_id") + val subthemeId: Int, +) : Serializable diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt index f73e74ec0..4f4b2bfc2 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt @@ -7,7 +7,7 @@ import org.springframework.stereotype.Repository @Repository class JpaControlPlanSubThemeRepository( - private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, + private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, ) : IControlPlanSubThemeRepository { override fun findAll(): List { return dbControlPlanSubThemeRepository.findAll().map { it.toControlPlanSubThemeEntity() } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt deleted file mode 100644 index 1826e74a8..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt +++ /dev/null @@ -1,20 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.database.repositories - -import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity -import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository -import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanThemeRepository -import org.springframework.stereotype.Repository - -@Repository -class JpaControlPlanThemeRepository( - private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, -) : IControlPlanThemeRepository { - override fun findAll(): List { - return dbControlPlanThemeRepository.findAll().map { it.toControlPlanThemeEntity() } - } - override fun findByYear(year: Int): List { - return dbControlPlanThemeRepository.findByYearOrderById(year).map { - it.toControlPlanThemeEntity() - } - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt index 21fad8c5e..8b1378917 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt @@ -1,8 +1 @@ -package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces -import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanSubThemeModel -import org.springframework.data.jpa.repository.JpaRepository - -interface IDBControlPlanSubThemeRepository : JpaRepository { - fun findByYearOrderById(year: Int): List -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt deleted file mode 100644 index 9de8bb05f..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt +++ /dev/null @@ -1,20 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces - -import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanThemeModel -import org.springframework.data.jpa.repository.JpaRepository -import org.springframework.data.jpa.repository.Query - -interface IDBControlPlanThemeRepository : JpaRepository { - @Query( - value = - """ - SELECT th.* - FROM control_plan_themes th, control_plan_sub_themes s - WHERE th.id = s.theme_id - AND s.year = :year - ORDER BY th.id ASC - """, - nativeQuery = true, - ) - fun findByYearOrderById(year: Int): List -} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt new file mode 100644 index 000000000..d333d2464 --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt @@ -0,0 +1,41 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes + +import com.nhaarman.mockitokotlin2.given +import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.junit.jupiter.SpringExtension + +@ExtendWith(SpringExtension::class) +class GetControlPlanSubThemesByYearUTest { + @MockBean + private lateinit var controlPlanSubThemeRepository: IControlPlanSubThemeRepository + + fun `execute should return all ControlPlanSubThemes for the given year`() { + val controlPlanSubThemes = listOf( + ControlPlanSubThemeEntity( + id = 1, + theme = "ControlPlanTheme Name", + subTheme = "ControlPlanSubTheme Name", + allowedTags = listOf("tag1", "tag2"), + year = 2023, + ), + ControlPlanSubThemeEntity( + id = 2, + theme = "ControlPlanTheme Name 2", + subTheme = "ControlPlanSubTheme Name 2", + allowedTags = null, + year = 2023, + ), + ) + + given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) + + val result = GetControlPlanSubThemesByYear(controlPlanSubThemeRepository).execute(2023) + + assertThat(result.size).isEqualTo(2) + assertThat(result).isEqualTo(controlPlanSubThemes) + } +} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt similarity index 50% rename from backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt rename to backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt index 35c99e37e..3d2fd33e9 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanThemesControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt @@ -2,8 +2,8 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff import com.nhaarman.mockitokotlin2.verify import fr.gouv.cacem.monitorenv.config.WebSecurityConfig -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanTheme.ControlPlanThemeEntity -import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanThemes.GetControlPlanThemesByYear +import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes.GetControlPlanSubThemesByYear import org.junit.jupiter.api.Test import org.mockito.BDDMockito import org.springframework.beans.factory.annotation.Autowired @@ -16,36 +16,36 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPat import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status @Import(WebSecurityConfig::class) -@WebMvcTest(value = [(ControlPlanThemesController::class)]) -class ControlPlanThemesControllerITests { +@WebMvcTest(value = [(ControlPlanSubThemesController::class)]) +class ControlPlanSubThemesControllerITests { @Autowired private lateinit var mockMvc: MockMvc @MockBean - private lateinit var getControlPlanThemesByYear: GetControlPlanThemesByYear + private lateinit var getControlPlanSubThemesByYear: GetControlPlanSubThemesByYear @Test fun `Should get all control plan themes`() { // Given - val controlPlanTheme = ControlPlanThemeEntity( + val ControlPlanSubTheme = ControlPlanSubThemeEntity( id = 1, theme = "Theme Police des mouillages", subTheme = "Sous Theme Mouillage individuel", allowedTags = listOf("tag1", "tag2"), year = 2024, ) - BDDMockito.given(getControlPlanThemesByYear.execute(2024)).willReturn(listOf(controlPlanTheme)) + BDDMockito.given(getControlPlanSubThemesByYear.execute(2024)).willReturn(listOf(ControlPlanSubTheme)) // When - mockMvc.perform(get("/bff/v1/controlplanthemes/2024")) + mockMvc.perform(get("/bff/v1/controlPlanSubThemes/2024")) // Then .andExpect(status().isOk) - .andExpect(jsonPath("$[0].id").value(controlPlanTheme.id)) - .andExpect(jsonPath("$[0].theme").value(controlPlanTheme.theme)) - .andExpect(jsonPath("$[0].subTheme").value(controlPlanTheme.subTheme)) - .andExpect(jsonPath("$[0].year").value(controlPlanTheme.year)) - .andExpect(jsonPath("$[0].allowedTags[0]").value(controlPlanTheme.allowedTags?.get(0))) - .andExpect(jsonPath("$[0].allowedTags[1]").value(controlPlanTheme.allowedTags?.get(1))) + .andExpect(jsonPath("$[0].id").value(ControlPlanSubTheme.id)) + .andExpect(jsonPath("$[0].theme").value(ControlPlanSubTheme.theme)) + .andExpect(jsonPath("$[0].subTheme").value(ControlPlanSubTheme.subTheme)) + .andExpect(jsonPath("$[0].year").value(ControlPlanSubTheme.year)) + .andExpect(jsonPath("$[0].allowedTags[0]").value(ControlPlanSubTheme.allowedTags?.get(0))) + .andExpect(jsonPath("$[0].allowedTags[1]").value(ControlPlanSubTheme.allowedTags?.get(1))) - verify(getControlPlanThemesByYear).execute(2024) + verify(getControlPlanSubThemesByYear).execute(2024) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt index c70f63096..d30ad986e 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt @@ -17,9 +17,9 @@ class JpaControlPlanSubThemeRepositoryITests : AbstractDBTests() { assertThat(requestedControlPlanSubThemes[5].id).isEqualTo(6) assertThat(requestedControlPlanSubThemes[5].themeId).isEqualTo(4) assertThat(requestedControlPlanSubThemes[5].subTheme) - .isEqualTo( - "Atteinte aux biens culturels", - ) + .isEqualTo( + "Atteinte aux biens culturels", + ) assertThat(requestedControlPlanSubThemes[5].year).isEqualTo(2023) } @@ -34,9 +34,9 @@ class JpaControlPlanSubThemeRepositoryITests : AbstractDBTests() { assertThat(requestedControlPlanSubThemesFor2024[5].id).isEqualTo(6) assertThat(requestedControlPlanSubThemesFor2024[5].themeId).isEqualTo(11) assertThat(requestedControlPlanSubThemesFor2024[5].subTheme) - .isEqualTo( - "Destruction, capture, arrachage", - ) + .isEqualTo( + "Destruction, capture, arrachage", + ) assertThat(requestedControlPlanSubThemesFor2024[5].year).isEqualTo(2024) } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt deleted file mode 100644 index b5895234f..000000000 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt +++ /dev/null @@ -1,31 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.database.repositories - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired - -class JpaControlPlanThemeRepositoryITests : AbstractDBTests() { - @Autowired private lateinit var jpaControlPlanThemeRepository: JpaControlPlanThemeRepository - - @Test - fun `findAll Should return all control plan themes`() { - // When - val requestedControlPlanThemes = jpaControlPlanThemeRepository.findAll() - // Then - assertThat(requestedControlPlanThemes.size).isEqualTo(22) - assertThat(requestedControlPlanThemes[5].id).isEqualTo(6) - assertThat(requestedControlPlanThemes[5].theme).isEqualTo("Divers") - } - - @Test - fun `findByYear Should return all control plan theme for a specific year`() { - // When - val requestedControlPlanThemesFor2023 = jpaControlPlanThemeRepository.findByYear(2023) - val requestedControlPlanThemesFor2024 = jpaControlPlanThemeRepository.findByYear(2024) - // Then - assertThat(requestedControlPlanThemesFor2023.size).isEqualTo(83) - assertThat(requestedControlPlanThemesFor2024.size).isEqualTo(6) - assertThat(requestedControlPlanThemesFor2024[5].id).isEqualTo(100002) - assertThat(requestedControlPlanThemesFor2024[5].theme).isEqualTo("Rejet") - } -} From fae080f0617856ac9e3a1a608414df16042d82ee Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Fri, 1 Dec 2023 15:51:38 +0100 Subject: [PATCH 25/53] fix package names, dataoutput + tests on controller --- .../GetControlPlanSubThemesByYear.kt | 12 +- .../missions/MissionEnvActionDataOutput.kt | 43 +- .../GetControlPlanSubThemesByYearUTest.kt | 4 +- .../ControlPlanSubThemesControllerITests.kt | 4 +- .../endpoints/bff/MissionsControllerITests.kt | 1483 +++++++++-------- 5 files changed, 780 insertions(+), 766 deletions(-) rename backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/{controlPlanThemes => controlPlanSubThemes}/GetControlPlanSubThemesByYear.kt (57%) rename backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/{controlPlanThemes => controlPlanSubThemes}/GetControlPlanSubThemesByYearUTest.kt (92%) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt similarity index 57% rename from backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt rename to backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt index a1d2b4309..8d2c485a9 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYear.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt @@ -1,16 +1,16 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes import fr.gouv.cacem.monitorenv.config.UseCase -import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository import org.slf4j.LoggerFactory @UseCase -class GetControlPlanSubThemesByYear(private val ControlPlanSubThemeRepository: IControlPlanSubThemeRepository) { +class GetControlPlanSubThemesByYear(private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository) { private val logger = LoggerFactory.getLogger(GetControlPlanSubThemesByYear::class.java) fun execute(year: Int): List { - val ControlPlanSubThemes = ControlPlanSubThemeRepository.findByYear(year) - logger.info("Found ${ControlPlanSubThemes.size} control plan (sub)themes for year $year") - return ControlPlanSubThemes + val controlPlanSubThemes = controlPlanSubThemeRepository.findByYear(year) + logger.info("Found ${controlPlanSubThemes.size} control plan (sub)themes for year $year") + return controlPlanSubThemes } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt index 698a7970b..c2b0c3979 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt @@ -10,36 +10,39 @@ import java.time.ZonedDateTime import java.util.UUID abstract class MissionEnvActionDataOutput( - open val id: UUID, - open val actionStartDateTimeUtc: ZonedDateTime? = null, - open val actionType: ActionTypeEnum, + open val id: UUID, + open val actionStartDateTimeUtc: ZonedDateTime? = null, + open val actionType: ActionTypeEnum, ) { companion object { fun fromEnvActionEntity( - envActionEntity: EnvActionEntity, - envActionsAttachedToReportingIds: List?, + envActionEntity: EnvActionEntity, + envActionsAttachedToReportingIds: List?, ): MissionEnvActionDataOutput { return when (envActionEntity.actionType) { ActionTypeEnum.CONTROL -> - MissionEnvActionControlDataOutput - .fromEnvActionControlEntity( - envActionControlEntity = envActionEntity as EnvActionControlEntity, - reportingIds = envActionsAttachedToReportingIds?.find { id -> - id.first == envActionEntity.id - }?.second ?: listOf(), + MissionEnvActionControlDataOutput.fromEnvActionControlEntity( + envActionControlEntity = envActionEntity as EnvActionControlEntity, + reportingIds = + envActionsAttachedToReportingIds + ?.find { id -> id.first == envActionEntity.id } + ?.second + ?: listOf(), ) ActionTypeEnum.SURVEILLANCE -> - MissionEnvActionSurveillanceDataOutput - .fromEnvActionSurveillanceEntity( - envActionSurveillanceEntity = envActionEntity as EnvActionSurveillanceEntity, - reportingIds = envActionsAttachedToReportingIds?.find { id -> - id.first == envActionEntity.id - }?.second ?: listOf(), + MissionEnvActionSurveillanceDataOutput.fromEnvActionSurveillanceEntity( + envActionSurveillanceEntity = + envActionEntity as EnvActionSurveillanceEntity, + reportingIds = + envActionsAttachedToReportingIds + ?.find { id -> id.first == envActionEntity.id } + ?.second + ?: listOf(), ) ActionTypeEnum.NOTE -> - MissionEnvActionNoteDataOutput.fromEnvActionNoteEntity( - envActionEntity as EnvActionNoteEntity, - ) + MissionEnvActionNoteDataOutput.fromEnvActionNoteEntity( + envActionEntity as EnvActionNoteEntity, + ) } } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt similarity index 92% rename from backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt rename to backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt index d333d2464..3b457c9d5 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanThemes/GetControlPlanSubThemesByYearUTest.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt @@ -1,7 +1,7 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes import com.nhaarman.mockitokotlin2.given -import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.extension.ExtendWith diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt index 3d2fd33e9..59d8cae7a 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt @@ -2,8 +2,8 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff import com.nhaarman.mockitokotlin2.verify import fr.gouv.cacem.monitorenv.config.WebSecurityConfig -import fr.gouv.cacem.monitorenv.domain.entities.ControlPlanSubTheme.ControlPlanSubThemeEntity -import fr.gouv.cacem.monitorenv.domain.use_cases.ControlPlanSubThemes.GetControlPlanSubThemesByYear +import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes.GetControlPlanSubThemesByYear import org.junit.jupiter.api.Test import org.mockito.BDDMockito import org.springframework.beans.factory.annotation.Autowired diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt index 9d889c67b..4b3af7d64 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt @@ -26,6 +26,8 @@ import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos.ReportingDTO import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions.CreateOrUpdateMissionDataInput import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions.MissionEnvActionDataInput +import java.time.ZonedDateTime +import java.util.* import org.hamcrest.Matchers.equalTo import org.junit.jupiter.api.Test import org.locationtech.jts.geom.MultiPolygon @@ -44,8 +46,6 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* import org.springframework.test.web.servlet.result.MockMvcResultHandlers import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status -import java.time.ZonedDateTime -import java.util.* @Import(WebSecurityConfig::class, MapperConfiguration::class) @WebMvcTest(value = [(MissionsController::class)]) @@ -55,7 +55,7 @@ class MissionsControllerITests { @MockBean private lateinit var createOrUpdateMissionWithAttachedReporting: - CreateOrUpdateMissionWithAttachedReporting + CreateOrUpdateMissionWithAttachedReporting @MockBean private lateinit var getFullMissions: GetFullMissions @@ -67,65 +67,68 @@ class MissionsControllerITests { @Autowired private lateinit var objectMapper: ObjectMapper - private val polygon = WKTReader().read( - "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))", - ) as MultiPolygon + private val polygon = + WKTReader() + .read( + "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))", + ) as + MultiPolygon private val point = WKTReader().read("POINT (-4.54877816747593 48.305559876971)") as Point @Test fun `Should create a new mission`() { // Given val expectedNewMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - facade = "Outre-Mer", - geom = polygon, - observationsCacem = null, - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = - ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isDeleted = false, - isClosed = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ), - ) + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + facade = "Outre-Mer", + geom = polygon, + observationsCacem = null, + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = + ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isDeleted = false, + isClosed = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ), + ) val newMissionRequest = - CreateOrUpdateMissionDataInput( - missionTypes = listOf(MissionTypeEnum.LAND), - observationsCacem = null, - facade = "Outre-Mer", - geom = polygon, - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isClosed = false, - missionSource = MissionSourceEnum.MONITORENV, - attachedReportingIds = listOf(), - ) + CreateOrUpdateMissionDataInput( + missionTypes = listOf(MissionTypeEnum.LAND), + observationsCacem = null, + facade = "Outre-Mer", + geom = polygon, + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isClosed = false, + missionSource = MissionSourceEnum.MONITORENV, + attachedReportingIds = listOf(), + ) val requestbody = objectMapper.writeValueAsString(newMissionRequest) given( - createOrUpdateMissionWithAttachedReporting.execute( - mission = newMissionRequest.toMissionEntity(), - attachedReportingIds = listOf(), - envActionsAttachedToReportingIds = listOf(), - ), - ) - .willReturn(expectedNewMission) + createOrUpdateMissionWithAttachedReporting.execute( + mission = newMissionRequest.toMissionEntity(), + attachedReportingIds = listOf(), + envActionsAttachedToReportingIds = listOf(), + ), + ) + .willReturn(expectedNewMission) // When mockMvc.perform( - put("/bff/v1/missions") - .content(requestbody) - .contentType(MediaType.APPLICATION_JSON), - ) - // Then - .andDo(MockMvcResultHandlers.print()) - .andExpect(status().isOk) + put("/bff/v1/missions") + .content(requestbody) + .contentType(MediaType.APPLICATION_JSON), + ) + // Then + .andDo(MockMvcResultHandlers.print()) + .andExpect(status().isOk) } @Test @@ -133,328 +136,332 @@ class MissionsControllerITests { // Given val controlEnvAction = - EnvActionControlEntity( - id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - controlPlans = listOf( - EnvActionControlPlanEntity( - subThemeIds = listOf(1), - tagIds = listOf(1, 2), - themeId = 1, - ), - ), - geom = point, - facade = "Outre-Mer", - department = "29", - isAdministrativeControl = false, - isComplianceWithWaterRegulationsControl = false, - isSafetyEquipmentAndStandardsComplianceControl = false, - isSeafarersControl = false, - themes = - listOf( - ThemeEntity( - theme = "Theme 1", - subThemes = listOf("sous theme 1", "sous theme 2"), - ), - ), - observations = "Observations de l'action de contrôle", - actionNumberOfControls = 2, - actionTargetType = ActionTargetTypeEnum.VEHICLE, - vehicleType = VehicleTypeEnum.VEHICLE_LAND, - infractions = - listOf( - InfractionEntity( - id = "d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b", - natinf = listOf("27001"), - observations = "Observations de l'infraction", - registrationNumber = "AB-123-CD", - companyName = "Company Name", - relevantCourt = "LOCAL_COURT", - infractionType = InfractionTypeEnum.WAITING, - formalNotice = FormalNoticeEnum.NO, - toProcess = false, - controlledPersonIdentity = "Captain Flame", - vesselType = VesselTypeEnum.COMMERCIAL, - vesselSize = VesselSizeEnum.FROM_12_TO_24m, - ), - ), - ) + EnvActionControlEntity( + id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + controlPlans = + listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(1), + tagIds = listOf(1, 2), + themeId = 1, + ), + ), + geom = point, + facade = "Outre-Mer", + department = "29", + isAdministrativeControl = false, + isComplianceWithWaterRegulationsControl = false, + isSafetyEquipmentAndStandardsComplianceControl = false, + isSeafarersControl = false, + themes = + listOf( + ThemeEntity( + theme = "Theme 1", + subThemes = listOf("sous theme 1", "sous theme 2"), + ), + ), + observations = "Observations de l'action de contrôle", + actionNumberOfControls = 2, + actionTargetType = ActionTargetTypeEnum.VEHICLE, + vehicleType = VehicleTypeEnum.VEHICLE_LAND, + infractions = + listOf( + InfractionEntity( + id = "d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b", + natinf = listOf("27001"), + observations = "Observations de l'infraction", + registrationNumber = "AB-123-CD", + companyName = "Company Name", + relevantCourt = "LOCAL_COURT", + infractionType = InfractionTypeEnum.WAITING, + formalNotice = FormalNoticeEnum.NO, + toProcess = false, + controlledPersonIdentity = "Captain Flame", + vesselType = VesselTypeEnum.COMMERCIAL, + vesselSize = VesselSizeEnum.FROM_12_TO_24m, + ), + ), + ) val expectedFirstMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.SEA), - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 1, - name = "CU1", - administration = "Admin 1", - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 2, - controlUnitId = 1, - name = - "Ressource 2", + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.SEA), + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 1, + name = "CU1", + administration = "Admin 1", + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 2, + controlUnitId = + 1, + name = + "Ressource 2", + ), + ), + isArchived = false, + ), + ), + openBy = "OpenBy", + closedBy = "ClosedBy", + facade = "Outre-Mer", + geom = polygon, + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = + ZonedDateTime.parse("2022-01-23T20:29:03Z"), + observationsCacem = "obs cacem", + observationsCnsp = "obs cnsp", + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + envActions = listOf(controlEnvAction), ), - ), - isArchived = false, - ), - ), - openBy = "OpenBy", - closedBy = "ClosedBy", - facade = "Outre-Mer", - geom = polygon, - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = - ZonedDateTime.parse("2022-01-23T20:29:03Z"), - observationsCacem = "obs cacem", - observationsCnsp = "obs cnsp", - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - envActions = listOf(controlEnvAction), - ), - attachedReportingIds = listOf(1), - attachedReportings = - listOf( - ReportingDTO( - reporting = - ReportingEntity( - id = 1, - reportingId = 2300001, - sourceType = - SourceTypeEnum.SEMAPHORE, - semaphoreId = 1, - targetType = TargetTypeEnum.VEHICLE, - vehicleType = - VehicleTypeEnum - .VEHICLE_LAND, - geom = polygon, - seaFront = "SeaFront", - description = "Description", - reportType = - ReportingTypeEnum - .INFRACTION_SUSPICION, - themeId = 12, - subThemeIds = listOf(82), - actionTaken = "ActionTaken", - isControlRequired = true, - hasNoUnitAvailable = true, - createdAt = - ZonedDateTime.parse( - "2022-01-15T04:50:09Z", - ), - validityTime = 4, - isArchived = false, - isDeleted = false, - openBy = "OpenBy", - ), - semaphore = - SemaphoreEntity( - id = 1, - name = "Semaphore 1", - geom = point, - department = "29", - facade = "Outre-Mer", - administration = "Admin 1", - unit = "Unit 1", - email = "semaphore@", - phoneNumber = "0299999999", - base = "Base 1", - ), - ), - ), - ) + attachedReportingIds = listOf(1), + attachedReportings = + listOf( + ReportingDTO( + reporting = + ReportingEntity( + id = 1, + reportingId = 2300001, + sourceType = + SourceTypeEnum.SEMAPHORE, + semaphoreId = 1, + targetType = TargetTypeEnum.VEHICLE, + vehicleType = + VehicleTypeEnum + .VEHICLE_LAND, + geom = polygon, + seaFront = "SeaFront", + description = "Description", + reportType = + ReportingTypeEnum + .INFRACTION_SUSPICION, + themeId = 12, + subThemeIds = listOf(82), + actionTaken = "ActionTaken", + isControlRequired = true, + hasNoUnitAvailable = true, + createdAt = + ZonedDateTime.parse( + "2022-01-15T04:50:09Z", + ), + validityTime = 4, + isArchived = false, + isDeleted = false, + openBy = "OpenBy", + ), + semaphore = + SemaphoreEntity( + id = 1, + name = "Semaphore 1", + geom = point, + department = "29", + facade = "Outre-Mer", + administration = "Admin 1", + unit = "Unit 1", + email = "semaphore@", + phoneNumber = "0299999999", + base = "Base 1", + ), + ), + ), + ) given( - getFullMissions.execute( - startedAfterDateTime = null, - startedBeforeDateTime = null, - seaFronts = null, - missionSources = null, - missionTypes = null, - missionStatuses = null, - pageNumber = null, - pageSize = null, - ), - ) - .willReturn(listOf(expectedFirstMission)) + getFullMissions.execute( + startedAfterDateTime = null, + startedBeforeDateTime = null, + seaFronts = null, + missionSources = null, + missionTypes = null, + missionStatuses = null, + pageNumber = null, + pageSize = null, + ), + ) + .willReturn(listOf(expectedFirstMission)) // When mockMvc.perform(get("/bff/v1/missions")) - // Then - .andExpect(status().isOk) - .andDo(MockMvcResultHandlers.print()) - .andExpect(jsonPath("$.length()", equalTo(1))) - .andExpect(jsonPath("$[0].id", equalTo(10))) - .andExpect( - jsonPath("$[0].missionTypes[0]", equalTo(MissionTypeEnum.SEA.toString())), - ) - .andExpect(jsonPath("$[0].controlUnits[0].id", equalTo(1))) - .andExpect(jsonPath("$[0].openBy", equalTo("OpenBy"))) - .andExpect(jsonPath("$[0].closedBy", equalTo("ClosedBy"))) - .andExpect(jsonPath("$[0].facade", equalTo("Outre-Mer"))) - .andExpect(jsonPath("$[0].geom.type", equalTo("MultiPolygon"))) - .andExpect(jsonPath("$[0].startDateTimeUtc", equalTo("2022-01-15T04:50:09Z"))) - .andExpect(jsonPath("$[0].endDateTimeUtc", equalTo("2022-01-23T20:29:03Z"))) - .andExpect(jsonPath("$[0].observationsCacem", equalTo("obs cacem"))) - .andExpect(jsonPath("$[0].observationsCnsp", equalTo("obs cnsp"))) - .andExpect(jsonPath("$[0].isClosed", equalTo(false))) - .andExpect(jsonPath("$[0].isDeleted").doesNotExist()) - .andExpect( - jsonPath( - "$[0].missionSource", - equalTo(MissionSourceEnum.MONITORENV.toString()), - ), - ) - .andExpect(jsonPath("$[0].hasMissionOrder", equalTo(false))) - .andExpect(jsonPath("$[0].isUnderJdp", equalTo(false))) - .andExpect(jsonPath("$[0].attachedReportingIds", equalTo(listOf(1)))) - .andExpect(jsonPath("$[0].envActions.length()", equalTo(1))) - .andExpect( - jsonPath( - "$[0].envActions[0].id", - equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - ), - ) - .andExpect(jsonPath("$[0].envActions[0].actionType", equalTo("CONTROL"))) - .andExpect( - jsonPath( - "$[0].envActions[0].actionStartDateTimeUtc", - equalTo("2022-01-15T04:50:09Z"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].actionEndDateTimeUtc", - equalTo("2022-01-23T20:29:03Z"), - ), - ) - .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].themeId", equalTo(1))) - .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].subThemeIds[0]", equalTo(1))) - .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].tagIds[0]", equalTo(1))) - .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].tagIds[1]", equalTo(2))) - .andExpect(jsonPath("$[0].envActions[0].geom.type", equalTo("Point"))) - .andExpect(jsonPath("$[0].envActions[0].facade", equalTo("Outre-Mer"))) - .andExpect(jsonPath("$[0].envActions[0].department", equalTo("29"))) - .andExpect(jsonPath("$[0].envActions[0].isAdministrativeControl", equalTo(false))) - .andExpect( - jsonPath( - "$[0].envActions[0].isComplianceWithWaterRegulationsControl", - equalTo(false), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].isSafetyEquipmentAndStandardsComplianceControl", - equalTo(false), - ), - ) - .andExpect(jsonPath("$[0].envActions[0].isSeafarersControl", equalTo(false))) - .andExpect(jsonPath("$[0].envActions[0].themes[0].theme", equalTo("Theme 1"))) - .andExpect( - jsonPath( - "$[0].envActions[0].themes[0].subThemes[0]", - equalTo("sous theme 1"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].themes[0].subThemes[1]", - equalTo("sous theme 2"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].observations", - equalTo("Observations de l'action de contrôle"), - ), - ) - .andExpect(jsonPath("$[0].envActions[0].actionNumberOfControls", equalTo(2))) - .andExpect( - jsonPath( - "$[0].envActions[0].actionTargetType", - equalTo(ActionTargetTypeEnum.VEHICLE.toString()), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].vehicleType", - equalTo(VehicleTypeEnum.VEHICLE_LAND.toString()), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].id", - equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - ), - ) - .andExpect( - jsonPath("$[0].envActions[0].infractions[0].natinf[0]", equalTo("27001")), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].observations", - equalTo("Observations de l'infraction"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].registrationNumber", - equalTo("AB-123-CD"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].companyName", - equalTo("Company Name"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].relevantCourt", - equalTo("LOCAL_COURT"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].infractionType", - equalTo(InfractionTypeEnum.WAITING.toString()), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].formalNotice", - equalTo(FormalNoticeEnum.NO.toString()), - ), - ) - .andExpect(jsonPath("$[0].envActions[0].infractions[0].toProcess", equalTo(false))) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].controlledPersonIdentity", - equalTo("Captain Flame"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].vesselType", - equalTo(VesselTypeEnum.COMMERCIAL.toString()), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].vesselSize", - equalTo(VesselSizeEnum.FROM_12_TO_24m.toString()), - ), - ) + // Then + .andExpect(status().isOk) + .andDo(MockMvcResultHandlers.print()) + .andExpect(jsonPath("$.length()", equalTo(1))) + .andExpect(jsonPath("$[0].id", equalTo(10))) + .andExpect( + jsonPath("$[0].missionTypes[0]", equalTo(MissionTypeEnum.SEA.toString())), + ) + .andExpect(jsonPath("$[0].controlUnits[0].id", equalTo(1))) + .andExpect(jsonPath("$[0].openBy", equalTo("OpenBy"))) + .andExpect(jsonPath("$[0].closedBy", equalTo("ClosedBy"))) + .andExpect(jsonPath("$[0].facade", equalTo("Outre-Mer"))) + .andExpect(jsonPath("$[0].geom.type", equalTo("MultiPolygon"))) + .andExpect(jsonPath("$[0].startDateTimeUtc", equalTo("2022-01-15T04:50:09Z"))) + .andExpect(jsonPath("$[0].endDateTimeUtc", equalTo("2022-01-23T20:29:03Z"))) + .andExpect(jsonPath("$[0].observationsCacem", equalTo("obs cacem"))) + .andExpect(jsonPath("$[0].observationsCnsp", equalTo("obs cnsp"))) + .andExpect(jsonPath("$[0].isClosed", equalTo(false))) + .andExpect(jsonPath("$[0].isDeleted").doesNotExist()) + .andExpect( + jsonPath( + "$[0].missionSource", + equalTo(MissionSourceEnum.MONITORENV.toString()), + ), + ) + .andExpect(jsonPath("$[0].hasMissionOrder", equalTo(false))) + .andExpect(jsonPath("$[0].isUnderJdp", equalTo(false))) + .andExpect(jsonPath("$[0].attachedReportingIds", equalTo(listOf(1)))) + .andExpect(jsonPath("$[0].envActions.length()", equalTo(1))) + .andExpect( + jsonPath( + "$[0].envActions[0].id", + equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + ), + ) + .andExpect(jsonPath("$[0].envActions[0].actionType", equalTo("CONTROL"))) + .andExpect( + jsonPath( + "$[0].envActions[0].actionStartDateTimeUtc", + equalTo("2022-01-15T04:50:09Z"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].actionEndDateTimeUtc", + equalTo("2022-01-23T20:29:03Z"), + ), + ) + .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].themeId", equalTo(1))) + .andExpect( + jsonPath("$[0].envActions[0].controlPlans[0].subThemeIds[0]", equalTo(1)) + ) + .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].tagIds[0]", equalTo(1))) + .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].tagIds[1]", equalTo(2))) + .andExpect(jsonPath("$[0].envActions[0].geom.type", equalTo("Point"))) + .andExpect(jsonPath("$[0].envActions[0].facade", equalTo("Outre-Mer"))) + .andExpect(jsonPath("$[0].envActions[0].department", equalTo("29"))) + .andExpect(jsonPath("$[0].envActions[0].isAdministrativeControl", equalTo(false))) + .andExpect( + jsonPath( + "$[0].envActions[0].isComplianceWithWaterRegulationsControl", + equalTo(false), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].isSafetyEquipmentAndStandardsComplianceControl", + equalTo(false), + ), + ) + .andExpect(jsonPath("$[0].envActions[0].isSeafarersControl", equalTo(false))) + .andExpect(jsonPath("$[0].envActions[0].themes[0].theme", equalTo("Theme 1"))) + .andExpect( + jsonPath( + "$[0].envActions[0].themes[0].subThemes[0]", + equalTo("sous theme 1"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].themes[0].subThemes[1]", + equalTo("sous theme 2"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].observations", + equalTo("Observations de l'action de contrôle"), + ), + ) + .andExpect(jsonPath("$[0].envActions[0].actionNumberOfControls", equalTo(2))) + .andExpect( + jsonPath( + "$[0].envActions[0].actionTargetType", + equalTo(ActionTargetTypeEnum.VEHICLE.toString()), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].vehicleType", + equalTo(VehicleTypeEnum.VEHICLE_LAND.toString()), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].id", + equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + ), + ) + .andExpect( + jsonPath("$[0].envActions[0].infractions[0].natinf[0]", equalTo("27001")), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].observations", + equalTo("Observations de l'infraction"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].registrationNumber", + equalTo("AB-123-CD"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].companyName", + equalTo("Company Name"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].relevantCourt", + equalTo("LOCAL_COURT"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].infractionType", + equalTo(InfractionTypeEnum.WAITING.toString()), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].formalNotice", + equalTo(FormalNoticeEnum.NO.toString()), + ), + ) + .andExpect(jsonPath("$[0].envActions[0].infractions[0].toProcess", equalTo(false))) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].controlledPersonIdentity", + equalTo("Captain Flame"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].vesselType", + equalTo(VesselTypeEnum.COMMERCIAL.toString()), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].vesselSize", + equalTo(VesselSizeEnum.FROM_12_TO_24m.toString()), + ), + ) } @Test @@ -463,307 +470,310 @@ class MissionsControllerITests { val requestedId = 0 val controlEnvAction = - EnvActionControlEntity( - id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - controlPlans = listOf( - EnvActionControlPlanEntity( - subThemeIds = listOf(1), - tagIds = listOf(1, 2), - themeId = 1, - ), - ), - geom = point, - facade = "Outre-Mer", - department = "29", - isAdministrativeControl = false, - isComplianceWithWaterRegulationsControl = false, - isSafetyEquipmentAndStandardsComplianceControl = false, - isSeafarersControl = false, - themes = - listOf( - ThemeEntity( - theme = "Theme 1", - subThemes = listOf("sous theme 1", "sous theme 2"), - ), - ), - observations = "Observations de l'action de contrôle", - actionNumberOfControls = 2, - actionTargetType = ActionTargetTypeEnum.VEHICLE, - vehicleType = VehicleTypeEnum.VEHICLE_LAND, - infractions = - listOf( - InfractionEntity( - id = "d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b", - natinf = listOf("27001"), - observations = "Observations de l'infraction", - registrationNumber = "AB-123-CD", - companyName = "Company Name", - relevantCourt = "LOCAL_COURT", - infractionType = InfractionTypeEnum.WAITING, - formalNotice = FormalNoticeEnum.NO, - toProcess = false, - controlledPersonIdentity = "Captain Flame", - vesselType = VesselTypeEnum.COMMERCIAL, - vesselSize = VesselSizeEnum.FROM_12_TO_24m, - ), - ), - ) + EnvActionControlEntity( + id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + controlPlans = + listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(1), + tagIds = listOf(1, 2), + themeId = 1, + ), + ), + geom = point, + facade = "Outre-Mer", + department = "29", + isAdministrativeControl = false, + isComplianceWithWaterRegulationsControl = false, + isSafetyEquipmentAndStandardsComplianceControl = false, + isSeafarersControl = false, + themes = + listOf( + ThemeEntity( + theme = "Theme 1", + subThemes = listOf("sous theme 1", "sous theme 2"), + ), + ), + observations = "Observations de l'action de contrôle", + actionNumberOfControls = 2, + actionTargetType = ActionTargetTypeEnum.VEHICLE, + vehicleType = VehicleTypeEnum.VEHICLE_LAND, + infractions = + listOf( + InfractionEntity( + id = "d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b", + natinf = listOf("27001"), + observations = "Observations de l'infraction", + registrationNumber = "AB-123-CD", + companyName = "Company Name", + relevantCourt = "LOCAL_COURT", + infractionType = InfractionTypeEnum.WAITING, + formalNotice = FormalNoticeEnum.NO, + toProcess = false, + controlledPersonIdentity = "Captain Flame", + vesselType = VesselTypeEnum.COMMERCIAL, + vesselSize = VesselSizeEnum.FROM_12_TO_24m, + ), + ), + ) val expectedFirstMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.SEA), - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 1, - name = "CU1", - administration = "Admin 1", - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 2, - controlUnitId = 1, - name = "Ressource 2", + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.SEA), + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 1, + name = "CU1", + administration = "Admin 1", + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 2, + controlUnitId = + 1, + name = + "Ressource 2", + ), + ), + isArchived = false, + ), + ), + openBy = "OpenBy", + closedBy = "ClosedBy", + facade = "Outre-Mer", + geom = polygon, + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = + ZonedDateTime.parse("2022-01-23T20:29:03Z"), + observationsCacem = "obs cacem", + observationsCnsp = "obs cnsp", + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + envActions = listOf(controlEnvAction), ), - ), - isArchived = false, - ), - ), - openBy = "OpenBy", - closedBy = "ClosedBy", - facade = "Outre-Mer", - geom = polygon, - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = - ZonedDateTime.parse("2022-01-23T20:29:03Z"), - observationsCacem = "obs cacem", - observationsCnsp = "obs cnsp", - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - envActions = listOf(controlEnvAction), - ), - attachedReportingIds = listOf(1), - attachedReportings = - listOf( - ReportingDTO( - reporting = - ReportingEntity( - id = 1, - reportingId = 2300001, - sourceType = - SourceTypeEnum.SEMAPHORE, - semaphoreId = 1, - targetType = TargetTypeEnum.VEHICLE, - vehicleType = - VehicleTypeEnum - .VEHICLE_LAND, - geom = polygon, - seaFront = "SeaFront", - description = "Description", - reportType = - ReportingTypeEnum - .INFRACTION_SUSPICION, - themeId = 12, - subThemeIds = listOf(82), - actionTaken = "ActionTaken", - isControlRequired = true, - hasNoUnitAvailable = true, - createdAt = - ZonedDateTime.parse( - "2022-01-15T04:50:09Z", - ), - validityTime = 4, - isArchived = false, - isDeleted = false, - openBy = "OpenBy", - ), - semaphore = - SemaphoreEntity( - id = 1, - name = "Semaphore 1", - geom = point, - department = "29", - facade = "Outre-Mer", - administration = "Admin 1", - unit = "Unit 1", - email = "semaphore@", - phoneNumber = "0299999999", - base = "Base 1", - ), - ), - ), - ) + attachedReportingIds = listOf(1), + attachedReportings = + listOf( + ReportingDTO( + reporting = + ReportingEntity( + id = 1, + reportingId = 2300001, + sourceType = + SourceTypeEnum.SEMAPHORE, + semaphoreId = 1, + targetType = TargetTypeEnum.VEHICLE, + vehicleType = + VehicleTypeEnum + .VEHICLE_LAND, + geom = polygon, + seaFront = "SeaFront", + description = "Description", + reportType = + ReportingTypeEnum + .INFRACTION_SUSPICION, + themeId = 12, + subThemeIds = listOf(82), + actionTaken = "ActionTaken", + isControlRequired = true, + hasNoUnitAvailable = true, + createdAt = + ZonedDateTime.parse( + "2022-01-15T04:50:09Z", + ), + validityTime = 4, + isArchived = false, + isDeleted = false, + openBy = "OpenBy", + ), + semaphore = + SemaphoreEntity( + id = 1, + name = "Semaphore 1", + geom = point, + department = "29", + facade = "Outre-Mer", + administration = "Admin 1", + unit = "Unit 1", + email = "semaphore@", + phoneNumber = "0299999999", + base = "Base 1", + ), + ), + ), + ) // we test only if the route is called with the right arg given(getFullMissionById.execute(requestedId)).willReturn(expectedFirstMission) // When mockMvc.perform(get("/bff/v1/missions/$requestedId")) - // Then - .andDo(MockMvcResultHandlers.print()) - .andExpect(status().isOk) - .andExpect(jsonPath("$.missionTypes[0]", equalTo(MissionTypeEnum.SEA.toString()))) - .andExpect(jsonPath("$.id", equalTo(10))) - .andExpect(jsonPath("$.controlUnits[0].id", equalTo(1))) - .andExpect(jsonPath("$.openBy", equalTo("OpenBy"))) - .andExpect(jsonPath("$.closedBy", equalTo("ClosedBy"))) - .andExpect(jsonPath("$.facade", equalTo("Outre-Mer"))) - .andExpect(jsonPath("$.geom.type", equalTo("MultiPolygon"))) - .andExpect(jsonPath("$.startDateTimeUtc", equalTo("2022-01-15T04:50:09Z"))) - .andExpect(jsonPath("$.endDateTimeUtc", equalTo("2022-01-23T20:29:03Z"))) - .andExpect(jsonPath("$.observationsCacem", equalTo("obs cacem"))) - .andExpect(jsonPath("$.observationsCnsp", equalTo("obs cnsp"))) - .andExpect(jsonPath("$.isClosed", equalTo(false))) - .andExpect(jsonPath("$.isDeleted").doesNotExist()) - .andExpect( - jsonPath( - "$.missionSource", - equalTo(MissionSourceEnum.MONITORENV.toString()), - ), - ) - .andExpect(jsonPath("$.hasMissionOrder", equalTo(false))) - .andExpect(jsonPath("$.isUnderJdp", equalTo(false))) - .andExpect(jsonPath("$.attachedReportingIds", equalTo(listOf(1)))) - .andExpect(jsonPath("$.envActions.length()", equalTo(1))) - .andExpect( - jsonPath( - "$.envActions[0].id", - equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - ), - ) - .andExpect(jsonPath("$.envActions[0].actionType", equalTo("CONTROL"))) - .andExpect( - jsonPath( - "$.envActions[0].actionStartDateTimeUtc", - equalTo("2022-01-15T04:50:09Z"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].actionEndDateTimeUtc", - equalTo("2022-01-23T20:29:03Z"), - ), - ) - .andExpect(jsonPath("$.envActions[0].controlPlans[0].themeId", equalTo(1))) - .andExpect(jsonPath("$.envActions[0].controlPlans[0].subThemeIds[0]", equalTo(1))) - .andExpect(jsonPath("$.envActions[0].controlPlans[0].tagIds[0]", equalTo(1))) - .andExpect(jsonPath("$.envActions[0].controlPlans[0].tagIds[1]", equalTo(2))) - .andExpect(jsonPath("$.envActions[0].geom.type", equalTo("Point"))) - .andExpect(jsonPath("$.envActions[0].facade", equalTo("Outre-Mer"))) - .andExpect(jsonPath("$.envActions[0].department", equalTo("29"))) - .andExpect(jsonPath("$.envActions[0].isAdministrativeControl", equalTo(false))) - .andExpect( - jsonPath( - "$.envActions[0].isComplianceWithWaterRegulationsControl", - equalTo(false), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].isSafetyEquipmentAndStandardsComplianceControl", - equalTo(false), - ), - ) - .andExpect(jsonPath("$.envActions[0].isSeafarersControl", equalTo(false))) - .andExpect(jsonPath("$.envActions[0].themes[0].theme", equalTo("Theme 1"))) - .andExpect( - jsonPath("$.envActions[0].themes[0].subThemes[0]", equalTo("sous theme 1")), - ) - .andExpect( - jsonPath("$.envActions[0].themes[0].subThemes[1]", equalTo("sous theme 2")), - ) - .andExpect( - jsonPath( - "$.envActions[0].observations", - equalTo("Observations de l'action de contrôle"), - ), - ) - .andExpect(jsonPath("$.envActions[0].actionNumberOfControls", equalTo(2))) - .andExpect( - jsonPath( - "$.envActions[0].actionTargetType", - equalTo(ActionTargetTypeEnum.VEHICLE.toString()), - ), - ) - .andExpect(jsonPath("$.envActions[0].reportingIds.length()", equalTo(0))) - .andExpect( - jsonPath( - "$.envActions[0].vehicleType", - equalTo(VehicleTypeEnum.VEHICLE_LAND.toString()), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].id", - equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - ), - ) - .andExpect(jsonPath("$.envActions[0].infractions[0].natinf[0]", equalTo("27001"))) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].observations", - equalTo("Observations de l'infraction"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].registrationNumber", - equalTo("AB-123-CD"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].companyName", - equalTo("Company Name"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].relevantCourt", - equalTo("LOCAL_COURT"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].infractionType", - equalTo(InfractionTypeEnum.WAITING.toString()), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].formalNotice", - equalTo(FormalNoticeEnum.NO.toString()), - ), - ) - .andExpect(jsonPath("$.envActions[0].infractions[0].toProcess", equalTo(false))) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].controlledPersonIdentity", - equalTo("Captain Flame"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].vesselType", - equalTo(VesselTypeEnum.COMMERCIAL.toString()), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].vesselSize", - equalTo(VesselSizeEnum.FROM_12_TO_24m.toString()), - ), - ) + // Then + .andDo(MockMvcResultHandlers.print()) + .andExpect(status().isOk) + .andExpect(jsonPath("$.missionTypes[0]", equalTo(MissionTypeEnum.SEA.toString()))) + .andExpect(jsonPath("$.id", equalTo(10))) + .andExpect(jsonPath("$.controlUnits[0].id", equalTo(1))) + .andExpect(jsonPath("$.openBy", equalTo("OpenBy"))) + .andExpect(jsonPath("$.closedBy", equalTo("ClosedBy"))) + .andExpect(jsonPath("$.facade", equalTo("Outre-Mer"))) + .andExpect(jsonPath("$.geom.type", equalTo("MultiPolygon"))) + .andExpect(jsonPath("$.startDateTimeUtc", equalTo("2022-01-15T04:50:09Z"))) + .andExpect(jsonPath("$.endDateTimeUtc", equalTo("2022-01-23T20:29:03Z"))) + .andExpect(jsonPath("$.observationsCacem", equalTo("obs cacem"))) + .andExpect(jsonPath("$.observationsCnsp", equalTo("obs cnsp"))) + .andExpect(jsonPath("$.isClosed", equalTo(false))) + .andExpect(jsonPath("$.isDeleted").doesNotExist()) + .andExpect( + jsonPath( + "$.missionSource", + equalTo(MissionSourceEnum.MONITORENV.toString()), + ), + ) + .andExpect(jsonPath("$.hasMissionOrder", equalTo(false))) + .andExpect(jsonPath("$.isUnderJdp", equalTo(false))) + .andExpect(jsonPath("$.attachedReportingIds", equalTo(listOf(1)))) + .andExpect(jsonPath("$.envActions.length()", equalTo(1))) + .andExpect( + jsonPath( + "$.envActions[0].id", + equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + ), + ) + .andExpect(jsonPath("$.envActions[0].actionType", equalTo("CONTROL"))) + .andExpect( + jsonPath( + "$.envActions[0].actionStartDateTimeUtc", + equalTo("2022-01-15T04:50:09Z"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].actionEndDateTimeUtc", + equalTo("2022-01-23T20:29:03Z"), + ), + ) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].themeId", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].subThemeIds[0]", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].tagIds[0]", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].tagIds[1]", equalTo(2))) + .andExpect(jsonPath("$.envActions[0].geom.type", equalTo("Point"))) + .andExpect(jsonPath("$.envActions[0].facade", equalTo("Outre-Mer"))) + .andExpect(jsonPath("$.envActions[0].department", equalTo("29"))) + .andExpect(jsonPath("$.envActions[0].isAdministrativeControl", equalTo(false))) + .andExpect( + jsonPath( + "$.envActions[0].isComplianceWithWaterRegulationsControl", + equalTo(false), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].isSafetyEquipmentAndStandardsComplianceControl", + equalTo(false), + ), + ) + .andExpect(jsonPath("$.envActions[0].isSeafarersControl", equalTo(false))) + .andExpect(jsonPath("$.envActions[0].themes[0].theme", equalTo("Theme 1"))) + .andExpect( + jsonPath("$.envActions[0].themes[0].subThemes[0]", equalTo("sous theme 1")), + ) + .andExpect( + jsonPath("$.envActions[0].themes[0].subThemes[1]", equalTo("sous theme 2")), + ) + .andExpect( + jsonPath( + "$.envActions[0].observations", + equalTo("Observations de l'action de contrôle"), + ), + ) + .andExpect(jsonPath("$.envActions[0].actionNumberOfControls", equalTo(2))) + .andExpect( + jsonPath( + "$.envActions[0].actionTargetType", + equalTo(ActionTargetTypeEnum.VEHICLE.toString()), + ), + ) + .andExpect(jsonPath("$.envActions[0].reportingIds.length()", equalTo(0))) + .andExpect( + jsonPath( + "$.envActions[0].vehicleType", + equalTo(VehicleTypeEnum.VEHICLE_LAND.toString()), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].id", + equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + ), + ) + .andExpect(jsonPath("$.envActions[0].infractions[0].natinf[0]", equalTo("27001"))) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].observations", + equalTo("Observations de l'infraction"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].registrationNumber", + equalTo("AB-123-CD"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].companyName", + equalTo("Company Name"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].relevantCourt", + equalTo("LOCAL_COURT"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].infractionType", + equalTo(InfractionTypeEnum.WAITING.toString()), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].formalNotice", + equalTo(FormalNoticeEnum.NO.toString()), + ), + ) + .andExpect(jsonPath("$.envActions[0].infractions[0].toProcess", equalTo(false))) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].controlledPersonIdentity", + equalTo("Captain Flame"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].vesselType", + equalTo(VesselTypeEnum.COMMERCIAL.toString()), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].vesselSize", + equalTo(VesselSizeEnum.FROM_12_TO_24m.toString()), + ), + ) verify(getFullMissionById).execute(requestedId) } @@ -772,71 +782,71 @@ class MissionsControllerITests { fun `update mission should return updated mission`() { // Given val expectedUpdatedMission = - MissionDTO( - mission = - MissionEntity( - id = 14, - missionTypes = listOf(MissionTypeEnum.SEA), - observationsCacem = "updated observationsCacem", - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ), - ) + MissionDTO( + mission = + MissionEntity( + id = 14, + missionTypes = listOf(MissionTypeEnum.SEA), + observationsCacem = "updated observationsCacem", + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ), + ) val envAction = - MissionEnvActionDataInput( - id = UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), - actionType = ActionTypeEnum.CONTROL, - actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - actionTargetType = ActionTargetTypeEnum.VEHICLE, - vehicleType = VehicleTypeEnum.VESSEL, - actionNumberOfControls = 4, - reportingIds = Optional.of(listOf(1)), - ) + MissionEnvActionDataInput( + id = UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), + actionType = ActionTypeEnum.CONTROL, + actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + actionTargetType = ActionTargetTypeEnum.VEHICLE, + vehicleType = VehicleTypeEnum.VESSEL, + actionNumberOfControls = 4, + reportingIds = Optional.of(listOf(1)), + ) val requestBody = - CreateOrUpdateMissionDataInput( - id = 14, - missionTypes = listOf(MissionTypeEnum.SEA), - observationsCacem = "updated observationsCacem", - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - envActions = listOf(envAction), - missionSource = MissionSourceEnum.MONITORENV, - isClosed = false, - attachedReportingIds = listOf(1), - ) + CreateOrUpdateMissionDataInput( + id = 14, + missionTypes = listOf(MissionTypeEnum.SEA), + observationsCacem = "updated observationsCacem", + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + envActions = listOf(envAction), + missionSource = MissionSourceEnum.MONITORENV, + isClosed = false, + attachedReportingIds = listOf(1), + ) val envActionsAttachedToReportingIds = - listOf( - Pair(UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), listOf(1)), - ) as - List + listOf( + Pair(UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), listOf(1)), + ) as + List given( - createOrUpdateMissionWithAttachedReporting.execute( - mission = requestBody.toMissionEntity(), - attachedReportingIds = listOf(1), - envActionsAttachedToReportingIds = envActionsAttachedToReportingIds, - ), - ) - .willReturn(expectedUpdatedMission) + createOrUpdateMissionWithAttachedReporting.execute( + mission = requestBody.toMissionEntity(), + attachedReportingIds = listOf(1), + envActionsAttachedToReportingIds = envActionsAttachedToReportingIds, + ), + ) + .willReturn(expectedUpdatedMission) // When mockMvc.perform( - put("/bff/v1/missions/14") - .content(objectMapper.writeValueAsString(requestBody)) - .contentType(MediaType.APPLICATION_JSON), - ) - // Then - .andExpect(status().isOk) - .andExpect( - jsonPath( - "$.observationsCacem", - equalTo(expectedUpdatedMission.mission.observationsCacem), - ), - ) + put("/bff/v1/missions/14") + .content(objectMapper.writeValueAsString(requestBody)) + .contentType(MediaType.APPLICATION_JSON), + ) + // Then + .andExpect(status().isOk) + .andExpect( + jsonPath( + "$.observationsCacem", + equalTo(expectedUpdatedMission.mission.observationsCacem), + ), + ) } @Test @@ -844,34 +854,35 @@ class MissionsControllerITests { // Given // When mockMvc.perform(delete("/bff/v1/missions/20")) - // Then - .andExpect(status().isOk) + // Then + .andExpect(status().isOk) Mockito.verify(deleteMission).execute(20) } @Test fun `Should get all engaged control units`() { // Given - given(getEngagedControlUnits.execute()).willReturn( - listOf( - Pair( - LegacyControlUnitEntity( - id = 123, - administration = "Admin", - resources = listOf(), - isArchived = false, - name = "Control Unit Name", - ), - listOf(MissionSourceEnum.MONITORFISH), - ), - ), - ) + given(getEngagedControlUnits.execute()) + .willReturn( + listOf( + Pair( + LegacyControlUnitEntity( + id = 123, + administration = "Admin", + resources = listOf(), + isArchived = false, + name = "Control Unit Name", + ), + listOf(MissionSourceEnum.MONITORFISH), + ), + ), + ) // When mockMvc.perform(get("/bff/v1/missions/engaged_control_units")) - // Then - .andExpect(status().isOk) - .andExpect(jsonPath("$[0].controlUnit.name", equalTo("Control Unit Name"))) - .andExpect(jsonPath("$[0].missionSources[0]", equalTo("MONITORFISH"))) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$[0].controlUnit.name", equalTo("Control Unit Name"))) + .andExpect(jsonPath("$[0].missionSources[0]", equalTo("MONITORFISH"))) } } From a6160ddf7d4916dfc5f53eeebadcf8817b61c464 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Wed, 6 Dec 2023 15:58:09 +0100 Subject: [PATCH 26/53] fix test --- .../EnvActionsControlPlanSubThemeModel.kt | 2 +- .../JpaMissionRepositoryITests.kt | 1476 ++++++++++------- 2 files changed, 915 insertions(+), 563 deletions(-) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt index 50840de2c..3667b6370 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt @@ -24,7 +24,7 @@ class EnvActionsControlPlanSubThemeModel( @JoinColumn(name = "env_action_id") val envAction: EnvActionModel? = null, - @ManyToOne(fetch = FetchType.EAGER) + @ManyToOne(fetch = FetchType.LAZY) @MapsId("subthemeId") @JoinColumn(name = "subtheme_id") val controlPlanSubTheme: ControlPlanSubThemeModel? = null, diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt index 19c5fada6..4ade9340b 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt @@ -13,6 +13,8 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionContr import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.* import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO +import java.time.ZonedDateTime +import java.util.* import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.catchThrowable import org.junit.jupiter.api.Test @@ -25,8 +27,6 @@ import org.springframework.dao.InvalidDataAccessApiUsageException import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Pageable import org.springframework.transaction.annotation.Transactional -import java.time.ZonedDateTime -import java.util.* class JpaMissionRepositoryITests : AbstractDBTests() { @Autowired private lateinit var jpaMissionRepository: JpaMissionRepository @@ -36,9 +36,12 @@ class JpaMissionRepositoryITests : AbstractDBTests() { @Autowired private lateinit var jpaControlUnitResourceRepository: JpaControlUnitResourceRepository - private val polygon = WKTReader().read( - "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))", - ) as MultiPolygon + private val polygon = + WKTReader() + .read( + "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))", + ) as + MultiPolygon private val point = WKTReader().read("POINT (-4.54877816747593 48.305559876971)") as Point @Test @@ -46,14 +49,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `delete Should set the deleted flag as true`() { // Given val missionsList = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missionsList).hasSize(21) // When @@ -61,14 +64,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { // Then val nextMissionList = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(nextMissionList).hasSize(20) } @@ -77,14 +80,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return all missions when only required startedAfter is set to a very old date`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(54) } @@ -93,14 +96,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when startedAfter & startedBefore are set`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(21) } @@ -109,14 +112,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when missionTypes is set`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = listOf("SEA"), - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = listOf("SEA"), + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(22) } @@ -125,14 +128,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when multiple missionTypes are set`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = listOf("SEA", "LAND"), - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = listOf("SEA", "LAND"), + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(45) } @@ -141,14 +144,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when seaFront is set to MEMN`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = listOf("MEMN"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = listOf("MEMN"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(9) } @@ -157,14 +160,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when seaFront is set to MEMN and NAMO`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = listOf("MEMN", "NAMO"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = listOf("MEMN", "NAMO"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(27) } @@ -173,14 +176,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when status is set to UPCOMING`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("UPCOMING"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("UPCOMING"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(7) } @@ -189,14 +192,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when status is set to PENDING`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("PENDING"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("PENDING"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(14) } @@ -205,14 +208,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when status is set to ENDED`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("ENDED"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("ENDED"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(15) } @@ -221,14 +224,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when status is set to CLOSED`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("CLOSED"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("CLOSED"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(18) } @@ -237,14 +240,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when status is set to CLOSED or UPCOMING`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("CLOSED", "UPCOMING"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("CLOSED", "UPCOMING"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(25) } @@ -253,14 +256,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll with pagenumber and pagesize Should return subset of missions`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = PageRequest.of(1, 10), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = PageRequest.of(1, 10), + ) assertThat(missions).hasSize(10) } @@ -269,20 +272,265 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll should filter missions based on MissionSources`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = null, - missionSources = - listOf( - MissionSourceEnum.MONITORFISH, - MissionSourceEnum.POSEIDON_CACEM, - MissionSourceEnum.POSEIDON_CNSP, - ), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = null, + missionSources = + listOf( + MissionSourceEnum.MONITORFISH, + MissionSourceEnum.POSEIDON_CACEM, + MissionSourceEnum.POSEIDON_CNSP, + ), + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(3) + } + + @Test + @Transactional + fun `delete Should set the deleted flag as true`() { + // Given + val missionsList = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) + assertThat(missionsList).hasSize(21) + + // When + jpaMissionRepository.delete(3) + + // Then + val nextMissionList = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) + assertThat(nextMissionList).hasSize(20) + } + + @Test + @Transactional + fun `findAll Should return all missions when only required startedAfter is set to a very old date`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(53) + } + + @Test + @Transactional + fun `findAll Should return filtered missions when startedAfter & startedBefore are set`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(21) + } + + @Test + @Transactional + fun `findAll Should return filtered missions when missionTypes is set`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = listOf("SEA"), + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(21) + } + + @Test + @Transactional + fun `findAll Should return filtered missions when multiple missionTypes are set`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = listOf("SEA", "LAND"), + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(44) + } + + @Test + @Transactional + fun `findAll Should return filtered missions when seaFront is set to MEMN`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = listOf("MEMN"), + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(9) + } + + @Test + @Transactional + fun `findAll Should return filtered missions when seaFront is set to MEMN and NAMO`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = listOf("MEMN", "NAMO"), + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(26) + } + + @Test + @Transactional + fun `findAll Should return filtered missions when status is set to UPCOMING`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("UPCOMING"), + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(6) + } + + @Test + @Transactional + fun `findAll Should return filtered missions when status is set to PENDING`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("PENDING"), + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(14) + } + + @Test + @Transactional + fun `findAll Should return filtered missions when status is set to ENDED`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("ENDED"), + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(15) + } + + @Test + @Transactional + fun `findAll Should return filtered missions when status is set to CLOSED`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("CLOSED"), + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(18) + } + + @Test + @Transactional + fun `findAll Should return filtered missions when status is set to CLOSED or UPCOMING`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("CLOSED", "UPCOMING"), + pageable = Pageable.unpaged(), + ) + assertThat(missions).hasSize(24) + } + + @Test + @Transactional + fun `findAll with pagenumber and pagesize Should return subset of missions`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = PageRequest.of(1, 10), + ) + assertThat(missions).hasSize(10) + } + + @Test + @Transactional + fun `findAll should filter missions based on MissionSources`() { + // When + val missions = + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = null, + missionSources = + listOf( + MissionSourceEnum.MONITORFISH, + MissionSourceEnum.POSEIDON_CACEM, + MissionSourceEnum.POSEIDON_CNSP, + ), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(3) } @@ -307,62 +555,154 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findById Should return specified mission`() { // When val firstMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - openBy = "KIM", - closedBy = "TRA", - facade = "NAMO", - observationsCacem = - "Remain vote several ok. Bring American play woman challenge. Throw low law positive seven.", - startDateTimeUtc = - ZonedDateTime.parse("2022-03-21T12:11:13Z"), - endDateTimeUtc = null, - geom = polygon, - isClosed = false, - isDeleted = false, - envActions = listOf(), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10002, - administration = "DDTM", - isArchived = false, - name = "DML 2A", - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 3, - controlUnitId = - 10002, - name = - "Semi-rigide 1", - ), - LegacyControlUnitResourceEntity( - id = 4, - controlUnitId = - 10002, - name = - "Semi-rigide 2", + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + openBy = "KIM", + closedBy = "TRA", + facade = "NAMO", + observationsCacem = + "Remain vote several ok. Bring American play woman challenge. Throw low law positive seven.", + startDateTimeUtc = + ZonedDateTime.parse("2022-03-21T12:11:13Z"), + endDateTimeUtc = null, + geom = polygon, + isClosed = false, + isDeleted = false, + envActions = listOf(), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10002, + administration = "DDTM", + isArchived = false, + name = "DML 2A", + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 3, + controlUnitId = + 10002, + name = + "Semi-rigide 1", + ), + LegacyControlUnitResourceEntity( + id = 4, + controlUnitId = + 10002, + name = + "Semi-rigide 2", + ), + LegacyControlUnitResourceEntity( + id = 5, + controlUnitId = + 10002, + name = + "Voiture", + ), + ), + ), + ), + isGeometryComputedFromControls = false, ), - LegacyControlUnitResourceEntity( - id = 5, - controlUnitId = - 10002, - name = - "Voiture", + ) + val mission = jpaMissionRepository.findFullMissionById(10) + + assertThat(mission).isEqualTo(firstMission) + } + + @Test + @Transactional + fun `findById Should return specified mission and associated env actions and associated envActionReportingIds`() { + // When + val missionDTO = jpaMissionRepository.findFullMissionById(34) + assertThat(missionDTO.mission.id).isEqualTo(34) + assertThat(missionDTO.mission.envActions).hasSize(2) + assertThat( + missionDTO.envActionsAttachedToReportingIds?.get(0)?.first, + ) + .isEqualTo(UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807")) + assertThat(missionDTO.envActionsAttachedToReportingIds?.get(0)?.second).isEqualTo(listOf(6)) + } + + @Test + @Transactional + fun `findByIds() should find the matching missions`() { + val foundMissions = jpaMissionRepository.findByIds(listOf(50, 51, 52)) + + assertThat(foundMissions).hasSize(3) + } + + @Test + @Transactional + fun `findById Should return specified mission`() { + // When + val wktReader = WKTReader() + val multipolygonString = + "MULTIPOLYGON (((-4.99360539 48.42853215, -4.99359905 48.42848997, -4.99359291 48.42844777, -4.99358697 48.42840556, -4.99358123 48.42836334, -4.99357569 48.4283211, -4.99357035 48.42827886, -4.9935652 48.4282366, -4.99356026 48.42819434, -4.99355552 48.42815206, -4.99355097 48.42810977, -4.99354663 48.42806748, -4.99354249 48.42802517, -4.99353854 48.42798286, -4.9935348 48.42794054, -4.99353125 48.42789821, -4.99352791 48.42785587, -4.99352476 48.42781353, -4.99352182 48.42777118, -4.99351907 48.42772882, -4.99351653 48.42768646, -4.99351418 48.4276441, -4.99351203 48.42760173, -4.99351009 48.42755935, -4.99350834 48.42751697, -4.9935068 48.42747459, -4.99350545 48.42743221, -4.99350431 48.42738982, -4.99350336 48.42734743, -4.99350262 48.42730504, -4.99350207 48.42726264, -4.99350173 48.42722025, -4.99350158 48.42717785, -4.99350164 48.42713546, -4.99350189 48.42709307, -4.99350235 48.42705067, -4.99350301 48.42700828, -4.99350386 48.42696589, -4.99350492 48.4269235, -4.99350617 48.42688111, -4.99350763 48.42683873, -4.99350929 48.42679635, -4.99351114 48.42675397, -4.9935132 48.4267116, -4.99351545 48.42666923, -4.99351791 48.42662687, -4.99352057 48.42658451, -4.99352342 48.42654216, -4.99352648 48.42649981, -4.99352973 48.42645747, -4.99353319 48.42641514, -4.99353685 48.42637282, -4.9935407 48.4263305, -4.99354476 48.42628819, -4.99354901 48.42624589, -4.99355346 48.4262036, -4.99355812 48.42616132, -4.99356297 48.42611905, -4.99356802 48.42607679, -4.99357328 48.42603454, -4.99357873 48.4259923, -4.99358438 48.42595007, -4.99359023 48.42590785, -4.99359628 48.42586565, -4.99360253 48.42582346, -4.99360898 48.42578128, -4.99361562 48.42573912, -4.99362247 48.42569697, -4.99362951 48.42565484, -4.99363676 48.42561272, -4.9936442 48.42557061, -4.99365184 48.42552853, -4.99365968 48.42548645, -4.99366772 48.4254444, -4.99367596 48.42540236, -4.99368439 48.42536034, -4.99369302 48.42531833, -4.99370186 48.42527635, -4.99371089 48.42523438, -4.99372011 48.42519243, -4.99372954 48.42515051, -4.99373916 48.4251086, -4.99374898 48.42506671, -4.993759 48.42502484, -4.99376922 48.424983, -4.99377963 48.42494117, -4.99379024 48.42489937, -4.99380105 48.42485759, -4.99381206 48.42481583, -4.99382326 48.4247741, -4.99383466 48.42473239, -4.99384626 48.4246907, -4.99385805 48.42464904, -4.99387004 48.42460741, -4.99388223 48.42456579, -4.99389461 48.42452421, -4.99390719 48.42448265, -4.99391996 48.42444111, -4.99393293 48.42439961, -4.9939461 48.42435813, -4.99395946 48.42431668, -4.99397302 48.42427525, -4.99398677 48.42423386, -4.99400072 48.42419249, -4.99401487 48.42415116, -4.9940292 48.42410985, -4.99404374 48.42406857, -4.99405847 48.42402733, -4.99407339 48.42398611, -4.99408851 48.42394493, -4.99410382 48.42390378, -4.99411932 48.42386266, -4.99413502 48.42382157, -4.99415092 48.42378052, -4.994167 48.4237395, -4.99418328 48.42369851, -4.99419976 48.42365756, -4.99421643 48.42361664, -4.99423329 48.42357576, -4.99425034 48.42353491, -4.99426759 48.4234941, -4.99428502 48.42345333, -4.99430265 48.42341259, -4.99432048 48.42337189, -4.99433849 48.42333122, -4.9943567 48.4232906, -4.9943751 48.42325001, -4.99439369 48.42320946, -4.99441247 48.42316895, -4.99443144 48.42312848, -4.9944506 48.42308805, -4.99446996 48.42304766, -4.9944895 48.42300731, -4.99450924 48.422967, -4.99452916 48.42292673, -4.99454928 48.42288651, -4.99456958 48.42284633, -4.99459007 48.42280619, -4.99461076 48.42276609, -4.99463163 48.42272603, -4.99465269 48.42268602, -4.99467394 48.42264606, -4.99469538 48.42260614, -4.99471701 48.42256626, -4.99473882 48.42252643, -4.99476082 48.42248665, -4.99478301 48.42244691, -4.99480539 48.42240721, -4.99482796 48.42236757, -4.99485071 48.42232797, -4.99487365 48.42228842, -4.99489677 48.42224892, -4.99492008 48.42220947, -4.99494358 48.42217006, -4.99496727 48.42213071, -4.99499113 48.4220914, -4.99501519 48.42205215, -4.99503943 48.42201294, -4.99506385 48.42197379, -4.99508846 48.42193469, -4.99511326 48.42189563, -4.99513823 48.42185664, -4.99516339 48.42181769, -4.99518874 48.4217788, -4.99521427 48.42173995, -4.99523998 48.42170117, -4.99526587 48.42166243, -4.99529195 48.42162376, -4.99531821 48.42158513, -4.99534465 48.42154656, -4.99537128 48.42150805, -4.99539808 48.42146959, -4.99542507 48.42143119, -4.99545224 48.42139285, -4.99547959 48.42135456, -4.99550711 48.42131633, -4.99553482 48.42127816, -4.99556271 48.42124004, -4.99559078 48.42120199, -4.99561903 48.42116399, -4.99564746 48.42112605, -4.99567606 48.42108817, -4.99570485 48.42105035, -4.99573381 48.4210126, -4.99576295 48.4209749, -4.99579227 48.42093726, -4.99582177 48.42089969, -4.99585144 48.42086218, -4.99588129 48.42082473, -4.99591132 48.42078734, -4.99594152 48.42075001, -4.9959719 48.42071275, -4.99600246 48.42067555, -4.99603319 48.42063842, -4.9960641 48.42060135, -4.99609518 48.42056435, -4.99612643 48.42052741, -4.99615786 48.42049053, -4.99618946 48.42045372, -4.99622124 48.42041698, -4.99625319 48.42038031, -4.99628531 48.4203437, -4.9963176 48.42030716, -4.99635007 48.42027069, -4.99638271 48.42023428, -4.99641552 48.42019794, -4.9964485 48.42016168, -4.99648166 48.42012548, -4.99651498 48.42008935, -4.99654847 48.42005329, -4.99658214 48.4200173, -4.99661597 48.41998138, -4.99664997 48.41994553, -4.99668415 48.41990976, -4.99671849 48.41987405, -4.996753 48.41983842, -4.99678767 48.41980286, -4.99682252 48.41976737, -4.99685753 48.41973196, -4.99689271 48.41969662, -4.99692805 48.41966135, -4.99696356 48.41962616, -4.99699924 48.41959104, -4.99703508 48.41955599, -4.99707109 48.41952102, -4.99710726 48.41948613, -4.9971436 48.41945131, -4.9971801 48.41941657, -4.99721677 48.4193819, -4.9972536 48.41934732, -4.99729059 48.4193128, -4.99732774 48.41927837, -4.99736506 48.41924402, -4.99740254 48.41920974, -4.99744018 48.41917554, -4.99747798 48.41914142, -4.99751594 48.41910738, -4.99755406 48.41907342, -4.99759234 48.41903953, -4.99763079 48.41900573, -4.99766939 48.41897201, -4.99770815 48.41893837, -4.99774707 48.41890481, -4.99778614 48.41887133, -4.99782538 48.41883794, -4.99786477 48.41880463, -4.99790432 48.4187714, -4.99794402 48.41873825, -4.99798388 48.41870518, -4.9980239 48.4186722, -4.99806408 48.4186393, -4.9981044 48.41860649, -4.99814489 48.41857376, -4.99818552 48.41854112, -4.99822631 48.41850856, -4.99826726 48.41847609, -4.99830835 48.4184437, -4.9983496 48.4184114, -4.99839101 48.41837918, -4.99843256 48.41834705, -4.99847426 48.41831501, -4.99851612 48.41828306, -4.99855813 48.41825119, -4.99860028 48.41821941, -4.99864259 48.41818772, -4.99868504 48.41815612, -4.99872765 48.41812461, -4.9987704 48.41809319, -4.9988133 48.41806185, -4.99885635 48.41803061, -4.99889955 48.41799946, -4.99894289 48.41796839, -4.99898638 48.41793742, -4.99903001 48.41790654, -4.99907379 48.41787575, -4.99911772 48.41784505, -4.99916179 48.41781444, -4.999206 48.41778393, -4.99925036 48.41775351, -4.99929486 48.41772318, -4.99933951 48.41769294, -4.99938429 48.4176628, -4.99942922 48.41763276, -4.99947429 48.4176028, -4.9995195 48.41757294, -4.99956485 48.41754318, -4.99961035 48.41751351, -4.99965598 48.41748393, -4.99970175 48.41745445, -4.99974766 48.41742507, -4.99979371 48.41739578, -4.99983989 48.41736659, -4.99988622 48.4173375, -4.99993268 48.4173085, -4.99997927 48.4172796, -5.00002601 48.4172508, -5.00007288 48.4172221, -5.00011988 48.41719349, -5.00016702 48.41716498, -5.00021429 48.41713657, -5.0002617 48.41710826, -5.00030924 48.41708005, -5.00035691 48.41705194, -5.00040472 48.41702393, -5.00045266 48.41699602, -5.00050072 48.41696821, -5.00054892 48.4169405, -5.00059725 48.41691289, -5.00064571 48.41688538, -5.0006943 48.41685797, -5.00074302 48.41683067, -5.00079187 48.41680346, -5.00084085 48.41677636, -5.00088995 48.41674937, -5.00093918 48.41672247, -5.00098854 48.41669568, -5.00103802 48.41666899, -5.00108763 48.4166424, -5.00113736 48.41661592, -5.00118722 48.41658954, -5.0012372 48.41656327, -5.00128731 48.4165371, -5.00133754 48.41651104, -5.00138789 48.41648508, -5.00143837 48.41645923, -5.00148896 48.41643348, -5.00153968 48.41640784, -5.00159052 48.4163823, -5.00164148 48.41635688, -5.00169256 48.41633155, -5.00174375 48.41630634, -5.00179507 48.41628123, -5.0018465 48.41625623, -5.00189805 48.41623134, -5.00194972 48.41620655, -5.00200151 48.41618187, -5.00205341 48.41615731, -5.00210543 48.41613285, -5.00215756 48.4161085, -5.00220981 48.41608425, -5.00226217 48.41606012, -5.00231465 48.4160361, -5.00236723 48.41601219, -5.00241993 48.41598838, -5.00247275 48.41596469, -5.00252567 48.41594111, -5.00257871 48.41591764, -5.00263185 48.41589428, -5.00268511 48.41587103, -5.00273847 48.41584789, -5.00279195 48.41582486, -5.00284553 48.41580195, -5.00289922 48.41577915, -5.00295301 48.41575646, -5.00300692 48.41573388, -5.00306093 48.41571142, -5.00311504 48.41568907, -5.00316927 48.41566683, -5.00322359 48.4156447, -5.00327802 48.41562269, -5.00333255 48.4156008, -5.00338719 48.41557901, -5.00344193 48.41555735, -5.00349677 48.41553579, -5.00355171 48.41551435, -5.00360676 48.41549303, -5.0036619 48.41547182, -5.00371714 48.41545073, -5.00377249 48.41542975, -5.00382793 48.41540889, -5.00388347 48.41538814, -5.0039391 48.41536751, -5.00399484 48.415347, -5.00405067 48.4153266, -5.00410659 48.41530632, -5.00416261 48.41528616, -5.00421873 48.41526611, -5.00427494 48.41524619, -5.00433125 48.41522638, -5.00438764 48.41520668, -5.00444413 48.41518711, -5.00450072 48.41516765, -5.00455739 48.41514831, -5.00461416 48.41512909, -5.00467101 48.41510999, -5.00472796 48.41509101, -5.00478499 48.41507215, -5.00484211 48.41505341, -5.00489932 48.41503478, -5.00495662 48.41501628, -5.00501401 48.4149979, -5.00507148 48.41497963, -5.00512904 48.41496149, -5.00518668 48.41494347, -5.00524441 48.41492556, -5.00530222 48.41490778, -5.00536012 48.41489012, -5.0054181 48.41487258, -5.00547616 48.41485516, -5.0055343 48.41483786, -5.00559252 48.41482069, -5.00565083 48.41480364, -5.00570921 48.4147867, -5.00576768 48.4147699, -5.00582622 48.41475321, -5.00588485 48.41473664, -5.00594355 48.4147202, -5.00600232 48.41470388, -5.00606118 48.41468769, -5.00612011 48.41467161, -5.00617911 48.41465566, -5.00623819 48.41463984, -5.00629735 48.41462414, -5.00635658 48.41460856, -5.00641588 48.4145931, -5.00647525 48.41457777, -5.0065347 48.41456257, -5.00659422 48.41454748, -5.00665381 48.41453253, -5.00671347 48.41451769, -5.0067732 48.41450298, -5.00683299 48.4144884, -5.00689286 48.41447394, -5.00695279 48.41445961, -5.0070128 48.4144454, -5.00707286 48.41443132, -5.007133 48.41441736, -5.0071932 48.41440353, -5.00725346 48.41438983, -5.00731379 48.41437625, -5.00737419 48.4143628, -5.00743464 48.41434947, -5.00749516 48.41433627, -5.00755574 48.4143232, -5.00761638 48.41431025, -5.00767709 48.41429743, -5.00773785 48.41428474, -5.00779867 48.41427218, -5.00785955 48.41425974, -5.00792049 48.41424743, -5.00798149 48.41423525, -5.00804255 48.41422319, -5.00810366 48.41421126, -5.00816482 48.41419946, -5.00822605 48.41418779, -5.00828732 48.41417625, -5.00834866 48.41416483, -5.00841004 48.41415354, -5.00847148 48.41414238, -5.00853297 48.41413135, -5.00859451 48.41412045, -5.0086561 48.41410968, -5.00871775 48.41409903, -5.00877944 48.41408852, -5.00884119 48.41407813, -5.00890298 48.41406787, -5.00896482 48.41405775, -5.0090267 48.41404775, -5.00908864 48.41403788, -5.00915062 48.41402814, -5.00921264 48.41401853, -5.00927471 48.41400905, -5.00933683 48.4139997, -5.00939899 48.41399048, -5.00946119 48.41398139, -5.00952344 48.41397243, -5.00958572 48.4139636, -5.00964805 48.4139549, -5.00971042 48.41394633, -5.00977283 48.41393789, -5.00983528 48.41392958, -5.00989777 48.4139214, -5.00996029 48.41391335, -5.01002285 48.41390544, -5.01008545 48.41389765, -5.01014809 48.41389, -5.01021076 48.41388247, -5.01027347 48.41387508, -5.01033621 48.41386782, -5.01039899 48.41386069, -5.0104618 48.41385369, -5.01052464 48.41384682, -5.01058752 48.41384009, -5.01065042 48.41383348, -5.01071336 48.41382701, -5.01077633 48.41382067, -5.01083932 48.41381446, -5.01090235 48.41380838, -5.0109654 48.41380243, -5.01102848 48.41379662, -5.01109159 48.41379094, -5.01115473 48.41378539, -5.01121789 48.41377997, -5.01128107 48.41377468, -5.01134429 48.41376953, -5.01140752 48.41376451, -5.01147078 48.41375962, -5.01153406 48.41375486, -5.01159736 48.41375023, -5.01166069 48.41374574, -5.01172403 48.41374138, -5.0117874 48.41373715, -5.01185078 48.41373306, -5.01191419 48.41372909, -5.01197761 48.41372526, -5.01204105 48.41372157, -5.01210451 48.413718, -5.01216798 48.41371457, -5.01223147 48.41371127, -5.01229498 48.4137081, -5.0123585 48.41370507, -5.01242203 48.41370217, -5.01248558 48.4136994, -5.01254914 48.41369676, -5.01261271 48.41369426, -5.0126763 48.41369189, -5.01273989 48.41368965, -5.0128035 48.41368755, -5.01286711 48.41368558, -5.01293073 48.41368374, -5.01299437 48.41368204, -5.013058 48.41368047, -5.01312165 48.41367903, -5.0131853 48.41367772, -5.01324896 48.41367655, -5.01331263 48.41367551, -5.0133763 48.41367461, -5.01343997 48.41367383, -5.01350364 48.41367319, -5.01356732 48.41367269, -5.013631 48.41367231, -5.01369469 48.41367207, -5.01375837 48.41367197, -5.01382205 48.41367199, -5.01388573 48.41367215, -5.01394942 48.41367244, -5.0140131 48.41367287, -5.01407677 48.41367343, -5.01414045 48.41367412, -5.01420412 48.41367494, -5.01426779 48.4136759, -5.01433145 48.41367699, -5.01439511 48.41367822, -5.01445876 48.41367957, -5.0145224 48.41368106, -5.01458604 48.41368269, -5.01464966 48.41368444, -5.01471328 48.41368633, -5.0147769 48.41368836, -5.0148405 48.41369051, -5.01490409 48.4136928, -5.01496767 48.41369522, -5.01503123 48.41369778, -5.01509479 48.41370046, -5.01515833 48.41370328, -5.01522186 48.41370624, -5.01528537 48.41370932, -5.01534887 48.41371254, -5.01541236 48.41371589, -5.01547582 48.41371938, -5.01553928 48.41372299, -5.01560271 48.41372674, -5.01566613 48.41373062, -5.01572952 48.41373464, -5.0157929 48.41373879, -5.01585626 48.41374307, -5.0159196 48.41374748, -5.01598291 48.41375202, -5.01604621 48.4137567, -5.01610948 48.41376151, -5.01617273 48.41376645, -5.01623595 48.41377152, -5.01629915 48.41377673, -5.01636233 48.41378207, -5.01642548 48.41378754, -5.01648861 48.41379314, -5.01655171 48.41379887, -5.01661478 48.41380474, -5.01667782 48.41381074, -5.01674083 48.41381687, -5.01680382 48.41382313, -5.01686677 48.41382952, -5.0169297 48.41383605, -5.01699259 48.4138427, -5.01705545 48.41384949, -5.01711828 48.41385641, -5.01718108 48.41386346, -5.01724384 48.41387064, -5.01730657 48.41387795, -5.01736927 48.4138854, -5.01743192 48.41389297, -5.01749455 48.41390068, -5.01755713 48.41390851, -5.01761968 48.41391648, -5.01768219 48.41392458, -5.01774467 48.41393281, -5.0178071 48.41394117, -5.01786949 48.41394966, -5.01793185 48.41395828, -5.01799416 48.41396703, -5.01805643 48.41397591, -5.01811866 48.41398492, -5.01818084 48.41399406, -5.01824298 48.41400333, -5.01830508 48.41401274, -5.01836714 48.41402227, -5.01842914 48.41403193, -5.01849111 48.41404172, -5.01855302 48.41405164, -5.01861489 48.41406169, -5.01867671 48.41407186, -5.01873848 48.41408217, -5.01880021 48.41409261, -5.01886188 48.41410317, -5.01892351 48.41411387, -5.01898508 48.41412469, -5.0190466 48.41413565, -5.01910807 48.41414673, -5.01916949 48.41415794, -5.01923085 48.41416927, -5.01929216 48.41418074, -5.01935342 48.41419233, -5.01941462 48.41420405, -5.01947577 48.4142159, -5.01953686 48.41422788, -5.01959789 48.41423999, -5.01965886 48.41425222, -5.01971978 48.41426458, -5.01978064 48.41427707, -5.01984144 48.41428968, -5.01990218 48.41430242, -5.01996286 48.41431529, -5.02002348 48.41432829, -5.02008403 48.41434141, -5.02014453 48.41435466, -5.02020496 48.41436804, -5.02026533 48.41438154, -5.02032563 48.41439517, -5.02038587 48.41440892, -5.02044604 48.4144228, -5.02050615 48.4144368, -5.0205662 48.41445093, -5.02062617 48.41446519, -5.02068608 48.41447957, -5.02074592 48.41449408, -5.02080569 48.41450871, -5.02086539 48.41452347, -5.02092502 48.41453835, -5.02098458 48.41455336, -5.02104407 48.41456849, -5.02110349 48.41458374, -5.02116284 48.41459912, -5.02122211 48.41461463, -5.02128131 48.41463025, -5.02134044 48.414646, -5.02139949 48.41466188, -5.02145847 48.41467788, -5.02151737 48.414694, -5.02157619 48.41471024, -5.02163494 48.41472661, -5.02169361 48.4147431, -5.0217522 48.41475971, -5.02181071 48.41477644, -5.02186915 48.4147933, -5.0219275 48.41481028, -5.02198577 48.41482738, -5.02204397 48.4148446, -5.02210208 48.41486195, -5.02216011 48.41487941, -5.02221805 48.414897, -5.02227592 48.41491471, -5.0223337 48.41493254, -5.02239139 48.41495049, -5.022449 48.41496856, -5.02250653 48.41498675, -5.02256396 48.41500506, -5.02262132 48.41502349, -5.02267858 48.41504204, -5.02273576 48.41506071, -5.02279285 48.4150795, -5.02284984 48.41509841, -5.02290675 48.41511744, -5.02296357 48.41513659, -5.0230203 48.41515585, -5.02307694 48.41517524, -5.02313349 48.41519474, -5.02318994 48.41521436, -5.0232463 48.4152341, -5.02330257 48.41525395, -5.02335875 48.41527393, -5.02341483 48.41529402, -5.02347081 48.41531423, -5.0235267 48.41533455, -5.02358249 48.41535499, -5.02363819 48.41537555, -5.02369379 48.41539623, -5.02374929 48.41541702, -5.02380469 48.41543793, -5.02385999 48.41545895, -5.0239152 48.41548009, -5.0239703 48.41550134, -5.02402531 48.41552271, -5.02408021 48.41554419, -5.02413501 48.41556579, -5.02418971 48.41558751, -5.02424431 48.41560933, -5.0242988 48.41563127, -5.02435319 48.41565333, -5.02440747 48.4156755, -5.02446165 48.41569778, -5.02451573 48.41572017, -5.0245697 48.41574268, -5.02462356 48.4157653, -5.02467731 48.41578804, -5.02473096 48.41581088, -5.0247845 48.41583384, -5.02483793 48.41585691, -5.02489126 48.41588009, -5.02494447 48.41590338, -5.02499757 48.41592679, -5.02505056 48.4159503, -5.02510344 48.41597393, -5.02515621 48.41599766, -5.02520887 48.41602151, -5.02526141 48.41604547, -5.02531384 48.41606953, -5.02536616 48.41609371, -5.02541836 48.41611799, -5.02547045 48.41614238, -5.02552242 48.41616689, -5.02557428 48.4161915, -5.02562602 48.41621622, -5.02567764 48.41624104, -5.02572915 48.41626598, -5.02578054 48.41629102, -5.02583181 48.41631617, -5.02588296 48.41634143, -5.02593399 48.41636679, -5.0259849 48.41639226, -5.02603569 48.41641784, -5.02608636 48.41644352, -5.02613691 48.41646931, -5.02618734 48.4164952, -5.02623764 48.4165212, -5.02628782 48.41654731, -5.02633788 48.41657352, -5.02638782 48.41659983, -5.02643763 48.41662625, -5.02648731 48.41665277, -5.02653687 48.4166794, -5.02658631 48.41670613, -5.02663561 48.41673296, -5.02668479 48.41675989, -5.02673385 48.41678693, -5.02678277 48.41681407, -5.02683157 48.41684132, -5.02688024 48.41686866, -5.02692878 48.41689611, -5.02697719 48.41692366, -5.02702547 48.4169513, -5.02707362 48.41697905, -5.02712163 48.4170069, -5.02716952 48.41703485, -5.02721727 48.4170629, -5.02726489 48.41709105, -5.02731238 48.4171193, -5.02735974 48.41714765, -5.02740696 48.4171761, -5.02745404 48.41720465, -5.027501 48.41723329, -5.02754781 48.41726203, -5.02759449 48.41729087, -5.02764104 48.41731981, -5.02768744 48.41734885, -5.02773371 48.41737798, -5.02777985 48.41740721, -5.02782584 48.41743653, -5.02787169 48.41746595, -5.02791741 48.41749547, -5.02796299 48.41752508, -5.02800843 48.41755479, -5.02805372 48.41758459, -5.02809888 48.41761449, -5.02814389 48.41764448, -5.02818877 48.41767456, -5.0282335 48.41770474, -5.02827809 48.41773501, -5.02832253 48.41776538, -5.02836683 48.41779583, -5.02841099 48.41782638, -5.028455 48.41785703, -5.02849887 48.41788776, -5.0285426 48.41791859, -5.02858617 48.4179495, -5.02862961 48.41798051, -5.02867289 48.41801161, -5.02871603 48.4180428, -5.02875902 48.41807408, -5.02880186 48.41810545, -5.02884456 48.4181369, -5.02888711 48.41816845, -5.0289295 48.41820009, -5.02897175 48.41823181, -5.02901385 48.41826362, -5.0290558 48.41829552, -5.02909759 48.41832751, -5.02913924 48.41835959, -5.02918073 48.41839175, -5.02922208 48.418424, -5.02926327 48.41845633, -5.0293043 48.41848876, -5.02934519 48.41852126, -5.02938592 48.41855385, -5.02942649 48.41858653, -5.02946692 48.41861929, -5.02950718 48.41865214, -5.0295473 48.41868507, -5.02958725 48.41871808, -5.02962705 48.41875118, -5.0296667 48.41878436, -5.02970619 48.41881762, -5.02974552 48.41885097, -5.02978469 48.4188844, -5.0298237 48.41891791, -5.02986256 48.4189515, -5.02990126 48.41898517, -5.0299398 48.41901892, -5.02997818 48.41905275, -5.0300164 48.41908667, -5.03005446 48.41912066, -5.03009236 48.41915473, -5.0301301 48.41918888, -5.03016767 48.41922311, -5.03020509 48.41925742, -5.03024234 48.41929181, -5.03027943 48.41932627, -5.03031636 48.41936081, -5.03035312 48.41939543, -5.03038972 48.41943013, -5.03042616 48.4194649, -5.03046243 48.41949974, -5.03049854 48.41953467, -5.03053449 48.41956967, -5.03057026 48.41960474, -5.03060588 48.41963989, -5.03064132 48.41967511, -5.0306766 48.41971041, -5.03071172 48.41974578, -5.03074666 48.41978122, -5.03078144 48.41981674, -5.03081605 48.41985233, -5.0308505 48.41988799, -5.03088477 48.41992372, -5.03091888 48.41995952, -5.03095281 48.4199954, -5.03098658 48.42003134, -5.03102018 48.42006736, -5.03105361 48.42010345, -5.03108686 48.4201396, -5.03111995 48.42017583, -5.03115287 48.42021212, -5.03118561 48.42024849, -5.03121818 48.42028492, -5.03125058 48.42032142, -5.03128281 48.42035799, -5.03131486 48.42039462, -5.03134675 48.42043132, -5.03137845 48.42046809, -5.03140999 48.42050492, -5.03144135 48.42054182, -5.03147254 48.42057879, -5.03150355 48.42061582, -5.03153439 48.42065291, -5.03156505 48.42069007, -5.03159553 48.42072729, -5.03162584 48.42076458, -5.03165598 48.42080193, -5.03168594 48.42083934, -5.03171572 48.42087682, -5.03174532 48.42091435, -5.03177475 48.42095195, -5.031804 48.42098961, -5.03183307 48.42102733, -5.03186197 48.42106511, -5.03189068 48.42110295, -5.03191922 48.42114086, -5.03194758 48.42117882, -5.03197575 48.42121684, -5.03200375 48.42125492, -5.03203157 48.42129305, -5.03205921 48.42133125, -5.03208667 48.4213695, -5.03211395 48.42140781, -5.03214105 48.42144618, -5.03216796 48.4214846, -5.0321947 48.42152308, -5.03222125 48.42156162, -5.03224762 48.42160021, -5.03227381 48.42163885, -5.03229981 48.42167755, -5.03232564 48.42171631, -5.03235128 48.42175511, -5.03237673 48.42179398, -5.03240201 48.42183289, -5.0324271 48.42187186, -5.032452 48.42191088, -5.03247672 48.42194995, -5.03250126 48.42198907, -5.03252561 48.42202824, -5.03254978 48.42206747, -5.03257376 48.42210674, -5.03259756 48.42214607, -5.03262117 48.42218544, -5.0326446 48.42222487, -5.03266783 48.42226434, -5.03269089 48.42230386, -5.03271375 48.42234343, -5.03273643 48.42238304, -5.03275892 48.42242271, -5.03278123 48.42246242, -5.03280334 48.42250217, -5.03282527 48.42254198, -5.03284702 48.42258183, -5.03286857 48.42262172, -5.03288993 48.42266166, -5.03291111 48.42270164, -5.0329321 48.42274167, -5.0329529 48.42278174, -5.03297351 48.42282185, -5.03299393 48.42286201, -5.03301416 48.42290221, -5.0330342 48.42294245, -5.03305405 48.42298274, -5.03307371 48.42302306, -5.03309318 48.42306343, -5.03311246 48.42310383, -5.03313155 48.42314428, -5.03315044 48.42318476, -5.03316915 48.42322529, -5.03318766 48.42326585, -5.03320599 48.42330646, -5.03322412 48.4233471, -5.03324206 48.42338777, -5.03325981 48.42342849, -5.03327736 48.42346924, -5.03329473 48.42351003, -5.0333119 48.42355086, -5.03332888 48.42359172, -5.03334566 48.42363261, -5.03336225 48.42367355, -5.03337865 48.42371451, -5.03339486 48.42375551, -5.03341087 48.42379654, -5.03342669 48.42383761, -5.03344231 48.42387871, -5.03345774 48.42391984, -5.03347298 48.42396101, -5.03348802 48.4240022, -5.03350286 48.42404343, -5.03351752 48.42408469, -5.03353197 48.42412598, -5.03354624 48.42416729, -5.0335603 48.42420864, -5.03357418 48.42425002, -5.03358785 48.42429142, -5.03360133 48.42433286, -5.03361462 48.42437432, -5.03362771 48.42441581, -5.0336406 48.42445733, -5.0336533 48.42449887, -5.0336658 48.42454044, -5.03367811 48.42458204, -5.03369022 48.42462366, -5.03370213 48.42466531, -5.03371385 48.42470698, -5.03372537 48.42474867, -5.03373669 48.42479039, -5.03374782 48.42483214, -5.03375875 48.4248739, -5.03376948 48.42491569, -5.03378001 48.4249575, -5.03379035 48.42499933, -5.03380049 48.42504119, -5.03381043 48.42508306, -5.03382017 48.42512496, -5.03382972 48.42516687, -5.03383907 48.42520881, -5.03384822 48.42525077, -5.03385717 48.42529274, -5.03386593 48.42533473, -5.03387448 48.42537674, -5.03388284 48.42541877, -5.033891 48.42546082, -5.03389896 48.42550288, -5.03390672 48.42554496, -5.03391428 48.42558705, -5.03392165 48.42562916, -5.03392882 48.42567129, -5.03393578 48.42571343, -5.03394255 48.42575558, -5.03394912 48.42579775, -5.03395549 48.42583993, -5.03396166 48.42588213, -5.03396763 48.42592434, -5.03397341 48.42596656, -5.03397898 48.42600879, -5.03398435 48.42605103, -5.03398953 48.42609329, -5.0339945 48.42613555, -5.03399928 48.42617783, -5.03400385 48.42622011, -5.03400823 48.42626241, -5.03401241 48.42630471, -5.03401638 48.42634702, -5.03402016 48.42638934, -5.03402374 48.42643167, -5.03402712 48.42647401, -5.03403029 48.42651635, -5.03403327 48.4265587, -5.03403605 48.42660105, -5.03403863 48.42664341, -5.03404101 48.42668577, -5.03404318 48.42672814, -5.03404516 48.42677052, -5.03404694 48.4268129, -5.03404852 48.42685528, -5.0340499 48.42689766, -5.03405107 48.42694005, -5.03405205 48.42698244, -5.03405283 48.42702483, -5.03405341 48.42706722, -5.03405379 48.42710962, -5.03405396 48.42715201, -5.03405394 48.42719441, -5.03405372 48.4272368, -5.03405329 48.4272792, -5.03405267 48.42732159, -5.03405185 48.42736398, -5.03405082 48.42740637, -5.0340496 48.42744876, -5.03404818 48.42749114, -5.03404655 48.42753352, -5.03404473 48.4275759, -5.03404271 48.42761827, -5.03404048 48.42766064, -5.03403806 48.427703, -5.03403544 48.42774536, -5.03403261 48.42778772, -5.03402959 48.42783006, -5.03402637 48.4278724, -5.03402294 48.42791474, -5.03401932 48.42795706, -5.0340155 48.42799938, -5.03401148 48.42804169, -5.03400725 48.42808399, -5.03400283 48.42812628, -5.03399821 48.42816857, -5.03399339 48.42821084, -5.03398837 48.4282531, -5.03398315 48.42829535, -5.03397773 48.4283376, -5.03397211 48.42837982, -5.03396629 48.42842204, -5.03396027 48.42846425, -5.03395406 48.42850644, -5.03394764 48.42854862, -5.03394103 48.42859078, -5.03393421 48.42863294, -5.0339272 48.42867507, -5.03391999 48.42871719, -5.03391258 48.4287593, -5.03390497 48.42880139, -5.03389716 48.42884347, -5.03388915 48.42888552, -5.03388095 48.42892757, -5.03387254 48.42896959, -5.03386394 48.4290116, -5.03385514 48.42905358, -5.03384614 48.42909555, -5.03383695 48.4291375, -5.03382755 48.42917944, -5.03381796 48.42922135, -5.03380817 48.42926324, -5.03379818 48.42930511, -5.033788 48.42934696, -5.03377761 48.42938878, -5.03376703 48.42943059, -5.03375626 48.42947237, -5.03374528 48.42951413, -5.03373411 48.42955587, -5.03372274 48.42959759, -5.03371117 48.42963928, -5.03369941 48.42968094, -5.03368745 48.42972258, -5.0336753 48.4297642, -5.03366294 48.42980579, -5.0336504 48.42984735, -5.03363765 48.42988889, -5.03362471 48.4299304, -5.03361157 48.42997188, -5.03359824 48.43001334, -5.03358471 48.43005477, -5.03357099 48.43009617, -5.03355707 48.43013754, -5.03354296 48.43017888, -5.03352865 48.43022019, -5.03351414 48.43026147, -5.03349944 48.43030272, -5.03348455 48.43034394, -5.03346946 48.43038513, -5.03345418 48.43042628, -5.0334387 48.43046741, -5.03342303 48.4305085, -5.03340717 48.43054956, -5.03339111 48.43059058, -5.03337486 48.43063158, -5.03335841 48.43067253, -5.03334177 48.43071346, -5.03332494 48.43075434, -5.03330791 48.4307952, -5.0332907 48.43083601, -5.03327329 48.43087679, -5.03325568 48.43091754, -5.03323789 48.43095824, -5.0332199 48.43099891, -5.03320172 48.43103954, -5.03318335 48.43108014, -5.03316479 48.43112069, -5.03314603 48.43116121, -5.03312709 48.43120169, -5.03310795 48.43124212, -5.03308862 48.43128252, -5.03306911 48.43132287, -5.0330494 48.43136319, -5.0330295 48.43140346, -5.03300941 48.43144369, -5.03298913 48.43148388, -5.03296866 48.43152403, -5.03294801 48.43156413, -5.03292716 48.43160419, -5.03290612 48.43164421, -5.0328849 48.43168418, -5.03286349 48.43172411, -5.03284189 48.43176399, -5.0328201 48.43180383, -5.03279812 48.43184362, -5.03277595 48.43188337, -5.0327536 48.43192307, -5.03273106 48.43196272, -5.03270833 48.43200232, -5.03268542 48.43204188, -5.03266232 48.43208139, -5.03263903 48.43212085, -5.03261555 48.43216026, -5.03259189 48.43219962, -5.03256805 48.43223894, -5.03254402 48.4322782, -5.0325198 48.43231741, -5.0324954 48.43235657, -5.03247081 48.43239568, -5.03244604 48.43243474, -5.03242109 48.43247375, -5.03239595 48.4325127, -5.03237063 48.4325516, -5.03234512 48.43259045, -5.03231943 48.43262925, -5.03229356 48.43266799, -5.0322675 48.43270667, -5.03224126 48.4327453, -5.03221484 48.43278388, -5.03218824 48.4328224, -5.03216146 48.43286087, -5.03213449 48.43289928, -5.03210735 48.43293763, -5.03208002 48.43297593, -5.03205251 48.43301416, -5.03202482 48.43305235, -5.03199695 48.43309047, -5.0319689 48.43312853, -5.03194067 48.43316654, -5.03191227 48.43320448, -5.03188368 48.43324237, -5.03185491 48.4332802, -5.03182597 48.43331796, -5.03179685 48.43335567, -5.03176755 48.43339331, -5.03173807 48.4334309, -5.03170841 48.43346842, -5.03167858 48.43350588, -5.03164857 48.43354327, -5.03161839 48.43358061, -5.03158802 48.43361788, -5.03155749 48.43365508, -5.03152677 48.43369223, -5.03149589 48.4337293, -5.03146482 48.43376632, -5.03143358 48.43380327, -5.03140217 48.43384015, -5.03137059 48.43387697, -5.03133883 48.43391372, -5.03130689 48.4339504, -5.03127479 48.43398702, -5.03124251 48.43402357, -5.03121006 48.43406005, -5.03117743 48.43409646, -5.03114464 48.43413281, -5.03111167 48.43416909, -5.03107853 48.4342053, -5.03104522 48.43424143, -5.03101175 48.4342775, -5.0309781 48.4343135, -5.03094428 48.43434943, -5.03091029 48.43438529, -5.03087613 48.43442107, -5.0308418 48.43445679, -5.03080731 48.43449243, -5.03077264 48.434528, -5.03073781 48.43456349, -5.03070281 48.43459892, -5.03066765 48.43463427, -5.03063232 48.43466955, -5.03059682 48.43470475, -5.03056115 48.43473988, -5.03052532 48.43477493, -5.03048933 48.43480991, -5.03045316 48.43484482, -5.03041684 48.43487964, -5.03038035 48.4349144, -5.03034369 48.43494907, -5.03030688 48.43498367, -5.0302699 48.43501819, -5.03023275 48.43505263, -5.03019545 48.435087, -5.03015798 48.43512129, -5.03012035 48.4351555, -5.03008256 48.43518963, -5.0300446 48.43522368, -5.03000649 48.43525765, -5.02996822 48.43529154, -5.02992979 48.43532535, -5.02989119 48.43535908, -5.02985244 48.43539273, -5.02981353 48.4354263, -5.02977446 48.43545979, -5.02973524 48.4354932, -5.02969585 48.43552652, -5.02965631 48.43555976, -5.02961661 48.43559292, -5.02957676 48.43562599, -5.02953675 48.43565898, -5.02949658 48.43569189, -5.02945626 48.43572472, -5.02941578 48.43575745, -5.02937515 48.43579011, -5.02933437 48.43582268, -5.02929343 48.43585516, -5.02925234 48.43588756, -5.02921109 48.43591987, -5.0291697 48.4359521, -5.02912815 48.43598423, -5.02908645 48.43601629, -5.0290446 48.43604825, -5.02900259 48.43608013, -5.02896044 48.43611192, -5.02891814 48.43614362, -5.02887569 48.43617523, -5.02883309 48.43620675, -5.02879034 48.43623818, -5.02874744 48.43626953, -5.02870439 48.43630078, -5.0286612 48.43633195, -5.02861786 48.43636302, -5.02857437 48.436394, -5.02853074 48.4364249, -5.02848696 48.4364557, -5.02844304 48.4364864, -5.02839897 48.43651702, -5.02835476 48.43654755, -5.0283104 48.43657798, -5.0282659 48.43660832, -5.02822126 48.43663856, -5.02817647 48.43666871, -5.02813154 48.43669877, -5.02808647 48.43672874, -5.02804126 48.43675861, -5.02799591 48.43678838, -5.02795041 48.43681806, -5.02790478 48.43684765, -5.02785901 48.43687714, -5.0278131 48.43690653, -5.02776705 48.43693583, -5.02772086 48.43696503, -5.02767454 48.43699413, -5.02762807 48.43702314, -5.02758147 48.43705205, -5.02753474 48.43708086, -5.02748787 48.43710958, -5.02744086 48.4371382, -5.02739372 48.43716671, -5.02734644 48.43719513, -5.02729903 48.43722345, -5.02725149 48.43725167, -5.02720381 48.4372798, -5.027156 48.43730782, -5.02710806 48.43733574, -5.02705998 48.43736356, -5.02701178 48.43739128, -5.02696344 48.4374189, -5.02691498 48.43744642, -5.02686638 48.43747384, -5.02681766 48.43750115, -5.02676881 48.43752836, -5.02671983 48.43755548, -5.02667072 48.43758248, -5.02662148 48.43760939, -5.02657212 48.43763619, -5.02652263 48.43766289, -5.02647301 48.43768949, -5.02642327 48.43771598, -5.0263734 48.43774237, -5.02632341 48.43776865, -5.0262733 48.43779483, -5.02622306 48.4378209, -5.0261727 48.43784687, -5.02612222 48.43787273, -5.02607161 48.43789849, -5.02602089 48.43792414, -5.02597004 48.43794969, -5.02591907 48.43797513, -5.02586798 48.43800046, -5.02581678 48.43802568, -5.02576545 48.4380508, -5.02571401 48.43807581, -5.02566245 48.43810072, -5.02561077 48.43812551, -5.02555897 48.4381502, -5.02550706 48.43817478, -5.02545503 48.43819924, -5.02540289 48.43822361, -5.02535063 48.43824786, -5.02529825 48.438272, -5.02524577 48.43829603, -5.02519317 48.43831995, -5.02514045 48.43834377, -5.02508763 48.43836747, -5.02503469 48.43839106, -5.02498165 48.43841454, -5.02492849 48.43843791, -5.02487522 48.43846117, -5.02482184 48.43848432, -5.02476835 48.43850735, -5.02471476 48.43853028, -5.02466105 48.43855309, -5.02460724 48.43857579, -5.02455332 48.43859837, -5.0244993 48.43862085, -5.02444517 48.43864321, -5.02439093 48.43866546, -5.02433659 48.43868759, -5.02428215 48.43870961, -5.0242276 48.43873151, -5.02417295 48.43875331, -5.02411819 48.43877498, -5.02406334 48.43879655, -5.02400838 48.43881799, -5.02395332 48.43883933, -5.02389816 48.43886055, -5.0238429 48.43888165, -5.02378754 48.43890263, -5.02373208 48.43892351, -5.02367653 48.43894426, -5.02362087 48.4389649, -5.02356512 48.43898542, -5.02350927 48.43900583, -5.02345333 48.43902611, -5.02339729 48.43904629, -5.02334115 48.43906634, -5.02328493 48.43908628, -5.0232286 48.4391061, -5.02317219 48.4391258, -5.02311568 48.43914538, -5.02305908 48.43916485, -5.02300238 48.43918419, -5.0229456 48.43920342, -5.02288872 48.43922253, -5.02283176 48.43924152, -5.02277471 48.43926039, -5.02271756 48.43927914, -5.02266033 48.43929777, -5.02260301 48.43931628, -5.02254561 48.43933468, -5.02248811 48.43935295, -5.02243054 48.4393711, -5.02237287 48.43938913, -5.02231512 48.43940704, -5.02225729 48.43942483, -5.02219937 48.4394425, -5.02214137 48.43946005, -5.02208329 48.43947747, -5.02202512 48.43949478, -5.02196688 48.43951196, -5.02190855 48.43952902, -5.02185014 48.43954596, -5.02179166 48.43956278, -5.02173309 48.43957947, -5.02167444 48.43959605, -5.02161572 48.4396125, -5.02155692 48.43962882, -5.02149804 48.43964502, -5.02143909 48.43966111, -5.02138006 48.43967706, -5.02132096 48.4396929, -5.02126178 48.4397086, -5.02120253 48.43972419, -5.0211432 48.43973965, -5.0210838 48.43975499, -5.02102433 48.4397702, -5.02096479 48.43978529, -5.02090517 48.43980026, -5.02084549 48.4398151, -5.02078574 48.43982981, -5.02072591 48.4398444, -5.02066602 48.43985887, -5.02060606 48.43987321, -5.02054604 48.43988742, -5.02048594 48.43990151, -5.02042578 48.43991547, -5.02036556 48.43992931, -5.02030527 48.43994302, -5.02024491 48.43995661, -5.02018449 48.43997006, -5.02012401 48.4399834, -5.02006346 48.4399966, -5.02000286 48.44000968, -5.01994219 48.44002263, -5.01988146 48.44003546, -5.01982067 48.44004816, -5.01975982 48.44006073, -5.01969891 48.44007317, -5.01963794 48.44008549, -5.01957692 48.44009768, -5.01951584 48.44010974, -5.0194547 48.44012167, -5.0193935 48.44013348, -5.01933225 48.44014515, -5.01927095 48.4401567, -5.01920959 48.44016812, -5.01914817 48.44017942, -5.01908671 48.44019058, -5.01902519 48.44020162, -5.01896362 48.44021253, -5.018902 48.4402233, -5.01884032 48.44023395, -5.0187786 48.44024447, -5.01871683 48.44025486, -5.01865501 48.44026513, -5.01859314 48.44027526, -5.01853122 48.44028526, -5.01846926 48.44029514, -5.01840725 48.44030488, -5.0183452 48.4403145, -5.0182831 48.44032398, -5.01822095 48.44033334, -5.01815876 48.44034256, -5.01809653 48.44035166, -5.01803426 48.44036062, -5.01797194 48.44036945, -5.01790958 48.44037816, -5.01784718 48.44038673, -5.01778474 48.44039518, -5.01772226 48.44040349, -5.01765975 48.44041167, -5.01759719 48.44041972, -5.0175346 48.44042764, -5.01747197 48.44043543, -5.0174093 48.44044309, -5.0173466 48.44045062, -5.01728386 48.44045801, -5.01722108 48.44046528, -5.01715828 48.44047241, -5.01709544 48.44047941, -5.01703256 48.44048629, -5.01696966 48.44049302, -5.01690672 48.44049963, -5.01684375 48.44050611, -5.01678075 48.44051245, -5.01671773 48.44051867, -5.01665467 48.44052475, -5.01659158 48.4405307, -5.01652847 48.44053651, -5.01646533 48.4405422, -5.01640216 48.44054775, -5.01633897 48.44055317, -5.01627575 48.44055846, -5.01621251 48.44056362, -5.01614924 48.44056864, -5.01608595 48.44057354, -5.01602264 48.4405783, -5.01595931 48.44058292, -5.01589595 48.44058742, -5.01583257 48.44059178, -5.01576917 48.44059601, -5.01570576 48.44060011, -5.01564232 48.44060407, -5.01557886 48.4406079, -5.01551539 48.4406116, -5.0154519 48.44061517, -5.0153884 48.4406186, -5.01532487 48.44062191, -5.01526134 48.44062507, -5.01519778 48.44062811, -5.01513422 48.44063101, -5.01507064 48.44063378, -5.01500704 48.44063642, -5.01494344 48.44063892, -5.01487982 48.44064129, -5.0148162 48.44064353, -5.01475256 48.44064564, -5.01468891 48.44064761, -5.01462526 48.44064945, -5.01456159 48.44065115, -5.01449792 48.44065272, -5.01443424 48.44065416, -5.01437056 48.44065547, -5.01430686 48.44065664, -5.01424317 48.44065768, -5.01417947 48.44065859, -5.01411576 48.44065936, -5.01405205 48.44066, -5.01398834 48.44066051, -5.01392463 48.44066088, -5.01386091 48.44066112, -5.0137972 48.44066123, -5.01373348 48.4406612, -5.01366977 48.44066104, -5.01360605 48.44066075, -5.01354234 48.44066033, -5.01347863 48.44065977, -5.01341492 48.44065907, -5.01335122 48.44065825, -5.01328752 48.44065729, -5.01322382 48.4406562, -5.01316013 48.44065497, -5.01309645 48.44065362, -5.01303277 48.44065212, -5.0129691 48.4406505, -5.01290544 48.44064874, -5.01284179 48.44064685, -5.01277815 48.44064483, -5.01271451 48.44064267, -5.01265089 48.44064038, -5.01258728 48.44063796, -5.01252368 48.4406354, -5.01246009 48.44063272, -5.01239652 48.44062989, -5.01233296 48.44062694, -5.01226941 48.44062385, -5.01220588 48.44062063, -5.01214236 48.44061728, -5.01207886 48.44061379, -5.01201538 48.44061018, -5.01195191 48.44060642, -5.01188846 48.44060254, -5.01182504 48.44059852, -5.01176163 48.44059437, -5.01169824 48.44059009, -5.01163487 48.44058568, -5.01157152 48.44058113, -5.01150819 48.44057645, -5.01144489 48.44057164, -5.01138161 48.4405667, -5.01131835 48.44056162, -5.01125512 48.44055641, -5.01119191 48.44055107, -5.01112872 48.4405456, -5.01106557 48.44053999, -5.01100244 48.44053426, -5.01093934 48.44052839, -5.01087626 48.44052239, -5.01081322 48.44051626, -5.0107502 48.44050999, -5.01068721 48.4405036, -5.01062426 48.44049707, -5.01056133 48.44049041, -5.01049844 48.44048362, -5.01043558 48.4404767, -5.01037275 48.44046964, -5.01030996 48.44046246, -5.0102472 48.44045514, -5.01018447 48.44044769, -5.01012178 48.44044011, -5.01005913 48.44043241, -5.00999651 48.44042456, -5.00993394 48.44041659, -5.00987139 48.44040849, -5.00980889 48.44040026, -5.00974643 48.44039189, -5.00968401 48.4403834, -5.00962162 48.44037478, -5.00955928 48.44036602, -5.00949698 48.44035714, -5.00943472 48.44034812, -5.00937251 48.44033897, -5.00931033 48.4403297, -5.00924821 48.44032029, -5.00918612 48.44031076, -5.00912409 48.44030109, -5.00906209 48.4402913, -5.00900015 48.44028137, -5.00893825 48.44027132, -5.0088764 48.44026114, -5.0088146 48.44025082, -5.00875285 48.44024038, -5.00869115 48.44022981, -5.00862949 48.44021911, -5.00856789 48.44020828, -5.00850634 48.44019732, -5.00844484 48.44018624, -5.0083834 48.44017502, -5.008322 48.44016368, -5.00826067 48.44015221, -5.00819938 48.44014061, -5.00813815 48.44012888, -5.00807698 48.44011703, -5.00801586 48.44010504, -5.0079548 48.44009293, -5.0078938 48.44008069, -5.00783286 48.44006833, -5.00777197 48.44005583, -5.00771114 48.44004321, -5.00765038 48.44003047, -5.00758967 48.44001759, -5.00752903 48.44000459, -5.00746844 48.43999146, -5.00740792 48.43997821, -5.00734747 48.43996482, -5.00728707 48.43995132, -5.00722674 48.43993768, -5.00716648 48.43992392, -5.00710628 48.43991004, -5.00704614 48.43989602, -5.00698607 48.43988189, -5.00692607 48.43986762, -5.00686614 48.43985323, -5.00680628 48.43983872, -5.00674648 48.43982408, -5.00668675 48.43980932, -5.0066271 48.43979443, -5.00656751 48.43977942, -5.006508 48.43976428, -5.00644855 48.43974902, -5.00638918 48.43973363, -5.00632989 48.43971812, -5.00627066 48.43970249, -5.00621151 48.43968673, -5.00615244 48.43967085, -5.00609344 48.43965484, -5.00603451 48.43963871, -5.00597567 48.43962246, -5.0059169 48.43960609, -5.0058582 48.43958959, -5.00579959 48.43957297, -5.00574105 48.43955623, -5.0056826 48.43953936, -5.00562422 48.43952238, -5.00556593 48.43950527, -5.00550771 48.43948804, -5.00544958 48.43947068, -5.00539153 48.43945321, -5.00533356 48.43943562, -5.00527568 48.4394179, -5.00521787 48.43940006, -5.00516016 48.43938211, -5.00510253 48.43936403, -5.00504498 48.43934583, -5.00498752 48.43932751, -5.00493015 48.43930907, -5.00487287 48.43929051, -5.00481567 48.43927183, -5.00475856 48.43925304, -5.00470154 48.43923412, -5.00464461 48.43921508, -5.00458777 48.43919593, -5.00453103 48.43917665, -5.00447437 48.43915726, -5.0044178 48.43913775, -5.00436133 48.43911812, -5.00430495 48.43909837, -5.00424866 48.43907851, -5.00419247 48.43905852, -5.00413637 48.43903842, -5.00408037 48.43901821, -5.00402447 48.43899787, -5.00396866 48.43897742, -5.00391294 48.43895685, -5.00385733 48.43893617, -5.00380181 48.43891537, -5.00374639 48.43889445, -5.00369107 48.43887342, -5.00363585 48.43885227, -5.00358073 48.43883101, -5.00352571 48.43880963, -5.00347079 48.43878814, -5.00341597 48.43876653, -5.00336126 48.43874481, -5.00330665 48.43872297, -5.00325214 48.43870102, -5.00319773 48.43867896, -5.00314343 48.43865678, -5.00308924 48.43863449, -5.00303515 48.43861209, -5.00298117 48.43858957, -5.00292729 48.43856694, -5.00287352 48.4385442, -5.00281986 48.43852134, -5.00276631 48.43849837, -5.00271286 48.43847529, -5.00265953 48.4384521, -5.0026063 48.4384288, -5.00255318 48.43840539, -5.00250018 48.43838186, -5.00244729 48.43835823, -5.00239451 48.43833448, -5.00234184 48.43831063, -5.00228928 48.43828666, -5.00223684 48.43826259, -5.00218451 48.4382384, -5.0021323 48.43821411, -5.0020802 48.4381897, -5.00202822 48.43816519, -5.00197635 48.43814057, -5.0019246 48.43811584, -5.00187296 48.438091, -5.00182145 48.43806606, -5.00177005 48.43804101, -5.00171877 48.43801585, -5.00166761 48.43799058, -5.00161657 48.43796521, -5.00156565 48.43793973, -5.00151485 48.43791414, -5.00146417 48.43788845, -5.00141361 48.43786265, -5.00136318 48.43783674, -5.00131286 48.43781073, -5.00126267 48.43778462, -5.00121261 48.4377584, -5.00116267 48.43773208, -5.00111285 48.43770565, -5.00106316 48.43767912, -5.00101359 48.43765248, -5.00096415 48.43762574, -5.00091484 48.4375989, -5.00086565 48.43757195, -5.00081659 48.4375449, -5.00076766 48.43751775, -5.00071886 48.4374905, -5.00067018 48.43746314, -5.00062164 48.43743569, -5.00057322 48.43740813, -5.00052494 48.43738047, -5.00047678 48.43735271, -5.00042876 48.43732485, -5.00038087 48.43729689, -5.00033311 48.43726883, -5.00028549 48.43724067, -5.000238 48.43721241, -5.00019064 48.43718405, -5.00014342 48.43715559, -5.00009633 48.43712703, -5.00004937 48.43709838, -5.00000255 48.43706963, -4.99995587 48.43704078, -4.99990932 48.43701183, -4.99986292 48.43698278, -4.99981664 48.43695364, -4.99977051 48.4369244, -4.99972451 48.43689507, -4.99967866 48.43686563, -4.99963294 48.43683611, -4.99958736 48.43680649, -4.99954192 48.43677677, -4.99949663 48.43674696, -4.99945147 48.43671705, -4.99940646 48.43668705, -4.99936158 48.43665695, -4.99931685 48.43662676, -4.99927226 48.43659648, -4.99922782 48.43656611, -4.99918352 48.43653564, -4.99913936 48.43650508, -4.99909535 48.43647443, -4.99905148 48.43644368, -4.99900776 48.43641284, -4.99896419 48.43638192, -4.99892076 48.4363509, -4.99887747 48.43631979, -4.99883434 48.43628859, -4.99879135 48.4362573, -4.99874851 48.43622592, -4.99870582 48.43619445, -4.99866328 48.4361629, -4.99862088 48.43613125, -4.99857864 48.43609951, -4.99853654 48.43606769, -4.9984946 48.43603578, -4.99845281 48.43600378, -4.99841117 48.4359717, -4.99836968 48.43593952, -4.99832834 48.43590726, -4.99828716 48.43587492, -4.99824612 48.43584249, -4.99820525 48.43580997, -4.99816452 48.43577737, -4.99812395 48.43574468, -4.99808353 48.43571191, -4.99804327 48.43567905, -4.99800317 48.43564611, -4.99796322 48.43561309, -4.99792343 48.43557998, -4.99788379 48.43554679, -4.99784431 48.43551352, -4.99780499 48.43548016, -4.99776582 48.43544672, -4.99772681 48.43541321, -4.99768796 48.4353796, -4.99764928 48.43534592, -4.99761075 48.43531216, -4.99757237 48.43527832, -4.99753416 48.43524439, -4.99749611 48.43521039, -4.99745822 48.43517631, -4.9974205 48.43514215, -4.99738293 48.43510791, -4.99734552 48.43507359, -4.99730828 48.43503919, -4.9972712 48.43500472, -4.99723428 48.43497017, -4.99719753 48.43493554, -4.99716094 48.43490084, -4.99712451 48.43486605, -4.99708825 48.4348312, -4.99705216 48.43479626, -4.99701622 48.43476126, -4.99698046 48.43472617, -4.99694486 48.43469101, -4.99690942 48.43465578, -4.99687416 48.43462048, -4.99683906 48.4345851, -4.99680412 48.43454964, -4.99676936 48.43451412, -4.99673476 48.43447852, -4.99670033 48.43444285, -4.99666607 48.43440711, -4.99663198 48.43437129, -4.99659805 48.43433541, -4.9965643 48.43429945, -4.99653072 48.43426343, -4.99649731 48.43422733, -4.99646406 48.43419117, -4.99643099 48.43415493, -4.99639809 48.43411863, -4.99636536 48.43408225, -4.99633281 48.43404581, -4.99630042 48.43400931, -4.99626821 48.43397273, -4.99623617 48.43393609, -4.99620431 48.43389938, -4.99617262 48.4338626, -4.9961411 48.43382576, -4.99610975 48.43378885, -4.99607858 48.43375187, -4.99604759 48.43371484, -4.99601677 48.43367773, -4.99598612 48.43364056, -4.99595566 48.43360333, -4.99592536 48.43356604, -4.99589525 48.43352868, -4.99586531 48.43349126, -4.99583554 48.43345378, -4.99580596 48.43341623, -4.99577655 48.43337862, -4.99574732 48.43334095, -4.99571826 48.43330322, -4.99568939 48.43326544, -4.99566069 48.43322758, -4.99563218 48.43318967, -4.99560384 48.43315171, -4.99557568 48.43311368, -4.9955477 48.43307559, -4.9955199 48.43303744, -4.99549228 48.43299924, -4.99546485 48.43296098, -4.99543759 48.43292266, -4.99541051 48.43288429, -4.99538362 48.43284586, -4.99535691 48.43280737, -4.99533037 48.43276883, -4.99530402 48.43273023, -4.99527786 48.43269157, -4.99525187 48.43265287, -4.99522607 48.4326141, -4.99520045 48.43257529, -4.99517502 48.43253642, -4.99514977 48.4324975, -4.9951247 48.43245852, -4.99509982 48.4324195, -4.99507512 48.43238042, -4.99505061 48.43234129, -4.99502628 48.43230211, -4.99500213 48.43226287, -4.99497817 48.43222359, -4.9949544 48.43218426, -4.99493081 48.43214488, -4.99490741 48.43210545, -4.9948842 48.43206597, -4.99486117 48.43202644, -4.99483833 48.43198687, -4.99481567 48.43194724, -4.99479321 48.43190757, -4.99477093 48.43186785, -4.99474883 48.43182809, -4.99472693 48.43178828, -4.99470521 48.43174843, -4.99468369 48.43170853, -4.99466235 48.43166858, -4.99464119 48.43162859, -4.99462023 48.43158856, -4.99459946 48.43154848, -4.99457888 48.43150836, -4.99455848 48.4314682, -4.99453828 48.43142799, -4.99451826 48.43138774, -4.99449844 48.43134745, -4.99447881 48.43130712, -4.99445936 48.43126675, -4.99444011 48.43122634, -4.99442105 48.43118589, -4.99440218 48.43114539, -4.9943835 48.43110486, -4.99436501 48.43106429, -4.99434671 48.43102368, -4.99432861 48.43098304, -4.9943107 48.43094235, -4.99429298 48.43090163, -4.99427545 48.43086087, -4.99425811 48.43082008, -4.99424097 48.43077925, -4.99422402 48.43073838, -4.99420726 48.43069748, -4.9941907 48.43065655, -4.99417433 48.43061557, -4.99415815 48.43057457, -4.99414217 48.43053353, -4.99412638 48.43049246, -4.99411079 48.43045135, -4.99409539 48.43041022, -4.99408018 48.43036905, -4.99406517 48.43032785, -4.99405035 48.43028662, -4.99403573 48.43024535, -4.9940213 48.43020406, -4.99400706 48.43016274, -4.99399303 48.43012139, -4.99397918 48.43008, -4.99396554 48.43003859, -4.99395208 48.42999716, -4.99393883 48.42995569, -4.99392577 48.4299142, -4.9939129 48.42987267, -4.99390024 48.42983113, -4.99388776 48.42978955, -4.99387549 48.42974795, -4.99386341 48.42970633, -4.99385153 48.42966468, -4.99383984 48.429623, -4.99382835 48.4295813, -4.99381706 48.42953958, -4.99380597 48.42949783, -4.99379507 48.42945606, -4.99378437 48.42941427, -4.99377386 48.42937246, -4.99376356 48.42933062, -4.99375345 48.42928876, -4.99374354 48.42924688, -4.99373383 48.42920499, -4.99372431 48.42916307, -4.99371499 48.42912113, -4.99370587 48.42907917, -4.99369695 48.42903719, -4.99368823 48.4289952, -4.99367971 48.42895318, -4.99367138 48.42891115, -4.99366325 48.42886911, -4.99365532 48.42882704, -4.99364759 48.42878496, -4.99364006 48.42874286, -4.99363273 48.42870075, -4.99362559 48.42865862, -4.99361866 48.42861648, -4.99361192 48.42857432, -4.99360539 48.42853215)))" + val polygon = wktReader.read(multipolygonString) as MultiPolygon + val firstMission = + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + openBy = "KIM", + closedBy = "TRA", + facade = "NAMO", + observationsCacem = + "Remain vote several ok. Bring American play woman challenge. Throw low law positive seven.", + startDateTimeUtc = + ZonedDateTime.parse("2022-03-21T12:11:13Z"), + endDateTimeUtc = null, + geom = polygon, + isClosed = false, + isDeleted = false, + envActions = listOf(), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10002, + administration = "DDTM", + isArchived = false, + name = "DML 2A", + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 3, + controlUnitId = + 10002, + name = + "Semi-rigide 1", + ), + LegacyControlUnitResourceEntity( + id = 4, + controlUnitId = + 10002, + name = + "Semi-rigide 2", + ), + LegacyControlUnitResourceEntity( + id = 5, + controlUnitId = + 10002, + name = + "Voiture", + ), + ), + ), + ), + isGeometryComputedFromControls = false, ), - ), - ), - ), - isGeometryComputedFromControls = false, - ), - ) + ) val mission = jpaMissionRepository.findFullMissionById(10) assertThat(mission).isEqualTo(firstMission) @@ -376,9 +716,9 @@ class JpaMissionRepositoryITests : AbstractDBTests() { assertThat(missionDTO.mission.id).isEqualTo(34) assertThat(missionDTO.mission.envActions).hasSize(2) assertThat( - missionDTO.envActionsAttachedToReportingIds?.get(0)?.first, - ) - .isEqualTo(UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807")) + missionDTO.envActionsAttachedToReportingIds?.get(0)?.first, + ) + .isEqualTo(UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807")) assertThat(missionDTO.envActionsAttachedToReportingIds?.get(0)?.second).isEqualTo(listOf(6)) } @@ -395,88 +735,89 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save should create a new mission`() { // Given val existingMissions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(existingMissions).hasSize(21) val noteObservations = "Quelqu'un aurait vu quelque chose quelque part à un certain moment." val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - envActions = - listOf( - EnvActionControlEntity( - id = - UUID.fromString( - "33310163-4e22-4d3d-b585-dac4431eb4b5", - ), - facade = "Facade 1", - controlPlans = listOf( - EnvActionControlPlanEntity( - subThemeIds = listOf(1), - tagIds = listOf(1, 2), - themeId = 1, - ), - ), - department = "Department 1", - geom = point, - vehicleType = VehicleTypeEnum.VEHICLE_LAND, - isAdministrativeControl = true, - isComplianceWithWaterRegulationsControl = true, - isSafetyEquipmentAndStandardsComplianceControl = - true, - isSeafarersControl = true, - ), - EnvActionSurveillanceEntity( - id = - UUID.fromString( - "a6c4bd17-eb45-4504-ab15-7a18ea714a10", - ), - facade = "Facade 2", - department = "Department 2", - geom = polygon, - ), - EnvActionNoteEntity( - id = - UUID.fromString( - "126ded89-2dc0-4c77-9bf2-49f86b9a71a1", - ), - observations = noteObservations, - ), - ), - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10121, - name = "PAM Jeanne Barret", - administration = "DIRM / DM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 8, - controlUnitId = 10121, - name = "PAM Jeanne Barret", - ), - ), - ), - ), - isGeometryComputedFromControls = false, - ) + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + envActions = + listOf( + EnvActionControlEntity( + id = + UUID.fromString( + "33310163-4e22-4d3d-b585-dac4431eb4b5", + ), + facade = "Facade 1", + controlPlans = + listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(1), + tagIds = listOf(1, 2), + themeId = 1, + ), + ), + department = "Department 1", + geom = point, + vehicleType = VehicleTypeEnum.VEHICLE_LAND, + isAdministrativeControl = true, + isComplianceWithWaterRegulationsControl = true, + isSafetyEquipmentAndStandardsComplianceControl = + true, + isSeafarersControl = true, + ), + EnvActionSurveillanceEntity( + id = + UUID.fromString( + "a6c4bd17-eb45-4504-ab15-7a18ea714a10", + ), + facade = "Facade 2", + department = "Department 2", + geom = polygon, + ), + EnvActionNoteEntity( + id = + UUID.fromString( + "126ded89-2dc0-4c77-9bf2-49f86b9a71a1", + ), + observations = noteObservations, + ), + ), + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10121, + name = "PAM Jeanne Barret", + administration = "DIRM / DM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 8, + controlUnitId = 10121, + name = "PAM Jeanne Barret", + ), + ), + ), + ), + isGeometryComputedFromControls = false, + ) // When val newMissionCreated = jpaMissionRepository.save(newMission) @@ -485,39 +826,39 @@ class JpaMissionRepositoryITests : AbstractDBTests() { assertThat(newMissionCreated.mission.controlUnits).hasSize(1) assertThat(newMissionCreated.mission.controlUnits.first().id).isEqualTo(10121) assertThat(newMissionCreated.mission.controlUnits.first().name) - .isEqualTo("PAM Jeanne Barret") + .isEqualTo("PAM Jeanne Barret") assertThat(newMissionCreated.mission.controlUnits.first().administration) - .isEqualTo("DIRM / DM") + .isEqualTo("DIRM / DM") assertThat(newMissionCreated.mission.controlUnits.first().resources).hasSize(1) assertThat(newMissionCreated.mission.controlUnits.first().resources.first().id).isEqualTo(8) assertThat(newMissionCreated.mission.controlUnits.first().resources.first().controlUnitId) - .isEqualTo(10121) + .isEqualTo(10121) assertThat(newMissionCreated.mission.controlUnits.first().resources.first().name) - .isEqualTo("PAM Jeanne Barret") + .isEqualTo("PAM Jeanne Barret") assertThat(newMissionCreated.mission.envActions).hasSize(3) assertThat(newMissionCreated.mission.envActions?.first()?.facade).isEqualTo("Facade 1") assertThat(newMissionCreated.mission.envActions?.first()?.department) - .isEqualTo("Department 1") + .isEqualTo("Department 1") assertThat(newMissionCreated.mission.envActions?.get(1)?.facade).isEqualTo("Facade 2") assertThat(newMissionCreated.mission.envActions?.get(1)?.department) - .isEqualTo("Department 2") + .isEqualTo("Department 2") assertThat( - (newMissionCreated.mission.envActions?.get(2) as EnvActionNoteEntity) - .observations, - ) - .isEqualTo( - noteObservations, - ) + (newMissionCreated.mission.envActions?.get(2) as EnvActionNoteEntity) + .observations, + ) + .isEqualTo( + noteObservations, + ) val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(22) } @@ -527,84 +868,84 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save should update mission resources`() { // Given val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10004, - name = "DPM – DDTM 35", - administration = "DDTM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 8, - controlUnitId = 10004, - name = "PAM Jeanne Barret", - ), - ), - ), - ), - isGeometryComputedFromControls = false, - ) + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10004, + name = "DPM – DDTM 35", + administration = "DDTM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 8, + controlUnitId = 10004, + name = "PAM Jeanne Barret", + ), + ), + ), + ), + isGeometryComputedFromControls = false, + ) jpaMissionRepository.save(newMission) // When val newMissionUpdated = - jpaMissionRepository.save( - newMission.copy( - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10002, - name = "DML 2A", - administration = "DIRM / DM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 3, - controlUnitId = - 10002, - name = - "Semi-rigide 1", - ), - LegacyControlUnitResourceEntity( - id = 5, - controlUnitId = - 10002, - name = "Voiture", - ), - ), + jpaMissionRepository.save( + newMission.copy( + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10002, + name = "DML 2A", + administration = "DIRM / DM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 3, + controlUnitId = + 10002, + name = + "Semi-rigide 1", + ), + LegacyControlUnitResourceEntity( + id = 5, + controlUnitId = + 10002, + name = "Voiture", + ), + ), + ), + ), ), - ), - ), - ) + ) // Then assertThat(newMissionUpdated.mission.controlUnits).hasSize(1) assertThat(newMissionUpdated.mission.controlUnits.first().id).isEqualTo(10002) assertThat(newMissionUpdated.mission.controlUnits.first().name).isEqualTo("DML 2A") assertThat(newMissionUpdated.mission.controlUnits.first().administration) - .isEqualTo("DIRM / DM") + .isEqualTo("DIRM / DM") assertThat(newMissionUpdated.mission.controlUnits.first().resources).hasSize(2) assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().id).isEqualTo(3) assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().controlUnitId) - .isEqualTo(10002) + .isEqualTo(10002) assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().name) - .isEqualTo("Semi-rigide 1") + .isEqualTo("Semi-rigide 1") assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().id).isEqualTo(5) assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().controlUnitId) - .isEqualTo(10002) + .isEqualTo(10002) assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().name) - .isEqualTo("Voiture") + .isEqualTo("Voiture") } @Test @@ -614,28 +955,28 @@ class JpaMissionRepositoryITests : AbstractDBTests() { val mission = jpaMissionRepository.findById(25) val newControlUnitResource = jpaControlUnitResourceRepository.findById(10) val newControlUnit = - jpaControlUnitRepository.findById( - requireNotNull(newControlUnitResource.controlUnit.id), - ) + jpaControlUnitRepository.findById( + requireNotNull(newControlUnitResource.controlUnit.id), + ) val nextMission = - mission.copy( - controlUnits = - mission.controlUnits.plus( - LegacyControlUnitEntity( - id = requireNotNull(newControlUnit.controlUnit.id), - administration = newControlUnit.administration.name, - isArchived = newControlUnit.controlUnit.isArchived, - name = newControlUnit.controlUnit.name, - resources = - listOf( - newControlUnitResource - .toLegacyControlUnitResource(), - ), - contact = null, - ), - ), - ) + mission.copy( + controlUnits = + mission.controlUnits.plus( + LegacyControlUnitEntity( + id = requireNotNull(newControlUnit.controlUnit.id), + administration = newControlUnit.administration.name, + isArchived = newControlUnit.controlUnit.isArchived, + name = newControlUnit.controlUnit.name, + resources = + listOf( + newControlUnitResource + .toLegacyControlUnitResource(), + ), + contact = null, + ), + ), + ) val updatedMission = jpaMissionRepository.save(nextMission) @@ -644,12 +985,12 @@ class JpaMissionRepositoryITests : AbstractDBTests() { assertThat(updatedMission.mission.controlUnits.first().resources).hasSize(1) assertThat(updatedMission.mission.controlUnits.first().resources.first().id).isEqualTo(3) assertThat(updatedMission.mission.controlUnits.first().resources.first().controlUnitId) - .isEqualTo(10002) + .isEqualTo(10002) assertThat(updatedMission.mission.controlUnits.last().id).isEqualTo(10018) assertThat(updatedMission.mission.controlUnits.last().resources).hasSize(1) assertThat(updatedMission.mission.controlUnits.last().resources.first().id).isEqualTo(10) assertThat(updatedMission.mission.controlUnits.last().resources.first().controlUnitId) - .isEqualTo(10018) + .isEqualTo(10018) } @Test @@ -657,33 +998,33 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save should throw an exception When the resource id is not found`() { // Given val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 5, - name = "DPM – DDTM 35", - administration = "DDTM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 123456, - controlUnitId = 5, - name = "PAM Jeanne Barret", - ), - ), - ), - ), - isGeometryComputedFromControls = false, - ) + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 5, + name = "DPM – DDTM 35", + administration = "DDTM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 123456, + controlUnitId = 5, + name = "PAM Jeanne Barret", + ), + ), + ), + ), + isGeometryComputedFromControls = false, + ) // When val throwable = catchThrowable { jpaMissionRepository.save(newMission) } @@ -697,26 +1038,26 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save should throw an exception When the unit id is not found`() { // Given val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 123456, - name = "PAM Jeanne Barret", - administration = "", - isArchived = false, - resources = listOf(), - ), - ), - isGeometryComputedFromControls = false, - ) + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 123456, + name = "PAM Jeanne Barret", + administration = "", + isArchived = false, + resources = listOf(), + ), + ), + isGeometryComputedFromControls = false, + ) // When val throwable = catchThrowable { jpaMissionRepository.save(newMission) } @@ -730,90 +1071,90 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save Should update mission`() { // Given val infraction = - InfractionEntity( - id = UUID.randomUUID().toString(), - natinf = listOf("53432"), - observations = "This is an infraction", - registrationNumber = "REGISTRATION NUM", - companyName = "ACME inc.", - relevantCourt = "MARITIME_COURT", - infractionType = InfractionTypeEnum.WITHOUT_REPORT, - formalNotice = FormalNoticeEnum.NO, - toProcess = false, - controlledPersonIdentity = "Dick Hoover", - vesselType = VesselTypeEnum.FISHING, - vesselSize = VesselSizeEnum.FROM_12_TO_24m, - ) + InfractionEntity( + id = UUID.randomUUID().toString(), + natinf = listOf("53432"), + observations = "This is an infraction", + registrationNumber = "REGISTRATION NUM", + companyName = "ACME inc.", + relevantCourt = "MARITIME_COURT", + infractionType = InfractionTypeEnum.WITHOUT_REPORT, + formalNotice = FormalNoticeEnum.NO, + toProcess = false, + controlledPersonIdentity = "Dick Hoover", + vesselType = VesselTypeEnum.FISHING, + vesselSize = VesselSizeEnum.FROM_12_TO_24m, + ) val controlAction = - EnvActionControlEntity( - id = UUID.randomUUID(), - observations = "RAS", - actionNumberOfControls = 12, - actionTargetType = ActionTargetTypeEnum.VEHICLE, - vehicleType = VehicleTypeEnum.VESSEL, - infractions = listOf(infraction), - ) + EnvActionControlEntity( + id = UUID.randomUUID(), + observations = "RAS", + actionNumberOfControls = 12, + actionTargetType = ActionTargetTypeEnum.VEHICLE, + vehicleType = VehicleTypeEnum.VESSEL, + infractions = listOf(infraction), + ) val surveillanceAction = - EnvActionSurveillanceEntity( - id = UUID.randomUUID(), - observations = "This is a surveillance action", - ) + EnvActionSurveillanceEntity( + id = UUID.randomUUID(), + observations = "This is a surveillance action", + ) val noteAction = - EnvActionNoteEntity( - id = UUID.randomUUID(), - observations = "This is a note", - ) + EnvActionNoteEntity( + id = UUID.randomUUID(), + observations = "This is a note", + ) val missionToUpdate = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - openBy = "John Smith", - closedBy = "Carol Tim", - facade = "MEMN", - geom = polygon, - observationsCacem = null, - observationsCnsp = null, - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isClosed = false, - isDeleted = false, - envActions = listOf(controlAction, surveillanceAction, noteAction), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ) - val expectedUpdatedMission = - MissionDTO( - mission = MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - openBy = "John Smith", - closedBy = "Carol Tim", - facade = "MEMN", - geom = polygon, - observationsCacem = null, - observationsCnsp = null, - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = - ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isClosed = false, - isDeleted = false, - envActions = - listOf( - controlAction, - surveillanceAction, - noteAction, - ), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ), - ) + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + openBy = "John Smith", + closedBy = "Carol Tim", + facade = "MEMN", + geom = polygon, + observationsCacem = null, + observationsCnsp = null, + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isClosed = false, + isDeleted = false, + envActions = listOf(controlAction, surveillanceAction, noteAction), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ) + val expectedUpdatedMission = + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + openBy = "John Smith", + closedBy = "Carol Tim", + facade = "MEMN", + geom = polygon, + observationsCacem = null, + observationsCnsp = null, + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = + ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isClosed = false, + isDeleted = false, + envActions = + listOf( + controlAction, + surveillanceAction, + noteAction, + ), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ), + ) // When jpaMissionRepository.save(missionToUpdate) assertThat(jpaMissionRepository.findFullMissionById(10)).isEqualTo(expectedUpdatedMission) @@ -825,53 +1166,53 @@ class JpaMissionRepositoryITests : AbstractDBTests() { // Given val envAction = - EnvActionControlEntity( - id = UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), - actionTargetType = ActionTargetTypeEnum.VEHICLE, - vehicleType = VehicleTypeEnum.VESSEL, - actionNumberOfControls = 4, - ) + EnvActionControlEntity( + id = UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), + actionTargetType = ActionTargetTypeEnum.VEHICLE, + vehicleType = VehicleTypeEnum.VESSEL, + actionNumberOfControls = 4, + ) val missionToUpdate = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - facade = "NAMO", - geom = polygon, - observationsCacem = null, - observationsCnsp = null, - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isClosed = false, - isDeleted = false, - envActions = listOf(envAction), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ) - val expectedUpdatedMission = - MissionDTO( - mission = MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - facade = "NAMO", - geom = polygon, - observationsCacem = null, - observationsCnsp = null, - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = - ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isClosed = false, - isDeleted = false, - envActions = listOf(envAction), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ), - ) + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + facade = "NAMO", + geom = polygon, + observationsCacem = null, + observationsCnsp = null, + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isClosed = false, + isDeleted = false, + envActions = listOf(envAction), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ) + val expectedUpdatedMission = + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + facade = "NAMO", + geom = polygon, + observationsCacem = null, + observationsCnsp = null, + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = + ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isClosed = false, + isDeleted = false, + envActions = listOf(envAction), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ), + ) // When jpaMissionRepository.save(missionToUpdate) val updatedMission = jpaMissionRepository.findFullMissionById(10) @@ -882,35 +1223,46 @@ class JpaMissionRepositoryITests : AbstractDBTests() { @Transactional fun `save Should update subThemes of envActions`() { val mission = jpaMissionRepository.findById(34) - val envAction = mission.envActions?.find { it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") } + val envAction = + mission.envActions?.find { + it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") + } assertThat(envAction?.controlPlans?.size).isEqualTo(1) assertThat(envAction?.controlPlans?.get(0)?.subThemeIds?.size).isEqualTo(2) - val nextControlPlans = listOf( - EnvActionControlPlanEntity( - subThemeIds = listOf(53, 34), - themeId = 2, - ), - EnvActionControlPlanEntity( - tagIds = listOf(1, 2, 3), - themeId = 11, - ), - EnvActionControlPlanEntity( - themeId = 17, - ), - ) - val nextMission = mission.copy( - envActions = mission.envActions?.map { - if (it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") && it is EnvActionControlEntity) { - it.copy(controlPlans = nextControlPlans) - } else { - it - } - }, - ) + val nextControlPlans = + listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(53, 34), + themeId = 2, + ), + EnvActionControlPlanEntity( + tagIds = listOf(1, 2, 3), + themeId = 11, + ), + EnvActionControlPlanEntity( + themeId = 17, + ), + ) + val nextMission = + mission.copy( + envActions = + mission.envActions?.map { + if (it.id == + UUID.fromString( + "b8007c8a-5135-4bc3-816f-c69c7b75d807" + ) && it is EnvActionControlEntity + ) { + it.copy(controlPlans = nextControlPlans) + } else { + it + } + }, + ) val updatedMission = jpaMissionRepository.save(nextMission) - val updatedControlPlan = updatedMission.mission.envActions?.find { - it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") - }?.controlPlans + val updatedControlPlan = + updatedMission.mission.envActions + ?.find { it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") } + ?.controlPlans assertThat(updatedControlPlan?.size).isEqualTo(3) assertThat(updatedControlPlan?.get(0)?.subThemeIds?.size).isEqualTo(2) assertThat(updatedControlPlan?.get(0)?.subThemeIds?.get(0)).isEqualTo(53) From 5ba97293c8048662c58cadb247b2cbeab01b1f64 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Fri, 8 Dec 2023 09:37:36 +0100 Subject: [PATCH 27/53] wip --- .../EnvActionControlPlanSubThemeEntity.kt | 8 -- .../controlPlan/GetControlPlansByYear.kt | 14 +- .../GetControlPlanSubThemesByYear.kt | 16 --- .../bff/outputs/ControlPlanThemeDataOutput.kt | 19 +++ .../MissionEnvActionSubThemeDataOutput.kt | 22 --- .../endpoints/bff/ControlPlansController.kt | 30 ++-- .../database/model/ControlPlanTagModel.kt | 33 ++--- .../EnvActionsControlPlanSubThemeModel.kt | 56 ++++---- .../model/EnvActionsControlPlanTagModel.kt | 56 ++++---- .../repositories/JpaMissionRepository.kt | 132 ++++++++++-------- .../interfaces/IDBControlPlanTagRepository.kt | 6 +- .../GetControlPlanSubThemesByYearUTest.kt | 8 +- .../ControlPlanSubThemesControllerITests.kt | 8 +- 13 files changed, 188 insertions(+), 220 deletions(-) delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt rename backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/{controlPlanSubThemes => controlPlan}/GetControlPlanSubThemesByYearUTest.kt (83%) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt deleted file mode 100644 index 2fb3ef3ad..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanSubThemeEntity.kt +++ /dev/null @@ -1,8 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction - -data class EnvActionControlPlanSubThemeEntity( - val subThemeId: Int, - val tags: List, - val theme: String, - val subTheme: String, -) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt index 9881f6668..192fc7e06 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt @@ -11,9 +11,9 @@ import org.slf4j.LoggerFactory @UseCase class GetControlPlansByYear( - private val controlPlanThemeRepository: IControlPlanThemeRepository, - private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository, - private val controlPlanTagRepository: IControlPlanTagRepository, + private val controlPlanThemeRepository: IControlPlanThemeRepository, + private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository, + private val controlPlanTagRepository: IControlPlanTagRepository, ) { private val logger = LoggerFactory.getLogger(GetControlPlansByYear::class.java) fun execute(year: Int): ControlPlanByYear { @@ -26,8 +26,8 @@ class GetControlPlansByYear( } typealias ControlPlanByYear = - Triple< - List, - List, - List, + Triple< + List, + List, + List, > diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt deleted file mode 100644 index 8d2c485a9..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYear.kt +++ /dev/null @@ -1,16 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes - -import fr.gouv.cacem.monitorenv.config.UseCase -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity -import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository -import org.slf4j.LoggerFactory - -@UseCase -class GetControlPlanSubThemesByYear(private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository) { - private val logger = LoggerFactory.getLogger(GetControlPlanSubThemesByYear::class.java) - fun execute(year: Int): List { - val controlPlanSubThemes = controlPlanSubThemeRepository.findByYear(year) - logger.info("Found ${controlPlanSubThemes.size} control plan (sub)themes for year $year") - return controlPlanSubThemes - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt new file mode 100644 index 000000000..53a22bfc0 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanThemeDataOutput.kt @@ -0,0 +1,19 @@ +package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity + +data class ControlPlanThemeDataOutput( + val id: Int, + val theme: String, +) { + companion object { + fun fromControlPlanThemeEntity( + controlPlanThemeEntity: ControlPlanThemeEntity, + ): ControlPlanThemeDataOutput { + return ControlPlanThemeDataOutput( + id = controlPlanThemeEntity.id, + theme = controlPlanThemeEntity.theme, + ) + } + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt deleted file mode 100644 index a51a1ca3f..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionSubThemeDataOutput.kt +++ /dev/null @@ -1,22 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.missions - -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity - -data class MissionEnvActionSubThemeDataOutput( - val id: Int, - val subTheme: String, - val theme: String, - val tags: List, -) { - companion object { - fun fromEnvActionControlPlanSubThemeEntity( - envActionControlPlanSubThemeEntity: EnvActionControlPlanSubThemeEntity, - ) = - MissionEnvActionSubThemeDataOutput( - id = envActionControlPlanSubThemeEntity.subThemeId, - theme = envActionControlPlanSubThemeEntity.theme, - subTheme = envActionControlPlanSubThemeEntity.subTheme, - tags = envActionControlPlanSubThemeEntity.tags, - ) - } -} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt index 11766d42f..d4c748623 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt @@ -14,12 +14,12 @@ import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/bff/v1/control_plans") @Tag( - name = "Control Plan Themes, SubThemes and tags", - description = "API des sous thématiques des plan de contrôle", + name = "Control Plan Themes, SubThemes and tags", + description = "API des sous thématiques des plan de contrôle", ) class ControlPlansController( - private val getControlPlans: GetControlPlans, - private val getControlPlansByYear: GetControlPlansByYear, + private val getControlPlans: GetControlPlans, + private val getControlPlansByYear: GetControlPlansByYear, ) { @GetMapping("/") @@ -27,27 +27,27 @@ class ControlPlansController( fun getAll(): ControlPlanDataOutput { val controlPlan = getControlPlans.execute() return ControlPlanDataOutput.fromControlPlanEntities( - themes = controlPlan.first, - subThemes = controlPlan.second, - tags = controlPlan.third, + themes = controlPlan.first, + subThemes = controlPlan.second, + tags = controlPlan.third, ) } @GetMapping("/{year}") @Operation( - summary = - "Get control plan themes, subthemes and tags and allowed tags for a given year", + summary = + "Get control plan themes, subthemes and tags and allowed tags for a given year", ) fun getControlPlansByYear( - @PathParam("validity year of the control plan themes") - @PathVariable(name = "year") - year: Int, + @PathParam("validity year of the control plan themes") + @PathVariable(name = "year") + year: Int, ): ControlPlanDataOutput { val controlPlan = getControlPlansByYear.execute(year) return ControlPlanDataOutput.fromControlPlanEntities( - themes = controlPlan.first, - subThemes = controlPlan.second, - tags = controlPlan.third, + themes = controlPlan.first, + subThemes = controlPlan.second, + tags = controlPlan.third, ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt index bd5c9b9cb..2aaf24d1b 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt @@ -17,27 +17,24 @@ import org.hibernate.annotations.CacheConcurrencyStrategy @Entity @Table(name = "control_plan_tags") @Cache( - usage = CacheConcurrencyStrategy.READ_WRITE, + usage = CacheConcurrencyStrategy.READ_WRITE, ) class ControlPlanTagModel( - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id", nullable = false, updatable = false) - val id: Int, - - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "theme_id") - val controlPlanTheme: ControlPlanThemeModel, - - @Column(name = "tag") - val tag: String, - + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false, updatable = false) + val id: Int, + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "theme_id") + val controlPlanTheme: ControlPlanThemeModel, + @Column(name = "tag") val tag: String, ) { - fun toControlPlanTagEntity() = ControlPlanTagEntity( - id = this.id, - tag = this.tag, - themeId = this.controlPlanTheme.id, - ) + fun toControlPlanTagEntity() = + ControlPlanTagEntity( + id = this.id, + tag = this.tag, + themeId = this.controlPlanTheme.id, + ) override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt index 3667b6370..b0f82f94c 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt @@ -9,39 +9,37 @@ import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne import jakarta.persistence.MapsId import jakarta.persistence.Table -import org.hibernate.Hibernate import java.io.Serializable import java.util.UUID +import org.hibernate.Hibernate @Entity @Table(name = "env_actions_control_plan_sub_themes") class EnvActionsControlPlanSubThemeModel( - @EmbeddedId - val id: EnvActionsSubThemePk, - - @ManyToOne(fetch = FetchType.LAZY) - @MapsId("envActionId") - @JoinColumn(name = "env_action_id") - val envAction: EnvActionModel? = null, - - @ManyToOne(fetch = FetchType.LAZY) - @MapsId("subthemeId") - @JoinColumn(name = "subtheme_id") - val controlPlanSubTheme: ControlPlanSubThemeModel? = null, - + @EmbeddedId val id: EnvActionsSubThemePk, + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("envActionId") + @JoinColumn(name = "env_action_id") + val envAction: EnvActionModel? = null, + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("subthemeId") + @JoinColumn(name = "subtheme_id") + val controlPlanSubTheme: ControlPlanSubThemeModel? = null, ) { companion object { fun fromEnvActionControlPlanSubThemeEntity( - envAction: EnvActionModel, - controlPlanSubTheme: ControlPlanSubThemeModel, - ) = EnvActionsControlPlanSubThemeModel( - id = EnvActionsSubThemePk( - envActionId = envAction.id, - subthemeId = controlPlanSubTheme.id, - ), - envAction = envAction, - controlPlanSubTheme = controlPlanSubTheme, - ) + envAction: EnvActionModel, + controlPlanSubTheme: ControlPlanSubThemeModel, + ) = + EnvActionsControlPlanSubThemeModel( + id = + EnvActionsSubThemePk( + envActionId = envAction.id, + subthemeId = controlPlanSubTheme.id, + ), + envAction = envAction, + controlPlanSubTheme = controlPlanSubTheme, + ) } override fun equals(other: Any?): Boolean { @@ -57,18 +55,14 @@ class EnvActionsControlPlanSubThemeModel( @Embeddable data class EnvActionsSubThemePk( - @Column(name = "env_action_id") - val envActionId: UUID, - - @Column(name = "subtheme_id") - val subthemeId: Int, + @Column(name = "env_action_id") val envActionId: UUID, + @Column(name = "subtheme_id") val subthemeId: Int, ) : Serializable { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is EnvActionsSubThemePk) return false - return envActionId == other.envActionId && - subthemeId == other.subthemeId + return envActionId == other.envActionId && subthemeId == other.subthemeId } override fun hashCode(): Int { diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt index a3cdf267a..f579bdc5e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt @@ -9,39 +9,37 @@ import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne import jakarta.persistence.MapsId import jakarta.persistence.Table -import org.hibernate.Hibernate import java.io.Serializable import java.util.UUID +import org.hibernate.Hibernate @Entity @Table(name = "env_actions_control_plan_tags") class EnvActionsControlPlanTagModel( - @EmbeddedId - val id: EnvActionsTagPk, - - @ManyToOne(fetch = FetchType.LAZY) - @MapsId("envActionId") - @JoinColumn(name = "env_action_id") - val envAction: EnvActionModel? = null, - - @ManyToOne(fetch = FetchType.EAGER) - @MapsId("tagId") - @JoinColumn(name = "tag_id") - val controlPlanTag: ControlPlanTagModel? = null, - + @EmbeddedId val id: EnvActionsTagPk, + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("envActionId") + @JoinColumn(name = "env_action_id") + val envAction: EnvActionModel? = null, + @ManyToOne(fetch = FetchType.EAGER) + @MapsId("tagId") + @JoinColumn(name = "tag_id") + val controlPlanTag: ControlPlanTagModel? = null, ) { companion object { fun fromEnvActionControlPlanTagEntity( - envAction: EnvActionModel, - controlPlanTag: ControlPlanTagModel, - ) = EnvActionsControlPlanTagModel( - id = EnvActionsTagPk( - envActionId = envAction.id!!, - tagId = controlPlanTag.id!!, - ), - envAction = envAction, - controlPlanTag = controlPlanTag, - ) + envAction: EnvActionModel, + controlPlanTag: ControlPlanTagModel, + ) = + EnvActionsControlPlanTagModel( + id = + EnvActionsTagPk( + envActionId = envAction.id!!, + tagId = controlPlanTag.id!!, + ), + envAction = envAction, + controlPlanTag = controlPlanTag, + ) } override fun equals(other: Any?): Boolean { @@ -57,18 +55,14 @@ class EnvActionsControlPlanTagModel( @Embeddable data class EnvActionsTagPk( - @Column(name = "env_action_id") - val envActionId: UUID, - - @Column(name = "tag_id") - val tagId: Int, + @Column(name = "env_action_id") val envActionId: UUID, + @Column(name = "tag_id") val tagId: Int, ) : Serializable { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is EnvActionsTagPk) return false - return envActionId == other.envActionId && - tagId == other.tagId + return envActionId == other.envActionId && tagId == other.tagId } override fun hashCode(): Int { diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt index 05ed5a20b..f72a687fc 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt @@ -11,20 +11,20 @@ import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces. import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanThemeRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlUnitResourceRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBMissionRepository +import java.time.Instant import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.Modifying import org.springframework.stereotype.Repository import org.springframework.transaction.annotation.Transactional -import java.time.Instant @Repository class JpaMissionRepository( - private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, - private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, - private val dbControlPlanTagRepository: IDBControlPlanTagRepository, - private val dbControlUnitResourceRepository: IDBControlUnitResourceRepository, - private val dbMissionRepository: IDBMissionRepository, - private val mapper: ObjectMapper, + private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, + private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, + private val dbControlPlanTagRepository: IDBControlPlanTagRepository, + private val dbControlUnitResourceRepository: IDBControlUnitResourceRepository, + private val dbMissionRepository: IDBMissionRepository, + private val mapper: ObjectMapper, ) : IMissionRepository { override fun count(): Long { return dbMissionRepository.count() @@ -37,25 +37,25 @@ class JpaMissionRepository( } override fun findAllFullMissions( - startedAfter: Instant, - startedBefore: Instant?, - missionTypes: List?, - missionStatuses: List?, - missionSources: List?, - seaFronts: List?, - pageable: Pageable, + startedAfter: Instant, + startedBefore: Instant?, + missionTypes: List?, + missionStatuses: List?, + missionSources: List?, + seaFronts: List?, + pageable: Pageable, ): List { val missionSourcesAsStringArray = missionSources?.map { it.name } return dbMissionRepository.findAll( - startedAfter = startedAfter, - startedBefore = startedBefore, - missionTypes = convertToPGArray(missionTypes), - missionStatuses = convertToPGArray(missionStatuses), - missionSources = convertToPGArray(missionSourcesAsStringArray), - seaFronts = convertToPGArray(seaFronts), - pageable = pageable, - ) - .map { it.toMissionDTO(mapper) } + startedAfter = startedAfter, + startedBefore = startedBefore, + missionTypes = convertToPGArray(missionTypes), + missionStatuses = convertToPGArray(missionStatuses), + missionSources = convertToPGArray(missionSourcesAsStringArray), + seaFronts = convertToPGArray(seaFronts), + pageable = pageable, + ) + .map { it.toMissionDTO(mapper) } } override fun findByIds(ids: List): List { @@ -75,25 +75,25 @@ class JpaMissionRepository( } override fun findAll( - startedAfter: Instant, - startedBefore: Instant?, - missionTypes: List?, - missionStatuses: List?, - missionSources: List?, - seaFronts: List?, - pageable: Pageable, + startedAfter: Instant, + startedBefore: Instant?, + missionTypes: List?, + missionStatuses: List?, + missionSources: List?, + seaFronts: List?, + pageable: Pageable, ): List { val missionSourcesAsStringArray = missionSources?.map { it.name } return dbMissionRepository.findAll( - startedAfter = startedAfter, - startedBefore = startedBefore, - missionTypes = convertToPGArray(missionTypes), - missionStatuses = convertToPGArray(missionStatuses), - missionSources = convertToPGArray(missionSourcesAsStringArray), - seaFronts = convertToPGArray(seaFronts), - pageable = pageable, - ) - .map { it.toMissionEntity(mapper) } + startedAfter = startedAfter, + startedBefore = startedBefore, + missionTypes = convertToPGArray(missionTypes), + missionStatuses = convertToPGArray(missionStatuses), + missionSources = convertToPGArray(missionSourcesAsStringArray), + seaFronts = convertToPGArray(seaFronts), + pageable = pageable, + ) + .map { it.toMissionEntity(mapper) } } override fun findFullMissionById(missionId: Int): MissionDTO { @@ -108,13 +108,16 @@ class JpaMissionRepository( @Modifying(clearAutomatically = true, flushAutomatically = true) override fun save(mission: MissionEntity): MissionDTO { // Extract all control units resources unique control unit resource IDs - val uniqueControlUnitResourceIds = mission.controlUnits - .flatMap { controlUnit -> controlUnit.resources.map { it.id } } - .distinct() + val uniqueControlUnitResourceIds = + mission.controlUnits + .flatMap { controlUnit -> controlUnit.resources.map { it.id } } + .distinct() // Fetch all of them as models - val controlUnitResourceModels = dbControlUnitResourceRepository.findAllById(uniqueControlUnitResourceIds) + val controlUnitResourceModels = + dbControlUnitResourceRepository.findAllById(uniqueControlUnitResourceIds) // Create an `[id] → ControlUnitResourceModel` map - val controlUnitResourceModelMap = controlUnitResourceModels.associateBy { requireNotNull(it.id) } + val controlUnitResourceModelMap = + controlUnitResourceModels.associateBy { requireNotNull(it.id) } val controlPlanThemes = ArrayList() val controlPlanSubThemes = ArrayList() @@ -131,26 +134,33 @@ class JpaMissionRepository( } // Create a map from controlPlanThemes mapping each id to a reference to the model - val controlPlanThemesReferenceModelMap = controlPlanThemes?.distinct()?.associateWith { id -> - dbControlPlanThemeRepository.getReferenceById(id) - } + val controlPlanThemesReferenceModelMap = + controlPlanThemes?.distinct()?.associateWith { id -> + dbControlPlanThemeRepository.getReferenceById(id) + } // Create a map from controlPlanSubThemes mapping each id to a reference to the model - val controlPlanSubThemesReferenceModelMap = controlPlanSubThemes?.distinct()?.associateWith { id -> - dbControlPlanSubThemeRepository.getReferenceById(id) - } + val controlPlanSubThemesReferenceModelMap = + controlPlanSubThemes?.distinct()?.associateWith { id -> + dbControlPlanSubThemeRepository.getReferenceById(id) + } // Create a map from controlPlanTags mapping each id to a reference to the model - val controlPlanTagsReferenceModelMap = controlPlanTags?.distinct()?.associateWith { id -> - dbControlPlanTagRepository.getReferenceById(id) - } + val controlPlanTagsReferenceModelMap = + controlPlanTags?.distinct()?.associateWith { id -> + dbControlPlanTagRepository.getReferenceById(id) + } - val missionModel = MissionModel.fromMissionEntity( - mission = mission, - controlUnitResourceModelMap = controlUnitResourceModelMap, - controlPlanThemesReferenceModelMap = controlPlanThemesReferenceModelMap ?: emptyMap(), - controlPlanSubThemesReferenceModelMap = controlPlanSubThemesReferenceModelMap ?: emptyMap(), - controlPlanTagsReferenceModelMap = controlPlanTagsReferenceModelMap ?: emptyMap(), - mapper = mapper, - ) + val missionModel = + MissionModel.fromMissionEntity( + mission = mission, + controlUnitResourceModelMap = controlUnitResourceModelMap, + controlPlanThemesReferenceModelMap = controlPlanThemesReferenceModelMap + ?: emptyMap(), + controlPlanSubThemesReferenceModelMap = + controlPlanSubThemesReferenceModelMap ?: emptyMap(), + controlPlanTagsReferenceModelMap = controlPlanTagsReferenceModelMap + ?: emptyMap(), + mapper = mapper, + ) return dbMissionRepository.saveAndFlush(missionModel).toMissionDTO(mapper) } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt index 371bed3fc..fe7ffe8a8 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt @@ -7,8 +7,8 @@ import org.springframework.data.jpa.repository.Query interface IDBControlPlanTagRepository : JpaRepository { @Query( - value = - """ + value = + """ SELECT tags.* FROM control_plan_tags tags, control_plan_sub_themes s, control_plan_themes th WHERE tags.theme_id = th.id @@ -16,7 +16,7 @@ interface IDBControlPlanTagRepository : JpaRepository AND s.year = :year ORDER BY tags.id ASC """, - nativeQuery = true, + nativeQuery = true, ) fun findByYearOrderById(year: Int): List } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt similarity index 83% rename from backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt rename to backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt index 3b457c9d5..ab966d9f3 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlanSubThemes/GetControlPlanSubThemesByYearUTest.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt @@ -1,4 +1,4 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes +package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan import com.nhaarman.mockitokotlin2.given import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity @@ -17,14 +17,14 @@ class GetControlPlanSubThemesByYearUTest { val controlPlanSubThemes = listOf( ControlPlanSubThemeEntity( id = 1, - theme = "ControlPlanTheme Name", + theme = "ControlPlanThemeEntity Name", subTheme = "ControlPlanSubTheme Name", allowedTags = listOf("tag1", "tag2"), year = 2023, ), ControlPlanSubThemeEntity( id = 2, - theme = "ControlPlanTheme Name 2", + theme = "ControlPlanThemeEntity Name 2", subTheme = "ControlPlanSubTheme Name 2", allowedTags = null, year = 2023, @@ -33,7 +33,7 @@ class GetControlPlanSubThemesByYearUTest { given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) - val result = GetControlPlanSubThemesByYear(controlPlanSubThemeRepository).execute(2023) + val result = GetControlPlansByYear(controlPlanSubThemeRepository).execute(2023) assertThat(result.size).isEqualTo(2) assertThat(result).isEqualTo(controlPlanSubThemes) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt index 59d8cae7a..9d46374d2 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt @@ -3,7 +3,7 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff import com.nhaarman.mockitokotlin2.verify import fr.gouv.cacem.monitorenv.config.WebSecurityConfig import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity -import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlanSubThemes.GetControlPlanSubThemesByYear +import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlansByYear import org.junit.jupiter.api.Test import org.mockito.BDDMockito import org.springframework.beans.factory.annotation.Autowired @@ -22,7 +22,7 @@ class ControlPlanSubThemesControllerITests { private lateinit var mockMvc: MockMvc @MockBean - private lateinit var getControlPlanSubThemesByYear: GetControlPlanSubThemesByYear + private lateinit var getControlPlansByYear: GetControlPlansByYear @Test fun `Should get all control plan themes`() { @@ -34,7 +34,7 @@ class ControlPlanSubThemesControllerITests { allowedTags = listOf("tag1", "tag2"), year = 2024, ) - BDDMockito.given(getControlPlanSubThemesByYear.execute(2024)).willReturn(listOf(ControlPlanSubTheme)) + BDDMockito.given(getControlPlansByYear.execute(2024)).willReturn(listOf(ControlPlanSubTheme)) // When mockMvc.perform(get("/bff/v1/controlPlanSubThemes/2024")) // Then @@ -46,6 +46,6 @@ class ControlPlanSubThemesControllerITests { .andExpect(jsonPath("$[0].allowedTags[0]").value(ControlPlanSubTheme.allowedTags?.get(0))) .andExpect(jsonPath("$[0].allowedTags[1]").value(ControlPlanSubTheme.allowedTags?.get(1))) - verify(getControlPlanSubThemesByYear).execute(2024) + verify(getControlPlansByYear).execute(2024) } } From 2246d9137ac434bdbc6395fab5b260eb907bddd0 Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Fri, 8 Dec 2023 15:16:28 +0100 Subject: [PATCH 28/53] backend for control_plans api & envActions.controlPlans --- .../IControlPlanThemeRepository.kt | 7 + .../JpaControlPlanTagRepository.kt | 2 +- .../JpaControlPlanThemeRepository.kt | 15 ++ .../IDBControlPlanThemeRepository.kt | 19 +++ .../GetControlPlanSubThemesByYearUTest.kt | 41 ----- .../controlPlan/GetControlPlansByYearUTest.kt | 84 +++++----- .../ControlPlanSubThemesControllerITests.kt | 51 ------ .../bff/ControlPlansControllerITests.kt | 156 +++++++++--------- 8 files changed, 162 insertions(+), 213 deletions(-) create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt create mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt delete mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt delete mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt new file mode 100644 index 000000000..4724bc020 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt @@ -0,0 +1,7 @@ +package fr.gouv.cacem.monitorenv.domain.repositories + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity + +interface IControlPlanThemeRepository { + fun findByYear(year: Int): List +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt index 5da1764cc..97530bf41 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt @@ -7,7 +7,7 @@ import org.springframework.stereotype.Repository @Repository class JpaControlPlanTagRepository( - private val dbControlPlanTagRepository: IDBControlPlanTagRepository, + private val dbControlPlanTagRepository: IDBControlPlanTagRepository, ) : IControlPlanTagRepository { override fun findAll(): List { return dbControlPlanTagRepository.findAll().map { it.toControlPlanTagEntity() } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt new file mode 100644 index 000000000..ee9ef244b --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt @@ -0,0 +1,15 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories + +import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanThemeRepository +import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanThemeRepository +import org.springframework.stereotype.Repository + +@Repository +class JpaControlPlanThemeRepository( + private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, +) : IControlPlanThemeRepository { + override fun findByYear(year: Int): List { + return dbControlPlanThemeRepository.findByYearOrderById(year).map { it.toControlPlanThemeEntity() } + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt new file mode 100644 index 000000000..f3bd070af --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt @@ -0,0 +1,19 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces + +import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanThemeModel +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Query + +interface IDBControlPlanThemeRepository : JpaRepository { + @Query( + value = """ + SELECT th.* + FROM control_plan_themes th, control_plan_sub_themes s + WHERE th.id = s.theme_id + AND s.year = :year + ORDER BY th.id ASC + """, + nativeQuery = true, + ) + fun findByYearOrderById(year: Int): List +} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt deleted file mode 100644 index ab966d9f3..000000000 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlanSubThemesByYearUTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -package fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan - -import com.nhaarman.mockitokotlin2.given -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity -import fr.gouv.cacem.monitorenv.domain.repositories.IControlPlanSubThemeRepository -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.extension.ExtendWith -import org.springframework.boot.test.mock.mockito.MockBean -import org.springframework.test.context.junit.jupiter.SpringExtension - -@ExtendWith(SpringExtension::class) -class GetControlPlanSubThemesByYearUTest { - @MockBean - private lateinit var controlPlanSubThemeRepository: IControlPlanSubThemeRepository - - fun `execute should return all ControlPlanSubThemes for the given year`() { - val controlPlanSubThemes = listOf( - ControlPlanSubThemeEntity( - id = 1, - theme = "ControlPlanThemeEntity Name", - subTheme = "ControlPlanSubTheme Name", - allowedTags = listOf("tag1", "tag2"), - year = 2023, - ), - ControlPlanSubThemeEntity( - id = 2, - theme = "ControlPlanThemeEntity Name 2", - subTheme = "ControlPlanSubTheme Name 2", - allowedTags = null, - year = 2023, - ), - ) - - given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) - - val result = GetControlPlansByYear(controlPlanSubThemeRepository).execute(2023) - - assertThat(result.size).isEqualTo(2) - assertThat(result).isEqualTo(controlPlanSubThemes) - } -} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt index b537b15a1..a79557bef 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt @@ -20,56 +20,56 @@ class GetControlPlansByYearUTest { fun `execute should return all ControlPlanThemes, ControlPlanSubThemes and ControlPlanTags for the given year`() { val controlPlanThemes = - listOf( - ControlPlanThemeEntity( - id = 1, - theme = "ControlPlanTheme Name", - ), - ControlPlanThemeEntity( - id = 2, - theme = "ControlPlanTheme Name 2", - ), - ) + listOf( + ControlPlanThemeEntity( + id = 1, + theme = "ControlPlanTheme Name", + ), + ControlPlanThemeEntity( + id = 2, + theme = "ControlPlanTheme Name 2", + ), + ) val controlPlanSubThemes = - listOf( - ControlPlanSubThemeEntity( - id = 1, - themeId = 1, - subTheme = "ControlPlanSubTheme Name", - year = 2023, - ), - ControlPlanSubThemeEntity( - id = 2, - themeId = 1, - subTheme = "ControlPlanSubTheme Name 2", - year = 2023, - ), - ) + listOf( + ControlPlanSubThemeEntity( + id = 1, + themeId = 1, + subTheme = "ControlPlanSubTheme Name", + year = 2023, + ), + ControlPlanSubThemeEntity( + id = 2, + themeId = 1, + subTheme = "ControlPlanSubTheme Name 2", + year = 2023, + ), + ) val controlPlanTags = - listOf( - ControlPlanTagEntity( - id = 1, - tag = "ControlPlanTag Name", - themeId = 1, - ), - ControlPlanTagEntity( - id = 2, - tag = "ControlPlanTag Name 2", - themeId = 2, - ), - ) + listOf( + ControlPlanTagEntity( + id = 1, + tag = "ControlPlanTag Name", + themeId = 1, + ), + ControlPlanTagEntity( + id = 2, + tag = "ControlPlanTag Name 2", + themeId = 2, + ), + ) given(controlPlanThemeRepository.findByYear(2023)).willReturn(controlPlanThemes) given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) given(controlPlanTagRepository.findByYear(2023)).willReturn(controlPlanTags) val result = - GetControlPlansByYear( - controlPlanThemeRepository = controlPlanThemeRepository, - controlPlanSubThemeRepository = controlPlanSubThemeRepository, - controlPlanTagRepository = controlPlanTagRepository, - ) - .execute(2023) + GetControlPlansByYear( + controlPlanThemeRepository = controlPlanThemeRepository, + controlPlanSubThemeRepository = controlPlanSubThemeRepository, + controlPlanTagRepository = controlPlanTagRepository, + ) + .execute(2023) assertThat(result.first.size).isEqualTo(2) assertThat(result).isEqualTo(controlPlanSubThemes) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt deleted file mode 100644 index 9d46374d2..000000000 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlanSubThemesControllerITests.kt +++ /dev/null @@ -1,51 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.api.endpoints.bff - -import com.nhaarman.mockitokotlin2.verify -import fr.gouv.cacem.monitorenv.config.WebSecurityConfig -import fr.gouv.cacem.monitorenv.domain.entities.controlPlanSubTheme.ControlPlanSubThemeEntity -import fr.gouv.cacem.monitorenv.domain.use_cases.controlPlan.GetControlPlansByYear -import org.junit.jupiter.api.Test -import org.mockito.BDDMockito -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest -import org.springframework.boot.test.mock.mockito.MockBean -import org.springframework.context.annotation.Import -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get -import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath -import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status - -@Import(WebSecurityConfig::class) -@WebMvcTest(value = [(ControlPlanSubThemesController::class)]) -class ControlPlanSubThemesControllerITests { - @Autowired - private lateinit var mockMvc: MockMvc - - @MockBean - private lateinit var getControlPlansByYear: GetControlPlansByYear - - @Test - fun `Should get all control plan themes`() { - // Given - val ControlPlanSubTheme = ControlPlanSubThemeEntity( - id = 1, - theme = "Theme Police des mouillages", - subTheme = "Sous Theme Mouillage individuel", - allowedTags = listOf("tag1", "tag2"), - year = 2024, - ) - BDDMockito.given(getControlPlansByYear.execute(2024)).willReturn(listOf(ControlPlanSubTheme)) - // When - mockMvc.perform(get("/bff/v1/controlPlanSubThemes/2024")) - // Then - .andExpect(status().isOk) - .andExpect(jsonPath("$[0].id").value(ControlPlanSubTheme.id)) - .andExpect(jsonPath("$[0].theme").value(ControlPlanSubTheme.theme)) - .andExpect(jsonPath("$[0].subTheme").value(ControlPlanSubTheme.subTheme)) - .andExpect(jsonPath("$[0].year").value(ControlPlanSubTheme.year)) - .andExpect(jsonPath("$[0].allowedTags[0]").value(ControlPlanSubTheme.allowedTags?.get(0))) - .andExpect(jsonPath("$[0].allowedTags[1]").value(ControlPlanSubTheme.allowedTags?.get(1))) - - verify(getControlPlansByYear).execute(2024) - } -} diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt index 76059b4ff..da1117c03 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt @@ -31,52 +31,52 @@ class ControlPlansControllerITests { fun `Should get all control plan themes`() { // Given val controlPlanTheme1 = - ControlPlanThemeEntity( - id = 1, - theme = "Theme Police des mouillages", - ) + ControlPlanThemeEntity( + id = 1, + theme = "Theme Police des mouillages", + ) val controlPlanTheme2 = - ControlPlanThemeEntity( - id = 2, - theme = "Theme Protection des espèces", - ) + ControlPlanThemeEntity( + id = 2, + theme = "Theme Protection des espèces", + ) val controlPlanSubTheme1 = - ControlPlanSubThemeEntity( - id = 10, - themeId = 1, - subTheme = "SubTheme ZMEL", - year = 2024, - ) + ControlPlanSubThemeEntity( + id = 10, + themeId = 1, + subTheme = "SubTheme ZMEL", + year = 2024, + ) val controlPlanTag = - ControlPlanTagEntity( - id = 100, - themeId = 2, - tag = "Tag Bichique", - ) + ControlPlanTagEntity( + id = 100, + themeId = 2, + tag = "Tag Bichique", + ) val controlPlan = - Triple( - listOf(controlPlanTheme1, controlPlanTheme2), - listOf(controlPlanSubTheme1), - listOf(controlPlanTag), - ) + Triple( + listOf(controlPlanTheme1, controlPlanTheme2), + listOf(controlPlanSubTheme1), + listOf(controlPlanTag), + ) BDDMockito.given(getControlPlans.execute()).willReturn(controlPlan) // When mockMvc.perform(get("/bff/v1/control_plans/")) - // Then - .andExpect(status().isOk) - .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) - .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) - .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) - .andExpect( - jsonPath("$.subThemes[\"10\"].subTheme") - .value(controlPlanSubTheme1.subTheme), - ) - .andExpect( - jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId), - ) - .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) - .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) - .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) + .andExpect( + jsonPath("$.subThemes[\"10\"].subTheme") + .value(controlPlanSubTheme1.subTheme), + ) + .andExpect( + jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId), + ) + .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) + .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) + .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) verify(getControlPlans).execute() } @@ -85,52 +85,52 @@ class ControlPlansControllerITests { fun `Should get all control plan themes by year`() { // Given val controlPlanTheme1 = - ControlPlanThemeEntity( - id = 1, - theme = "Theme Police des mouillages", - ) + ControlPlanThemeEntity( + id = 1, + theme = "Theme Police des mouillages", + ) val controlPlanTheme2 = - ControlPlanThemeEntity( - id = 2, - theme = "Theme Protection des espèces", - ) + ControlPlanThemeEntity( + id = 2, + theme = "Theme Protection des espèces", + ) val controlPlanSubTheme1 = - ControlPlanSubThemeEntity( - id = 10, - themeId = 1, - subTheme = "SubTheme ZMEL", - year = 2024, - ) + ControlPlanSubThemeEntity( + id = 10, + themeId = 1, + subTheme = "SubTheme ZMEL", + year = 2024, + ) val controlPlanTag = - ControlPlanTagEntity( - id = 100, - themeId = 2, - tag = "Tag Bichique", - ) + ControlPlanTagEntity( + id = 100, + themeId = 2, + tag = "Tag Bichique", + ) val controlPlan = - Triple( - listOf(controlPlanTheme1, controlPlanTheme2), - listOf(controlPlanSubTheme1), - listOf(controlPlanTag), - ) + Triple( + listOf(controlPlanTheme1, controlPlanTheme2), + listOf(controlPlanSubTheme1), + listOf(controlPlanTag), + ) BDDMockito.given(getControlPlansByYear.execute(2024)).willReturn(controlPlan) // When mockMvc.perform(get("/bff/v1/control_plans/2024")) - // Then - .andExpect(status().isOk) - .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) - .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) - .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) - .andExpect( - jsonPath("$.subThemes[\"10\"].subTheme") - .value(controlPlanSubTheme1.subTheme), - ) - .andExpect( - jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId), - ) - .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) - .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) - .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) + .andExpect( + jsonPath("$.subThemes[\"10\"].subTheme") + .value(controlPlanSubTheme1.subTheme), + ) + .andExpect( + jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId), + ) + .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) + .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) + .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) verify(getControlPlansByYear).execute(2024) } From 50a631382b5fa284f2b474764e0f6a5fe51d7eec Mon Sep 17 00:00:00 2001 From: Thomas Brosset Date: Fri, 8 Dec 2023 18:56:09 +0100 Subject: [PATCH 29/53] backend for reportings controlPlans --- .../repositories/JpaReportingRepository.kt | 176 +++++++++--------- 1 file changed, 90 insertions(+), 86 deletions(-) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt index 059b2a6c7..e8ee86b32 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt @@ -16,25 +16,25 @@ import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces. import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBMissionRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBReportingRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBSemaphoreRepository +import java.time.Instant +import java.util.UUID import org.springframework.dao.DataIntegrityViolationException import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.Modifying import org.springframework.orm.jpa.JpaObjectRetrievalFailureException import org.springframework.stereotype.Repository import org.springframework.transaction.annotation.Transactional -import java.time.Instant -import java.util.UUID @Repository class JpaReportingRepository( - private val dbReportingRepository: IDBReportingRepository, - private val dbMissionRepository: IDBMissionRepository, - private val dbSemaphoreRepository: IDBSemaphoreRepository, - private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, - private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, - private val dbControlUnitRepository: IDBControlUnitRepository, - private val dbEnvActionRepository: IDBEnvActionRepository, - private val mapper: ObjectMapper, + private val dbReportingRepository: IDBReportingRepository, + private val dbMissionRepository: IDBMissionRepository, + private val dbSemaphoreRepository: IDBSemaphoreRepository, + private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, + private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, + private val dbControlUnitRepository: IDBControlUnitRepository, + private val dbEnvActionRepository: IDBEnvActionRepository, + private val mapper: ObjectMapper, ) : IReportingRepository { @Transactional @@ -57,26 +57,26 @@ class JpaReportingRepository( } override fun findAll( - pageable: Pageable, - reportingType: List?, - seaFronts: List?, - sourcesType: List?, - startedAfter: Instant, - startedBefore: Instant?, - status: List?, + pageable: Pageable, + reportingType: List?, + seaFronts: List?, + sourcesType: List?, + startedAfter: Instant, + startedBefore: Instant?, + status: List?, ): List { val sourcesTypeAsStringArray = sourcesType?.map { it.name } val reportingTypeAsStringArray = reportingType?.map { it.name } return dbReportingRepository.findAll( - pageable, - reportingType = convertToString(reportingTypeAsStringArray), - seaFronts = convertToString(seaFronts), - sourcesType = convertToString(sourcesTypeAsStringArray), - startedAfter = startedAfter, - startedBefore = startedBefore, - status = convertToString(status), - ) - .map { it.toReportingDTO(mapper) } + pageable, + reportingType = convertToString(reportingTypeAsStringArray), + seaFronts = convertToString(seaFronts), + sourcesType = convertToString(sourcesTypeAsStringArray), + startedAfter = startedAfter, + startedBefore = startedBefore, + status = convertToString(status), + ) + .map { it.toReportingDTO(mapper) } } override fun findByControlUnitId(controlUnitId: Int): List { @@ -92,88 +92,92 @@ class JpaReportingRepository( override fun save(reporting: ReportingEntity): ReportingDTO { return try { val semaphoreReference = - if (reporting.semaphoreId != null) { - dbSemaphoreRepository.getReferenceById( - reporting.semaphoreId, - ) - } else { - null - } + if (reporting.semaphoreId != null) { + dbSemaphoreRepository.getReferenceById( + reporting.semaphoreId, + ) + } else { + null + } val controlUnitReference = - if (reporting.controlUnitId != null) { - dbControlUnitRepository.getReferenceById( - reporting.controlUnitId, - ) - } else { - null - } + if (reporting.controlUnitId != null) { + dbControlUnitRepository.getReferenceById( + reporting.controlUnitId, + ) + } else { + null + } val missionReference = - if (reporting.missionId != null) { - dbMissionRepository.getReferenceById( - reporting.missionId, - ) - } else { - null - } + if (reporting.missionId != null) { + dbMissionRepository.getReferenceById( + reporting.missionId, + ) + } else { + null + } val envActionReference = - if (reporting.attachedEnvActionId != null) { - dbEnvActionRepository.getReferenceById( - reporting.attachedEnvActionId, - ) - } else { - null - } + if (reporting.attachedEnvActionId != null) { + dbEnvActionRepository.getReferenceById( + reporting.attachedEnvActionId, + ) + } else { + null + } val controlPlanThemeReference = - if (reporting.themeId != null) { - dbControlPlanThemeRepository.getReferenceById( - reporting.themeId, - ) - } else { - null - } - val controlPlanSubThemesReferenceList = reporting.subThemeIds?.map { - dbControlPlanSubThemeRepository.getReferenceById(it) - } + if (reporting.themeId != null) { + dbControlPlanThemeRepository.getReferenceById( + reporting.themeId, + ) + } else { + null + } + val controlPlanSubThemesReferenceList = + reporting.subThemeIds?.map { + dbControlPlanSubThemeRepository.getReferenceById(it) + } // To save controlPlanSubThemes we must ensure that reportingId is set - // to simplify the understandability of the code, we do the same steps for creation and update + // to simplify the understandability of the code, we do the same steps for creation and + // update // even if it is not necessary for update // first save (ensure id is set) var reportingModel: ReportingModel if (reporting.id == null) { - reportingModel = dbReportingRepository.save( - ReportingModel.fromReportingEntity( - reporting = reporting, - semaphoreReference = semaphoreReference, - controlUnitReference = controlUnitReference, - missionReference = missionReference, - envActionReference = envActionReference, - controlPlanThemeReference = controlPlanThemeReference, - ), - ) + reportingModel = + dbReportingRepository.save( + ReportingModel.fromReportingEntity( + reporting = reporting, + semaphoreReference = semaphoreReference, + controlUnitReference = controlUnitReference, + missionReference = missionReference, + envActionReference = envActionReference, + controlPlanThemeReference = controlPlanThemeReference, + ), + ) } else { - reportingModel = ReportingModel.fromReportingEntity( - reporting = reporting, - semaphoreReference = semaphoreReference, - controlUnitReference = controlUnitReference, - missionReference = missionReference, - envActionReference = envActionReference, - controlPlanThemeReference = controlPlanThemeReference, - ) + reportingModel = + ReportingModel.fromReportingEntity( + reporting = reporting, + semaphoreReference = semaphoreReference, + controlUnitReference = controlUnitReference, + missionReference = missionReference, + envActionReference = envActionReference, + controlPlanThemeReference = controlPlanThemeReference, + ) } // set controlPlanSubThemes and save again (and flush) controlPlanSubThemesReferenceList?.forEach { it -> reportingModel.controlPlanSubThemes?.add( - ReportingsControlPlanSubThemeModel.fromModels(reportingModel, it), + ReportingsControlPlanSubThemeModel.fromModels(reportingModel, it), ) } dbReportingRepository.saveAndFlush(reportingModel).toReportingDTO(mapper) } catch (e: JpaObjectRetrievalFailureException) { throw NotFoundException( - "Invalid reference to semaphore, control unit or mission: not found in referential", - e, + "Invalid reference to semaphore, control unit or mission: not found in referential", + e, ) } catch (e: DataIntegrityViolationException) { throw NotFoundException("Invalid combination of mission and/or envAction", e) From 1b0c1706840920f1195612048e030fa240fdb5ef Mon Sep 17 00:00:00 2001 From: Claire Dagan Date: Fri, 8 Dec 2023 18:10:55 +0100 Subject: [PATCH 30/53] [ControlPlan] use new controlPlans data instead of themes --- .../IDBControlPlanThemeRepository.kt | 1 - .../mission_form/mission_actions.spec.ts | 12 ++-- frontend/src/api/controlPlans.ts | 13 ++++ frontend/src/api/missionsAPI.ts | 6 +- frontend/src/domain/entities/controlPlan.ts | 22 ++++++ frontend/src/domain/entities/missions.ts | 70 +++++++++++-------- .../ActionForm/ControlForm/ControlForm.tsx | 1 + .../ActionForm/Themes/ActionTheme.tsx | 41 ++++++++--- .../Themes/MultipleThemeElement.tsx | 4 ++ .../Themes/ProtectedSpeciesSelector.tsx | 32 --------- .../ActionForm/Themes/TagsSelector.tsx | 34 +++++++++ .../ThemeSelector/SubThemesSelector.tsx | 48 +++++++------ .../ActionForm/Themes/ThemeSelector/index.tsx | 33 ++++----- .../formikUseCases/updateActionThemes.ts | 24 +++---- .../missions/MissionForm/mission.json | 0 .../src/features/missions/Missions.helpers.ts | 37 ++++++++++ .../useGetPlanThemesAndSubThemesAsOptions.ts | 37 ++++++++++ 17 files changed, 280 insertions(+), 135 deletions(-) create mode 100644 frontend/src/api/controlPlans.ts create mode 100644 frontend/src/domain/entities/controlPlan.ts delete mode 100644 frontend/src/features/missions/MissionForm/ActionForm/Themes/ProtectedSpeciesSelector.tsx create mode 100644 frontend/src/features/missions/MissionForm/ActionForm/Themes/TagsSelector.tsx create mode 100644 frontend/src/features/missions/MissionForm/mission.json create mode 100644 frontend/src/hooks/useGetPlanThemesAndSubThemesAsOptions.ts diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt index f3bd070af..ec6566f34 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanThemeRepository.kt @@ -2,7 +2,6 @@ package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanThemeModel import org.springframework.data.jpa.repository.JpaRepository -import org.springframework.data.jpa.repository.Query interface IDBControlPlanThemeRepository : JpaRepository { @Query( diff --git a/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts b/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts index 47a214eb5..14c1cac2b 100644 --- a/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts @@ -51,7 +51,7 @@ context('Mission actions', () => { cy.get('*[data-cy="envaction-theme-selector"]').contains('Police des mouillages') cy.get('*[data-cy="envaction-theme-element"]').contains('Mouillage individuel') cy.get('*[data-cy="envaction-theme-element"]').contains('ZMEL') - cy.get('*[data-cy="envaction-protected-species-selector"]').should('not.exist') + cy.get('*[data-cy="envaction-tags-selector"]').should('not.exist') // When cy.get('*[data-cy="envaction-theme-selector"]').click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').contains('Police des espèces protégées').click() @@ -61,11 +61,11 @@ context('Mission actions', () => { cy.get('*[data-cy="envaction-theme-element"]').contains('Atteinte aux habitats').click({ force: true }) cy.get('*[data-cy="envaction-subtheme-selector"]').click({ force: true }) - cy.get('*[data-cy="envaction-protected-species-selector"]').should('exist') - cy.get('*[data-cy="envaction-protected-species-selector"]').click({ force: true }) + cy.get('*[data-cy="envaction-tags-selector"]').should('exist') + cy.get('*[data-cy="envaction-tags-selector"]').click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').contains('Habitat').click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').contains('Oiseaux').click({ force: true }) - cy.get('*[data-cy="envaction-protected-species-selector"]').click({ force: true }) + cy.get('*[data-cy="envaction-tags-selector"]').click({ force: true }) cy.get('*[data-cy="envaction-add-theme"]').should('not.exist') @@ -123,7 +123,7 @@ context('Mission actions', () => { .eq(0) .contains('Police des espèces protégées et de leurs habitats (faune et flore)') cy.get('*[data-cy="envaction-theme-element"]').contains('Destruction, capture, arrachage') - cy.get('*[data-cy="envaction-protected-species-selector"]').should('exist') + cy.get('*[data-cy="envaction-tags-selector"]').should('exist') cy.get('*[data-cy="envaction-theme-element"]').contains('Flore') cy.get('*[data-cy="envaction-theme-element"]').contains('Oiseaux') @@ -138,7 +138,7 @@ context('Mission actions', () => { cy.get('*[data-cy="envaction-subtheme-selector"]').eq(2).click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').eq(2).contains('Jet de déchet').click({ force: true }) - cy.get('*[data-cy="envaction-protected-species-selector"]').should('have.length', 0) + cy.get('*[data-cy="envaction-tags-selector"]').should('have.length', 0) cy.intercept('PUT', `/bff/v1/missions/34`).as('updateMission') cy.clickButton('Enregistrer et quitter') diff --git a/frontend/src/api/controlPlans.ts b/frontend/src/api/controlPlans.ts new file mode 100644 index 000000000..e7edbb8ac --- /dev/null +++ b/frontend/src/api/controlPlans.ts @@ -0,0 +1,13 @@ +import { monitorenvPrivateApi } from './api' + +import type { ControlPlans } from '../domain/entities/controlPlan' + +export const controlPlansAPI = monitorenvPrivateApi.injectEndpoints({ + endpoints: build => ({ + getControlPlans: build.query({ + query: year => `/v1/control_plans/${year}` + }) + }) +}) + +export const { useGetControlPlansQuery } = controlPlansAPI diff --git a/frontend/src/api/missionsAPI.ts b/frontend/src/api/missionsAPI.ts index d59314db6..cd852ed1b 100644 --- a/frontend/src/api/missionsAPI.ts +++ b/frontend/src/api/missionsAPI.ts @@ -4,7 +4,7 @@ import { monitorenvPrivateApi, monitorenvPublicApi } from './api' import { ControlUnit } from '../domain/entities/controlUnit' import { addNewMissionListener, missionEventListener } from '../features/missions/MissionForm/sse' -import type { Mission, MissionForApi } from '../domain/entities/missions' +import type { Mission, MissionData } from '../domain/entities/missions' type MissionsResponse = Mission[] type MissionsFilter = { @@ -30,7 +30,7 @@ const getSeaFrontsFilter = seaFronts => export const missionsAPI = monitorenvPrivateApi.injectEndpoints({ endpoints: builder => ({ - createMission: builder.mutation({ + createMission: builder.mutation({ invalidatesTags: (_, __, { attachedReportingIds = [] }) => [ { id: 'LIST', type: 'Missions' }, { id: 'LIST', type: 'Reportings' }, @@ -88,7 +88,7 @@ export const missionsAPI = monitorenvPrivateApi.injectEndpoints({ .filter(v => v) .join('&') }), - updateMission: builder.mutation({ + updateMission: builder.mutation({ invalidatesTags: (_, __, { attachedReportingIds = [], detachedReportingIds = [], id }) => [ { id, type: 'Missions' }, { id: 'LIST', type: 'Missions' }, diff --git a/frontend/src/domain/entities/controlPlan.ts b/frontend/src/domain/entities/controlPlan.ts new file mode 100644 index 000000000..417df0f82 --- /dev/null +++ b/frontend/src/domain/entities/controlPlan.ts @@ -0,0 +1,22 @@ +export type ControlPlans = { + subThemes: { + id: number + subTheme: string + themeId: number + }[] + tags: { + id: number + tag: string + themeId: number + }[] + themes: { + id: number + theme: string + }[] +} + +export type ControlPlansData = { + subThemeIds: number[] + tagIds: number[] + themeId: number +} diff --git a/frontend/src/domain/entities/missions.ts b/frontend/src/domain/entities/missions.ts index 6837ec6de..49fe4453c 100644 --- a/frontend/src/domain/entities/missions.ts +++ b/frontend/src/domain/entities/missions.ts @@ -1,5 +1,6 @@ import { THEME, customDayjs } from '@mtes-mct/monitor-ui' +import type { ControlPlansData } from './controlPlan' import type { LegacyControlUnit } from './legacyControlUnit' import type { ReportingDetailed } from './reporting' import type { SeaFrontEnum } from './seaFrontType' @@ -158,33 +159,6 @@ export const vesselSizeEnum = { } } -export const protectedSpeciesEnum = { - BIRDS: { - label: 'Oiseaux', - value: 'BIRDS' - }, - FLORA: { - label: 'Flore', - value: 'FLORA' - }, - HABITAT: { - label: 'Habitat', - value: 'HABITAT' - }, - MARINE_MAMMALS: { - label: 'Mammifères marins', - value: 'MARINE_MAMMALS' - }, - OTHER: { - label: 'Autres espèces protégées', - value: 'OTHER' - }, - REPTILES: { - label: 'Reptiles', - value: 'REPTILES' - } -} - export enum MissionStatusEnum { CLOSED = 'CLOSED', ENDED = 'ENDED', @@ -246,8 +220,6 @@ export enum MissionSourceLabel { MONITORFISH = 'CNSP' } -export const THEME_REQUIRE_PROTECTED_SPECIES = ['Police des espèces protégées et de leurs habitats (faune et flore)'] - export const relevantCourtEnum = { JULIS: { code: 'JULIS', @@ -271,6 +243,7 @@ export type ResourceUnit = { administration: string } +// Mission from API export type Mission = { attachedReportingIds: number[] attachedReportings: ReportingDetailed[] @@ -297,10 +270,12 @@ export type Mission, 'controlUnits' | 'facade' | 'id'> & { controlUnits: Array> } +// Mission for API +export type MissionData = Omit>, 'attachedReportings'> -export type MissionForApi = Omit, 'attachedReportings'> export type EnvAction = EnvActionControl | EnvActionSurveillance | EnvActionNote export type NewEnvAction = NewEnvActionControl | EnvActionSurveillance | EnvActionNote +export type EnvActionData = EnvActionControlData | EnvActionSurveillanceData | EnvActionNote export type EnvActionCommonProperties = { actionStartDateTimeUtc?: string | null @@ -317,7 +292,7 @@ export type NewEnvActionControl = EnvActionCommonProperties & { actionNumberOfControls?: number actionTargetType?: string actionType: ActionTypeEnum.CONTROL - geom?: Record[] + controlPlans: ControlPlansData[] infractions: Infraction[] isAdministrativeControl?: boolean isComplianceWithWaterRegulationsControl?: boolean @@ -332,9 +307,29 @@ export type EnvActionControl = NewEnvActionControl & { actionTargetType: string } +export type EnvActionControlData = { + actionEndDateTimeUtc?: string | null + actionNumberOfControls?: number + actionStartDateTimeUtc?: string | null + actionTargetType?: string + actionType: ActionTypeEnum.CONTROL + controlPlans: ControlPlansData[] + geom?: Record[] + id: string + infractions: Infraction[] + isAdministrativeControl?: boolean + isComplianceWithWaterRegulationsControl?: boolean + isSafetyEquipmentAndStandardsComplianceControl?: boolean + isSeafarersControl?: boolean + observations: string | null + reportingIds: number[] + vehicleType?: string +} + export type EnvActionSurveillance = EnvActionCommonProperties & { actionEndDateTimeUtc?: string | null actionType: ActionTypeEnum.SURVEILLANCE + controlPlans: ControlPlansData[] coverMissionZone?: boolean durationMatchesMission?: boolean geom?: Record[] @@ -343,6 +338,19 @@ export type EnvActionSurveillance = EnvActionCommonProperties & { themes: EnvActionTheme[] } +export type EnvActionSurveillanceData = { + actionEndDateTimeUtc?: string | null + actionStartDateTimeUtc?: string | null + actionType: ActionTypeEnum.SURVEILLANCE + controlPlans: ControlPlansData[] + coverMissionZone?: boolean + durationMatchesMission?: boolean + geom?: Record[] + id: string + observations: string | null + reportingIds: number[] +} + export type EnvActionNote = EnvActionCommonProperties & { actionType: ActionTypeEnum.NOTE observations?: string | null diff --git a/frontend/src/features/missions/MissionForm/ActionForm/ControlForm/ControlForm.tsx b/frontend/src/features/missions/MissionForm/ActionForm/ControlForm/ControlForm.tsx index 0cc3e84a4..74a01f641 100644 --- a/frontend/src/features/missions/MissionForm/ActionForm/ControlForm/ControlForm.tsx +++ b/frontend/src/features/missions/MissionForm/ActionForm/ControlForm/ControlForm.tsx @@ -204,6 +204,7 @@ export function ControlForm({ )} (`envActions[${actionIndex}].themes[${themeIndex}].theme`) +type ActionThemeProps = { + actionDate: string + actionIndex: number + labelSubTheme: string + labelTheme: string + themeIndex: number +} +export function ActionTheme({ actionDate, actionIndex, labelSubTheme, labelTheme, themeIndex }: ActionThemeProps) { + const year = customDayjs(actionDate).year() + const [currentThemeField] = useField(`envActions[${actionIndex}].controlPlans[${themeIndex}].themeId`) + + const { isError, isLoading, subThemesAsOptions, tagsAsOptions, themesAsOptions } = + useGetPlanThemesAndSubThemesAsOptions({ + selectedTheme: currentThemeField?.value, + year + }) return ( - + - {THEME_REQUIRE_PROTECTED_SPECIES.includes(currentThemeField.value) && ( - + {tagsAsOptions && tagsAsOptions.length > 0 && ( + )} ) diff --git a/frontend/src/features/missions/MissionForm/ActionForm/Themes/MultipleThemeElement.tsx b/frontend/src/features/missions/MissionForm/ActionForm/Themes/MultipleThemeElement.tsx index 4c3690434..06a5c4678 100644 --- a/frontend/src/features/missions/MissionForm/ActionForm/Themes/MultipleThemeElement.tsx +++ b/frontend/src/features/missions/MissionForm/ActionForm/Themes/MultipleThemeElement.tsx @@ -5,6 +5,8 @@ import styled from 'styled-components' import { ActionTheme } from './ActionTheme' export function MultipleThemeElement({ envActionIndex, form, push, remove }) { + const actionStartDateTimeUtc = + form?.values?.envActions[envActionIndex]?.actionStartDateTimeUtc || new Date().toISOString() const handleRemoveTheme = (index: number) => { remove(index) } @@ -21,6 +23,7 @@ export function MultipleThemeElement({ envActionIndex, form, push, remove }) { {isEmpty(compact(currentThemes)) && ( ( - `envActions[${actionIndex}].themes[${themeIndex}].protectedSpecies` - ) - const { newWindowContainerRef } = useNewWindow() - const { setFieldValue } = useFormikContext() - const options = Object.values(protectedSpeciesEnum)?.sort((a, b) => a.label.localeCompare(b.label)) - - const handleUpdateProtectedSpecies = protectedSpecies => { - updateProtectedSpecies(setFieldValue)(protectedSpecies, actionIndex, themeIndex) - } - - return ( - - ) -} diff --git a/frontend/src/features/missions/MissionForm/ActionForm/Themes/TagsSelector.tsx b/frontend/src/features/missions/MissionForm/ActionForm/Themes/TagsSelector.tsx new file mode 100644 index 000000000..f4c23731b --- /dev/null +++ b/frontend/src/features/missions/MissionForm/ActionForm/Themes/TagsSelector.tsx @@ -0,0 +1,34 @@ +import { MultiSelect, useNewWindow, type Option } from '@mtes-mct/monitor-ui' +import { useField, useFormikContext } from 'formik' + +import { type Mission } from '../../../../../domain/entities/missions' +import { updateTags } from '../../formikUseCases/updateActionThemes' + +type TagsSelectorProps = { + actionIndex: number + tags: Option[] + themeIndex: number +} +export function TagsSelector({ actionIndex, tags, themeIndex }: TagsSelectorProps) { + const [currentTagsField] = useField(`envActions[${actionIndex}].controlPlans[${themeIndex}].tagIds`) + const { newWindowContainerRef } = useNewWindow() + const { setFieldValue } = useFormikContext() + + const handleUpdateTags = nextTags => { + updateTags(setFieldValue)(nextTags, actionIndex, themeIndex) + } + + return ( + value) as any[]} + /> + ) +} diff --git a/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/SubThemesSelector.tsx b/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/SubThemesSelector.tsx index cac538463..b00892f86 100644 --- a/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/SubThemesSelector.tsx +++ b/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/SubThemesSelector.tsx @@ -1,31 +1,33 @@ -import { MultiSelect, useNewWindow } from '@mtes-mct/monitor-ui' +import { MultiSelect, useNewWindow, type Option } from '@mtes-mct/monitor-ui' import { useField, useFormikContext } from 'formik' -import _ from 'lodash' -import { useMemo } from 'react' import styled from 'styled-components' -import { useGetControlThemesQuery } from '../../../../../../api/controlThemesAPI' import { updateSubThemes } from '../../../formikUseCases/updateActionThemes' -import type { ControlTheme } from '../../../../../../domain/entities/controlThemes' import type { Mission } from '../../../../../../domain/entities/missions' -export function SubThemesSelector({ actionIndex, label, theme, themeIndex }) { - const { data: controlThemes, isError, isLoading } = useGetControlThemesQuery() +type SubThemesSelectorProps = { + actionIndex: number + isError: boolean + isLoading: boolean + label: string + subThemes: Option[] + themeId: number + themeIndex: number +} +export function SubThemesSelector({ + actionIndex, + isError, + isLoading, + label, + subThemes, + themeId, + themeIndex +}: SubThemesSelectorProps) { const { newWindowContainerRef } = useNewWindow() const { setFieldValue } = useFormikContext() - const [currentSubThemesField, currentSubThemesProps] = useField( - `envActions[${actionIndex}].themes[${themeIndex}].subThemes` - ) - - const availableThemes = useMemo( - () => - _.chain(controlThemes) - .filter((t): t is ControlTheme & { themeLevel2: string } => t.themeLevel1 === theme && !!t.themeLevel2) - .uniqBy('themeLevel2') - .map(t => ({ label: t.themeLevel2, value: t.themeLevel2 })) - .value(), - [controlThemes, theme] + const [currentSubThemesField, currentSubThemesProps] = useField( + `envActions[${actionIndex}].controlPlans[${themeIndex}].subThemeIds` ) const handleUpdateSubTheme = subTheme => { @@ -39,17 +41,17 @@ export function SubThemesSelector({ actionIndex, label, theme, themeIndex }) { {!isError && !isLoading && ( value) as any[]} /> )} diff --git a/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/index.tsx b/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/index.tsx index bf115eaf7..ad78334fc 100644 --- a/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/index.tsx +++ b/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/index.tsx @@ -1,31 +1,26 @@ -/* eslint-disable react/jsx-props-no-spreading */ -import { Select, useNewWindow } from '@mtes-mct/monitor-ui' +import { Select, useNewWindow, type Option } from '@mtes-mct/monitor-ui' import { useField, useFormikContext } from 'formik' -import _ from 'lodash' -import { useMemo } from 'react' import styled from 'styled-components' -import { useGetControlThemesQuery } from '../../../../../../api/controlThemesAPI' import { updateTheme } from '../../../formikUseCases/updateActionThemes' import type { Mission } from '../../../../../../domain/entities/missions' -export function ThemeSelector({ actionIndex, label, themeIndex }) { - const { data: controlThemes, isError, isLoading } = useGetControlThemesQuery() +type ActionThemeProps = { + actionIndex: number + isError: boolean + isLoading: boolean + label: string + themeIndex: number + themes: Option[] +} +export function ThemeSelector({ actionIndex, isError, isLoading, label, themeIndex, themes }: ActionThemeProps) { const { newWindowContainerRef } = useNewWindow() const [currentThemeField, currentThemeProps] = useField( - `envActions[${actionIndex}].themes[${themeIndex}].theme` + `envActions[${actionIndex}].controlPlans[${themeIndex}].themeId` ) const { setFieldValue, values } = useFormikContext() - const availableThemes = useMemo( - () => - _.chain(controlThemes) - .uniqBy('themeLevel1') - .map(t => ({ label: t.themeLevel1, value: t.themeLevel1 })) - .value(), - [controlThemes] - ) const handleUpdateTheme = theme => { updateTheme(setFieldValue, values)(theme, actionIndex, themeIndex) } @@ -36,7 +31,7 @@ export function ThemeSelector({ actionIndex, label, themeIndex }) { {isLoading && Chargement} {!isError && !isLoading && ( 10} + options={themesAsOptions} + searchable={themesAsOptions.length > 10} value={currentThemeField.value} /> )} diff --git a/frontend/src/features/Reportings/ReportingForm/FormContent.tsx b/frontend/src/features/Reportings/ReportingForm/FormContent.tsx index ae038e35b..41c51c99d 100644 --- a/frontend/src/features/Reportings/ReportingForm/FormContent.tsx +++ b/frontend/src/features/Reportings/ReportingForm/FormContent.tsx @@ -74,7 +74,7 @@ export function FormContent({ ReportingContext.MAP const { dirty, errors, setFieldValue, setValues, values } = useFormikContext>() - const [themeField] = useField('theme') + const [themeField] = useField('themeId') const [isDeleteModalOpen, setIsDeletModalOpen] = useState(false) const [mustIncreaseValidity, setMustIncreaseValidity] = useState(false) @@ -221,11 +221,11 @@ export function FormContent({ {errors.reportType && {errors.reportType}} - + diff --git a/frontend/src/features/Reportings/ReportingForm/formikUseCases/updateReportingThemes.ts b/frontend/src/features/Reportings/ReportingForm/formikUseCases/updateReportingThemes.ts index 0954ae776..c5830e81d 100644 --- a/frontend/src/features/Reportings/ReportingForm/formikUseCases/updateReportingThemes.ts +++ b/frontend/src/features/Reportings/ReportingForm/formikUseCases/updateReportingThemes.ts @@ -1,6 +1,6 @@ export const updateTheme = (setFieldValue: (field: string, value: any) => void) => (value: string) => { - const themesPath = `theme` - const subThemesPath = `subThemes` + const themesPath = `themeId` + const subThemesPath = `subThemeIds` setFieldValue(themesPath, value) setFieldValue(subThemesPath, []) diff --git a/frontend/src/features/Reportings/ReportingsList/Cells/CellActionThemes.tsx b/frontend/src/features/Reportings/ReportingsList/Cells/CellActionThemes.tsx index 2d9f85efe..65dd32e96 100644 --- a/frontend/src/features/Reportings/ReportingsList/Cells/CellActionThemes.tsx +++ b/frontend/src/features/Reportings/ReportingsList/Cells/CellActionThemes.tsx @@ -1,18 +1,23 @@ -/* eslint-disable react/jsx-props-no-spreading */ import { useMemo } from 'react' -export function CellActionThemes({ subThemes, theme }: { subThemes: any[]; theme: string }) { +import { useGetControlPlans } from '../../../../hooks/useGetControlPlans' + +export function CellActionThemes({ subThemeIds, themeId }: { subThemeIds: number[]; themeId: number }) { + const { subThemes, themes } = useGetControlPlans() const cellContent = useMemo(() => { - if (theme) { - if (subThemes.length > 0) { - return `${theme}: ${subThemes.join(', ')}` + if (themeId) { + const themeAsString = themes[themeId]?.theme ?? '' + if (subThemeIds.length > 0) { + const subThemesAsString = subThemeIds.map(subThemeId => subThemes[subThemeId]?.subTheme) + + return `${themeAsString}: ${subThemesAsString.join(', ')}` } - return theme + return themeAsString } return '' - }, [theme, subThemes]) + }, [themeId, subThemeIds, subThemes, themes]) return cellContent !== '' ? ( diff --git a/frontend/src/features/Reportings/ReportingsList/Columns/index.tsx b/frontend/src/features/Reportings/ReportingsList/Columns/index.tsx index 0d6ed0e4d..ddf52a105 100644 --- a/frontend/src/features/Reportings/ReportingsList/Columns/index.tsx +++ b/frontend/src/features/Reportings/ReportingsList/Columns/index.tsx @@ -81,7 +81,7 @@ export const Columns = [ }, { accessorFn: row => row.theme, - cell: ({ row }) => , + cell: ({ row }) => , enableSorting: true, header: () => 'Thématique', id: 'theme', diff --git a/frontend/src/features/Reportings/ReportingsList/index.tsx b/frontend/src/features/Reportings/ReportingsList/index.tsx index a4cdd7a00..631aed386 100644 --- a/frontend/src/features/Reportings/ReportingsList/index.tsx +++ b/frontend/src/features/Reportings/ReportingsList/index.tsx @@ -5,6 +5,7 @@ import { ReportingsTable } from './ReportingsTable' import { ReportingContext } from '../../../domain/shared_slices/Global' import { addReporting } from '../../../domain/use_cases/reporting/addReporting' import { useAppDispatch } from '../../../hooks/useAppDispatch' +import { useGetControlPlans } from '../../../hooks/useGetControlPlans' import { ReportingsFilters } from '../Filters' import { useGetFilteredReportingsQuery } from '../hooks/useGetFilteredReportingsQuery' @@ -12,6 +13,7 @@ export function ReportingsList() { const dispatch = useAppDispatch() const { isError, isFetching, isLoading, reportings } = useGetFilteredReportingsQuery() + const { isLoading: isControlPlansLoading } = useGetControlPlans() const createReporting = () => { dispatch(addReporting(ReportingContext.SIDE_WINDOW)) @@ -25,7 +27,7 @@ export function ReportingsList() { Ajouter un nouveau signalement - + {isControlPlansLoading ?
Chargement
: } {isError ? (

Erreur au chargement des données

diff --git a/frontend/src/features/map/layers/Reportings/reportingsGeometryHelpers.ts b/frontend/src/features/map/layers/Reportings/reportingsGeometryHelpers.ts index 05dde27d9..e14d14f63 100644 --- a/frontend/src/features/map/layers/Reportings/reportingsGeometryHelpers.ts +++ b/frontend/src/features/map/layers/Reportings/reportingsGeometryHelpers.ts @@ -40,8 +40,8 @@ export const getReportingZoneFeature = ( reportType: reporting.reportType, semaphoreId: reporting.semaphoreId, sourceName: reporting.sourceName, - subThemes: reporting.subThemes, - theme: reporting.theme, + subThemeIds: reporting.subThemeIds, + themeId: reporting.themeId, validityTime: reporting.validityTime }) @@ -77,8 +77,8 @@ export const getEditingReportingZoneFeature = (reporting: AtLeast state.global.displayReportingsLayer) @@ -84,8 +86,8 @@ export function ReportingCard({ missionId, reportingId, reportType, - subThemes, - theme, + subThemeIds, + themeId, validityTime } = feature.getProperties() @@ -93,7 +95,7 @@ export function ReportingCard({ const endOfValidity = getLocalizedDayjs(createdAt).add(validityTime || 0, 'hour') const timeLeft = customDayjs(endOfValidity).diff(getLocalizedDayjs(customDayjs().toISOString()), 'hour', true) - const subThemesFormatted = subThemes?.map(subTheme => subTheme).join(', ') + const subThemesFormatted = subThemeIds?.map(subThemeId => subThemes[subThemeId]?.subTheme).join(', ') const timeLeftText = useMemo(() => { if (timeLeft < 0 || isArchived) { @@ -128,7 +130,7 @@ export function ReportingCard({ } }, [feature, updateMargins]) - if (!isCardVisible) { + if (!isCardVisible || isLoading) { return null } @@ -169,8 +171,8 @@ export function ReportingCard({
- {theme && {theme}} - {subThemes?.length > 0 &&  / {subThemesFormatted}} + {themeId && themes[themeId] && {themes[themeId]?.theme}} + {subThemeIds?.length > 0 &&  / {subThemesFormatted}} {description && {description}}
diff --git a/frontend/src/features/missions/MissionForm/ActionCards/ReportingCard.tsx b/frontend/src/features/missions/MissionForm/ActionCards/ReportingCard.tsx index 1308fe11d..ab5a41724 100644 --- a/frontend/src/features/missions/MissionForm/ActionCards/ReportingCard.tsx +++ b/frontend/src/features/missions/MissionForm/ActionCards/ReportingCard.tsx @@ -5,6 +5,7 @@ import styled from 'styled-components' import { Accented, ReportingDate, SummaryContent } from './style' import { ActionTypeEnum, type Mission, type NewMission } from '../../../../domain/entities/missions' import { ControlStatusEnum, type ReportingForTimeline } from '../../../../domain/entities/reporting' +import { useGetControlPlans } from '../../../../hooks/useGetControlPlans' import { getDateAsLocalizedStringCompact } from '../../../../utils/getDateAsLocalizedString' import { StatusActionTag } from '../../../Reportings/components/StatusActionTag' import { getFormattedReportingId } from '../../../Reportings/utils' @@ -17,6 +18,7 @@ export function ReportingCard({ action: ReportingForTimeline setCurrentActionIndex: (string) => void }) { + const { themes } = useGetControlPlans() const { setFieldValue, values } = useFormikContext>() const addAttachedControl = e => { @@ -26,11 +28,12 @@ export function ReportingCard({ actionType: ActionTypeEnum.CONTROL, reportingIds: [Number(action.id)], vehicleType: action.vehicleType, - ...(action.theme && { - themes: [ + ...(action.themeId && { + controlPlans: [ { - subThemes: action.subThemes || [], - theme: action.theme + subThemeIds: action.subThemeIds || [], + tagIds: [], + themeId: action.themeId } ] }) @@ -56,7 +59,13 @@ export function ReportingCard({ {`Signalement ${getFormattedReportingId(action.reportingId)} ${action.displayedSource}`} {getDateAsLocalizedStringCompact(action.createdAt)} - {action.theme} {action.theme && '-'} {action.description || 'Aucune description'} + {action.themeId && ( + <> + {themes[action.themeId]?.theme} + {action.themeId && ' -'}{' '} + + )} + {action.description || 'Aucune description'} {action.attachedEnvActionId && ( diff --git a/frontend/src/features/missions/MissionForm/ActionForm/ReportingForm/index.tsx b/frontend/src/features/missions/MissionForm/ActionForm/ReportingForm/index.tsx index 242691873..b853d9522 100644 --- a/frontend/src/features/missions/MissionForm/ActionForm/ReportingForm/index.tsx +++ b/frontend/src/features/missions/MissionForm/ActionForm/ReportingForm/index.tsx @@ -16,6 +16,7 @@ import { ReportingTargetTypeLabels } from '../../../../../domain/entities/target import { vehicleTypeLabels } from '../../../../../domain/entities/vehicleType' import { useAppDispatch } from '../../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../../hooks/useAppSelector' +import { useGetControlPlans } from '../../../../../hooks/useGetControlPlans' import { getFormattedReportingId } from '../../../../Reportings/utils' import { attachReportingToMissionSliceActions } from '../../../slice' @@ -29,6 +30,7 @@ export function ReportingForm({ setCurrentActionIndex: (string) => void }) { const dispatch = useAppDispatch() + const { subThemes, themes } = useGetControlPlans() const { setFieldValue, values } = useFormikContext>() @@ -43,8 +45,8 @@ export function ReportingForm({ return null } - const subThemes = - reporting.subThemes && reporting.subThemes?.length > 0 ? reporting.subThemes.join(', ') : EMPTY_VALUE + const subThemesAsString = + reporting.subThemeIds?.map(subThemeId => subThemes[subThemeId]?.subTheme).join(', ') || EMPTY_VALUE const sourceTypeText = (() => { if (reporting.sourceType === ReportingSourceEnum.SEMAPHORE) { @@ -142,8 +144,13 @@ export function ReportingForm({ options={reportTypeOptions} value={reporting.reportType} /> - - + + , - themes: Array + subThemes: ControlPlansSubThemeCollection, + themes: ControlPlansThemeCollection ) => { const uniqueThemesAndSubthemes = envActions .filter( @@ -23,13 +23,13 @@ const getAllThemesAndSubThemesAsString = ( .reduce((acc, { controlPlans }) => { if (controlPlans) { controlPlans.forEach(controlPlan => { - const controlPlanTheme = themes.find(theme => theme.id === controlPlan.themeId)?.theme + const controlPlanTheme = controlPlan.themeId ? themes[controlPlan.themeId]?.theme : undefined if (controlPlanTheme && !acc[controlPlanTheme]) { acc[controlPlanTheme] = [] } if (controlPlan.subThemeIds) { controlPlan.subThemeIds.forEach(subThemeId => { - const controlPlanSubTheme = subThemes.find(subTheme => subTheme.id === subThemeId)?.subTheme + const controlPlanSubTheme = subThemes[subThemeId]?.subTheme if (controlPlanTheme && controlPlanSubTheme && !acc[controlPlanTheme].includes(controlPlanSubTheme)) { acc[controlPlanTheme].push(controlPlanSubTheme) } @@ -46,15 +46,8 @@ const getAllThemesAndSubThemesAsString = ( return Object.entries(uniqueThemesAndSubthemes).map(getThemeAndSubThemesString).join(' ; ') } -export function CellActionThemes({ - envActions, - subThemes, - themes -}: { - envActions: EnvAction[] - subThemes: Array - themes: Array -}) { +export function CellActionThemes({ envActions }: { envActions: EnvAction[] }) { + const { subThemes, themes } = useGetControlPlans() const cellContent = useMemo( () => getAllThemesAndSubThemesAsString(envActions, subThemes, themes), [envActions, subThemes, themes] diff --git a/frontend/src/features/missions/MissionsList/Columns/index.tsx b/frontend/src/features/missions/MissionsList/Columns/index.tsx index e2f97209f..ab9d1d1c9 100644 --- a/frontend/src/features/missions/MissionsList/Columns/index.tsx +++ b/frontend/src/features/missions/MissionsList/Columns/index.tsx @@ -8,12 +8,7 @@ import { getMissionTypeCell } from '../getMissionTypeCell' import { getNumberOfControlsCell } from '../getNumberOfControlsCell' import { getResourcesCell } from '../getResourcesCell' -import type { ControlPlansSubTheme, ControlPlansTheme } from '../../../../domain/entities/controlPlan' - -export const Columns = ( - themes?: Array | undefined, - subThemes?: Array | undefined -) => [ +export const Columns = [ { accessorFn: row => row.startDateTimeUtc, cell: info => getDateCell(info.getValue()), @@ -65,7 +60,7 @@ export const Columns = ( }, { accessorFn: row => row.envActions, - cell: info => , + cell: info => , enableSorting: false, header: () => 'Thématiques', id: 'themes', diff --git a/frontend/src/features/missions/MissionsList/Filters/index.tsx b/frontend/src/features/missions/MissionsList/Filters/index.tsx index ae8527b75..50fe2a4d9 100644 --- a/frontend/src/features/missions/MissionsList/Filters/index.tsx +++ b/frontend/src/features/missions/MissionsList/Filters/index.tsx @@ -7,8 +7,7 @@ import { getOptionsFromIdAndName, CheckPicker, getOptionsFromLabelledEnum, - CustomSearch, - type Option + CustomSearch } from '@mtes-mct/monitor-ui' import { type MutableRefObject, useMemo, useRef, useState } from 'react' import styled from 'styled-components' @@ -23,10 +22,11 @@ import { seaFrontLabels } from '../../../../domain/entities/seaFrontType' import { MissionFiltersEnum, resetMissionFilters, updateFilters } from '../../../../domain/shared_slices/MissionFilters' import { useAppDispatch } from '../../../../hooks/useAppDispatch' import { useAppSelector } from '../../../../hooks/useAppSelector' +import { useGetControlPlans } from '../../../../hooks/useGetControlPlans' import { ReactComponent as ReloadSVG } from '../../../../uiMonitor/icons/Reload.svg' import { isNotArchived } from '../../../../utils/isNotArchived' -export function MissionsTableFilters({ themes }: { themes: Array> }) { +export function MissionsTableFilters() { const dispatch = useAppDispatch() const { newWindowContainerRef } = useNewWindow() const { @@ -47,6 +47,7 @@ export function MissionsTableFilters({ themes }: { themes: Array> const { data: administrations } = useGetAdministrationsQuery(undefined, RTK_DEFAULT_QUERY_OPTIONS) const { data: legacyControlUnits, isLoading } = useGetLegacyControlUnitsQuery(undefined, RTK_DEFAULT_QUERY_OPTIONS) + const { themesAsOptions } = useGetControlPlans() const activeAdministrations = useMemo( () => @@ -57,7 +58,7 @@ export function MissionsTableFilters({ themes }: { themes: Array> [administrations] ) - const themeCustomSearch = useMemo(() => new CustomSearch(themes, ['label']), [themes]) + const themeCustomSearch = useMemo(() => new CustomSearch(themesAsOptions, ['label']), [themesAsOptions]) const controlUnitsAsOptions = useMemo(() => { const activeControlUnits = (legacyControlUnits || []).filter(isNotArchived) @@ -281,7 +282,7 @@ export function MissionsTableFilters({ themes }: { themes: Array> menuStyle={{ maxWidth: '200%' }} name="theme" onChange={(value: any) => onUpdateSimpleFilter(value, MissionFiltersEnum.THEME_FILTER)} - options={themes} + options={themesAsOptions} placeholder="Thématique" renderValue={() => selectedThemes && {`Theme (${selectedThemes.length})`}} size="sm" diff --git a/frontend/src/features/missions/MissionsList/MissionsTable.tsx b/frontend/src/features/missions/MissionsList/MissionsTable.tsx index c0813c58b..65d4c9b50 100644 --- a/frontend/src/features/missions/MissionsList/MissionsTable.tsx +++ b/frontend/src/features/missions/MissionsList/MissionsTable.tsx @@ -8,27 +8,16 @@ import { Columns } from './Columns' import { StyledSkeletonRow } from '../../commonComponents/Skeleton' import { ChevronIcon } from '../../commonStyles/icons/ChevronIcon.style' -import type { ControlPlansSubTheme, ControlPlansTheme } from '../../../domain/entities/controlPlan' import type { Mission } from '../../../domain/entities/missions' -export function MissionsTable({ - isLoading, - missions, - subThemes, - themes -}: { - isLoading: boolean - missions: Mission[] - subThemes: Array - themes: Array -}) { +export function MissionsTable({ isLoading, missions }: { isLoading: boolean; missions: Mission[] }) { const [sorting, setSorting] = useState([{ desc: true, id: 'startDate' }]) const tableData = useMemo(() => (isLoading ? Array(5).fill({}) : missions), [isLoading, missions]) const columns = useMemo( - () => (isLoading ? Columns().map(column => ({ ...column, cell: StyledSkeletonRow })) : Columns(themes, subThemes)), - [isLoading, themes, subThemes] + () => (isLoading ? Columns.map(column => ({ ...column, cell: StyledSkeletonRow })) : Columns), + [isLoading] ) const table = useReactTable({ diff --git a/frontend/src/features/missions/MissionsList/index.tsx b/frontend/src/features/missions/MissionsList/index.tsx index b3bad67bb..73d214b83 100644 --- a/frontend/src/features/missions/MissionsList/index.tsx +++ b/frontend/src/features/missions/MissionsList/index.tsx @@ -5,14 +5,12 @@ import { MissionsTableFilters } from './Filters' import { MissionsTable } from './MissionsTable' import { addMission } from '../../../domain/use_cases/missions/addMission' import { useAppDispatch } from '../../../hooks/useAppDispatch' -import { useGetControlPlans } from '../../../hooks/useGetControlPlans' import { useGetFilteredMissionsQuery } from '../../../hooks/useGetFilteredMissionsQuery' export function Missions() { const dispatch = useAppDispatch() const { isError, isFetching, isLoading, missions } = useGetFilteredMissionsQuery() - const { subThemes, themes, themesAsOptions } = useGetControlPlans() const createMission = () => { dispatch(addMission()) @@ -26,7 +24,7 @@ export function Missions() { Ajouter une nouvelle mission - + {missions?.length || '0'} Mission{missions && missions.length > 1 ? 's' : ''} @@ -34,7 +32,7 @@ export function Missions() { {isError ? (

Erreur au chargement des données

) : ( - + )} ) diff --git a/frontend/src/hooks/useGetControlPlans.ts b/frontend/src/hooks/useGetControlPlans.ts index afcea36c7..6d5f6e469 100644 --- a/frontend/src/hooks/useGetControlPlans.ts +++ b/frontend/src/hooks/useGetControlPlans.ts @@ -17,9 +17,9 @@ export function useGetControlPlans() { return { isError, isLoading, - subThemes: Object.values(data?.subThemes || {}) || [], + subThemes: data?.subThemes || {}, subThemesAsOptions, - themes: Object.values(data?.themes || {}) || [], + themes: data?.themes || {}, themesAsOptions } } diff --git a/frontend/src/utils/extractThemesAsText.ts b/frontend/src/utils/extractThemesAsText.ts index b0b9dfd2e..cdef3249a 100644 --- a/frontend/src/utils/extractThemesAsText.ts +++ b/frontend/src/utils/extractThemesAsText.ts @@ -1,16 +1,16 @@ -import type { ControlPlansData, ControlPlansTheme } from '../domain/entities/controlPlan' +import type { ControlPlansData, ControlPlansThemeCollection } from '../domain/entities/controlPlan' -export function extractThemesAsText(controlPlans: ControlPlansData[], themes: Array) { +export function extractThemesAsText(controlPlans: ControlPlansData[], themes: ControlPlansThemeCollection) { if (controlPlans?.length === 0) { return '' } return controlPlans .reduce((controlPlansCollection, currentControlPlan) => { - const actionTheme = themes.find(theme => theme.id === currentControlPlan.themeId) - if (currentControlPlan?.themeId && actionTheme) { - const controlPLanLabel = actionTheme.theme - controlPlansCollection.push(controlPLanLabel || '') + if (currentControlPlan?.themeId) { + const themeLabel = currentControlPlan.themeId ? themes[currentControlPlan.themeId]?.theme : undefined + + controlPlansCollection.push(themeLabel || '') } return controlPlansCollection diff --git a/frontend/src/utils/getThemesAsListOptions.ts b/frontend/src/utils/getThemesAsListOptions.ts deleted file mode 100644 index 0900f03f4..000000000 --- a/frontend/src/utils/getThemesAsListOptions.ts +++ /dev/null @@ -1,12 +0,0 @@ -import _ from 'lodash' - -import type { Option } from '@mtes-mct/monitor-ui' - -export function getThemesAsListOptions(themes): Option[] { - return _.chain(themes) - .map(theme => theme.themeLevel1) - .uniq() - .sort((a, b) => a?.localeCompare(b)) - .map(t => ({ label: t, value: t })) - .value() -} From ff32a8cea957e4769109dd744eb936fafbadac77 Mon Sep 17 00:00:00 2001 From: Claire Dagan Date: Thu, 14 Dec 2023 14:01:27 +0100 Subject: [PATCH 35/53] [Tech] clean variables ans update reportings filters --- .../domain/shared_slices/ReportingsFilters.ts | 4 +- .../Reportings/Filters/Table/FilterTags.tsx | 1 + .../Reportings/Filters/Table/index.tsx | 5 +- .../src/features/Reportings/Filters/index.tsx | 24 +++++++++- .../ThemeSelector/SubThemesSelector.tsx | 4 +- .../FormComponents/ThemeSelector/index.tsx | 6 +-- .../MissionForm/ActionCards/ControlCard.tsx | 4 +- .../ActionCards/SurveillanceCard.tsx | 4 +- .../ActionForm/Themes/ActionTheme.tsx | 17 +++---- frontend/src/hooks/useGetControlPlans.ts | 33 +++++++++---- .../src/hooks/useGetControlPlansByYear.ts | 47 ++++++++++++------- 11 files changed, 100 insertions(+), 49 deletions(-) diff --git a/frontend/src/domain/shared_slices/ReportingsFilters.ts b/frontend/src/domain/shared_slices/ReportingsFilters.ts index 05b35bdcd..3f5277bfd 100644 --- a/frontend/src/domain/shared_slices/ReportingsFilters.ts +++ b/frontend/src/domain/shared_slices/ReportingsFilters.ts @@ -58,13 +58,13 @@ const initialState: ReportingsFiltersSliceType = { } const persistConfig = { - key: 'reportingsFilters', + key: 'reportingFilters', storage } const reportingFiltersSlice = createSlice({ initialState, - name: 'reportingsFilters', + name: 'reportingFilters', reducers: { resetReportingsFilters() { return { ...initialState } diff --git a/frontend/src/features/Reportings/Filters/Table/FilterTags.tsx b/frontend/src/features/Reportings/Filters/Table/FilterTags.tsx index 43abf2203..b3332b797 100644 --- a/frontend/src/features/Reportings/Filters/Table/FilterTags.tsx +++ b/frontend/src/features/Reportings/Filters/Table/FilterTags.tsx @@ -94,4 +94,5 @@ const StyledContainer = styled.div` flex-direction: row; gap: 16px; margin-bottom: 2px; + flex-wrap: wrap; ` diff --git a/frontend/src/features/Reportings/Filters/Table/index.tsx b/frontend/src/features/Reportings/Filters/Table/index.tsx index 307c55edf..a81133da9 100644 --- a/frontend/src/features/Reportings/Filters/Table/index.tsx +++ b/frontend/src/features/Reportings/Filters/Table/index.tsx @@ -31,7 +31,8 @@ export function TableReportingsFiltersWithRef( updateDateRangeFilter, updatePeriodFilter, updateSimpleFilter, - updateSourceTypeFilter + updateSourceTypeFilter, + updateThemeFilter }, ref ) { @@ -170,7 +171,7 @@ export function TableReportingsFiltersWithRef( label="Thématiques" menuStyle={{ maxWidth: '200%' }} name="themes" - onChange={value => updateSimpleFilter(value, ReportingsFiltersEnum.THEME_FILTER)} + onChange={value => updateThemeFilter(value)} options={themesOptions} placeholder="Thématiques" renderValue={() => themeFilter && {`Thème (${themeFilter.length})`}} diff --git a/frontend/src/features/Reportings/Filters/index.tsx b/frontend/src/features/Reportings/Filters/index.tsx index b098d98d2..fe94fac4d 100644 --- a/frontend/src/features/Reportings/Filters/index.tsx +++ b/frontend/src/features/Reportings/Filters/index.tsx @@ -26,12 +26,12 @@ export enum ReportingFilterContext { } export function ReportingsFilters({ context = ReportingFilterContext.TABLE }: { context?: string }) { const dispatch = useAppDispatch() - const { periodFilter, sourceTypeFilter } = useAppSelector(state => state.reportingFilters) + const { periodFilter, sourceTypeFilter, subThemesFilter } = useAppSelector(state => state.reportingFilters) const wrapperRef = useRef() as MutableRefObject const [isCustomPeriodVisible, setIsCustomPeriodVisible] = useState(periodFilter === DateRangeEnum.CUSTOM) const { data: controlUnits } = useGetControlUnitsQuery(undefined, RTK_DEFAULT_QUERY_OPTIONS) - const { subThemesAsOptions, themesAsOptions } = useGetControlPlans() + const { subThemes, subThemesAsOptions, themesAsOptions } = useGetControlPlans() const { data: semaphores } = useGetSemaphoresQuery() const controlUnitsOptions = useMemo(() => (controlUnits ? Array.from(controlUnits) : []), [controlUnits]) @@ -211,6 +211,25 @@ export function ReportingsFilters({ context = ReportingFilterContext.TABLE }: { dispatch(reportingsFiltersActions.updateFilters({ key: ReportingsFiltersEnum.SOURCE_FILTER, value: undefined })) } + const updateThemeFilter = (themesIds: number[] | undefined) => { + dispatch(reportingsFiltersActions.updateFilters({ key: ReportingsFiltersEnum.THEME_FILTER, value: themesIds })) + + if (themesIds) { + const availableSubThemes = Object.values(subThemes) + .filter(subTheme => themesIds.includes(subTheme.themeId)) + .map(subTheme => subTheme.id) + dispatch( + reportingsFiltersActions.updateFilters({ + key: ReportingsFiltersEnum.SUB_THEMES_FILTER, + value: subThemesFilter?.filter(subThemeId => availableSubThemes.includes(subThemeId)) + }) + ) + } else { + dispatch( + reportingsFiltersActions.updateFilters({ key: ReportingsFiltersEnum.SUB_THEMES_FILTER, value: undefined }) + ) + } + } const resetFilters = () => { setIsCustomPeriodVisible(false) dispatch(reportingsFiltersActions.resetReportingsFilters()) @@ -227,6 +246,7 @@ export function ReportingsFilters({ context = ReportingFilterContext.TABLE }: { updatePeriodFilter={updatePeriodFilter} updateSimpleFilter={updateSimpleFilter} updateSourceTypeFilter={updateSourceTypeFilter} + updateThemeFilter={updateThemeFilter} /> ) : ( () const year = customDayjs(values.createdAt || new Date().toISOString()).year() - const { isError, isLoading, subThemesAsOptions } = useGetControlPlansByYear({ + const { isError, isLoading, subThemesByYearAsOptions } = useGetControlPlansByYear({ selectedTheme: theme, year }) @@ -28,7 +28,7 @@ export function SubThemesSelector({ isLight = false, label, name, theme }) { isLight={isLight} label={label} name={name} - options={subThemesAsOptions} + options={subThemesByYearAsOptions} /> )} diff --git a/frontend/src/features/Reportings/ReportingForm/FormComponents/ThemeSelector/index.tsx b/frontend/src/features/Reportings/ReportingForm/FormComponents/ThemeSelector/index.tsx index bda09a7c6..bba9c0180 100644 --- a/frontend/src/features/Reportings/ReportingForm/FormComponents/ThemeSelector/index.tsx +++ b/frontend/src/features/Reportings/ReportingForm/FormComponents/ThemeSelector/index.tsx @@ -13,7 +13,7 @@ export function ThemeSelector({ isInNewWindow = false, isLight = true, label, na const { setFieldValue, values } = useFormikContext() const year = customDayjs(values.createdAt || new Date().toISOString()).year() - const { isError, isLoading, themesAsOptions } = useGetControlPlansByYear({ + const { isError, isLoading, themesByYearAsOptions } = useGetControlPlansByYear({ year }) const handleUpdateTheme = theme => { @@ -34,8 +34,8 @@ export function ThemeSelector({ isInNewWindow = false, isLight = true, label, na label={label} name={name} onChange={handleUpdateTheme} - options={themesAsOptions} - searchable={themesAsOptions.length > 10} + options={themesByYearAsOptions} + searchable={themesByYearAsOptions.length > 10} value={currentThemeField.value} /> )} diff --git a/frontend/src/features/missions/MissionForm/ActionCards/ControlCard.tsx b/frontend/src/features/missions/MissionForm/ActionCards/ControlCard.tsx index 2274ef65d..01fee16ff 100644 --- a/frontend/src/features/missions/MissionForm/ActionCards/ControlCard.tsx +++ b/frontend/src/features/missions/MissionForm/ActionCards/ControlCard.tsx @@ -12,7 +12,7 @@ import type { Mission } from '../../../../domain/entities/missions' export function ControlCard({ action }) { const { values } = useFormikContext() const year = customDayjs(action.actionStartDateTimeUtc || values.startDateTimeUtc || new Date().toISOString()).year() - const { themes } = useGetControlPlansByYear({ + const { themesByYear } = useGetControlPlansByYear({ year }) @@ -23,7 +23,7 @@ export function ControlCard({ action }) { Contrôle{!!action.actionNumberOfControls && action.actionNumberOfControls > 1 ? 's ' : ' '} {action.controlPlans?.length > 0 && action.controlPlans[0]?.themeId ? ( - <Accented>{extractThemesAsText(action.controlPlans, themes)}</Accented> + <Accented>{extractThemesAsText(action.controlPlans, themesByYear)}</Accented> ) : ( 'à renseigner' )} diff --git a/frontend/src/features/missions/MissionForm/ActionCards/SurveillanceCard.tsx b/frontend/src/features/missions/MissionForm/ActionCards/SurveillanceCard.tsx index d59a72ede..5b4bd7b62 100644 --- a/frontend/src/features/missions/MissionForm/ActionCards/SurveillanceCard.tsx +++ b/frontend/src/features/missions/MissionForm/ActionCards/SurveillanceCard.tsx @@ -11,7 +11,7 @@ import type { Mission } from '../../../../domain/entities/missions' export function SurveillanceCard({ action }) { const { values } = useFormikContext<Mission>() const year = customDayjs(action.actionStartDateTimeUtc || values.startDateTimeUtc || new Date().toISOString()).year() - const { themes } = useGetControlPlansByYear({ + const { themesByYear } = useGetControlPlansByYear({ year }) @@ -23,7 +23,7 @@ export function SurveillanceCard({ action }) { <Title> Surveillance{' '} {action.controlPlans && action.controlPlans?.length > 0 ? ( - <Accented>{extractThemesAsText(action.controlPlans, themes)}</Accented> + <Accented>{extractThemesAsText(action.controlPlans, themesByYear)}</Accented> ) : ( 'à renseigner' )} diff --git a/frontend/src/features/missions/MissionForm/ActionForm/Themes/ActionTheme.tsx b/frontend/src/features/missions/MissionForm/ActionForm/Themes/ActionTheme.tsx index 85dc75812..a5c1e117c 100644 --- a/frontend/src/features/missions/MissionForm/ActionForm/Themes/ActionTheme.tsx +++ b/frontend/src/features/missions/MissionForm/ActionForm/Themes/ActionTheme.tsx @@ -22,10 +22,11 @@ export function ActionTheme({ actionIndex, labelSubTheme, labelTheme, themeIndex const year = customDayjs(actionDate).year() const [currentThemeField] = useField<number>(`envActions[${actionIndex}].controlPlans[${themeIndex}].themeId`) - const { isError, isLoading, subThemesAsOptions, tagsAsOptions, themesAsOptions } = useGetControlPlansByYear({ - selectedTheme: currentThemeField?.value, - year - }) + const { isError, isLoading, subThemesByYearAsOptions, tagsByYearAsOptions, themesByYearAsOptions } = + useGetControlPlansByYear({ + selectedTheme: currentThemeField?.value, + year + }) return ( <ActionThemeWrapper data-cy="envaction-theme-element"> @@ -35,19 +36,19 @@ export function ActionTheme({ actionIndex, labelSubTheme, labelTheme, themeIndex isLoading={isLoading} label={labelTheme} themeIndex={themeIndex} - themes={themesAsOptions} + themes={themesByYearAsOptions} /> <SubThemesSelector actionIndex={actionIndex} isError={isError} isLoading={isLoading} label={labelSubTheme} - subThemes={subThemesAsOptions} + subThemes={subThemesByYearAsOptions} themeId={currentThemeField?.value} themeIndex={themeIndex} /> - {tagsAsOptions && tagsAsOptions.length > 0 && ( - <TagsSelector actionIndex={actionIndex} tags={tagsAsOptions} themeIndex={themeIndex} /> + {tagsByYearAsOptions && tagsByYearAsOptions.length > 0 && ( + <TagsSelector actionIndex={actionIndex} tags={tagsByYearAsOptions} themeIndex={themeIndex} /> )} </ActionThemeWrapper> ) diff --git a/frontend/src/hooks/useGetControlPlans.ts b/frontend/src/hooks/useGetControlPlans.ts index 6d5f6e469..7c384c302 100644 --- a/frontend/src/hooks/useGetControlPlans.ts +++ b/frontend/src/hooks/useGetControlPlans.ts @@ -1,25 +1,40 @@ +import { useMemo } from 'react' + +import { useAppSelector } from './useAppSelector' import { useGetControlPlansQuery } from '../api/controlPlans' import type { Option } from '@mtes-mct/monitor-ui' export function useGetControlPlans() { + const themeFilter = useAppSelector(state => state.reportingFilters.themeFilter) const { data, isError, isLoading } = useGetControlPlansQuery() - const themesAsOptions: Array<Option<number>> = - Object.values(data?.themes || {}).map(({ id, theme }) => ({ - label: theme, - value: id - })) || [] + const themesAsOptions: Array<Option<number>> = useMemo( + () => + Object.values(data?.themes || {}).map(({ id, theme }) => ({ + label: theme, + value: id + })) || [], + [data?.themes] + ) + + const subThemesAsOptions: Array<Option<number>> = useMemo( + () => + Object.values(data?.subThemes || {}) + .filter(subTheme => (themeFilter ? themeFilter.includes(subTheme.themeId) : true)) + .map(({ id, subTheme }) => ({ label: subTheme, value: id })) || [], + [data?.subThemes, themeFilter] + ) - const subThemesAsOptions: Array<Option<number>> = - Object.values(data?.subThemes || {}).map(({ id, subTheme }) => ({ label: subTheme, value: id })) || [] + const themes = useMemo(() => data?.themes || {}, [data?.themes]) + const subThemes = useMemo(() => data?.subThemes || {}, [data?.subThemes]) return { isError, isLoading, - subThemes: data?.subThemes || {}, + subThemes, subThemesAsOptions, - themes: data?.themes || {}, + themes, themesAsOptions } } diff --git a/frontend/src/hooks/useGetControlPlansByYear.ts b/frontend/src/hooks/useGetControlPlansByYear.ts index 4feb9e0f3..1a48f1b75 100644 --- a/frontend/src/hooks/useGetControlPlansByYear.ts +++ b/frontend/src/hooks/useGetControlPlansByYear.ts @@ -1,3 +1,5 @@ +import { useMemo } from 'react' + import { useGetControlPlansByYearQuery } from '../api/controlPlans' import type { Option } from '@mtes-mct/monitor-ui' @@ -11,28 +13,39 @@ export function useGetControlPlansByYear({ }) { const { data, isError, isLoading } = useGetControlPlansByYearQuery(year) - const themesAsOptions: Array<Option<number>> = - Object.values(data?.themes || {}).map(({ id, theme }) => ({ - label: theme, - value: id - })) || [] + const themesByYearAsOptions: Array<Option<number>> = useMemo( + () => + Object.values(data?.themes || {}).map(({ id, theme }) => ({ + label: theme, + value: id + })) || [], + [data?.themes] + ) + + const subThemesByYearAsOptions: Array<Option<number>> = useMemo( + () => + Object.values(data?.subThemes || {}) + ?.filter(({ themeId }) => themeId === selectedTheme) + .map(({ id, subTheme }) => ({ label: subTheme, value: id })) || [], + [data?.subThemes, selectedTheme] + ) - const subThemesAsOptions: Array<Option<number>> = - Object.values(data?.subThemes || {}) - ?.filter(({ themeId }) => themeId === selectedTheme) - .map(({ id, subTheme }) => ({ label: subTheme, value: id })) || [] + const tagsByYearAsOptions: Array<Option<number>> = useMemo( + () => + Object.values(data?.tags || {}) + ?.filter(({ themeId }) => themeId === selectedTheme) + .map(({ id, tag }) => ({ label: tag, value: id })) || [], + [data?.tags, selectedTheme] + ) - const tagsAsOptions: Array<Option<number>> = - Object.values(data?.tags || {}) - ?.filter(({ themeId }) => themeId === selectedTheme) - .map(({ id, tag }) => ({ label: tag, value: id })) || [] + const themesByYear = useMemo(() => data?.themes || {}, [data?.themes]) return { isError, isLoading, - subThemesAsOptions, - tagsAsOptions, - themes: Object.values(data?.themes || {}) || [], - themesAsOptions + subThemesByYearAsOptions, + tagsByYearAsOptions, + themesByYear, + themesByYearAsOptions } } From 0d4398e8db73f009dce79672077d953b577245e1 Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Fri, 15 Dec 2023 09:43:30 +0100 Subject: [PATCH 36/53] [Tech] clean after rebase --- .../mission/envAction/EnvActionEntity.kt | 40 +- .../mission/envAction/EnvActionNoteEntity.kt | 14 +- .../envAction/EnvActionNoteProperties.kt | 22 +- .../envAction/EnvActionSurveillanceEntity.kt | 30 +- .../EnvActionSurveillanceProperties.kt | 56 +- .../EnvActionControlEntity.kt | 44 +- .../EnvActionControlProperties.kt | 94 +- .../domain/mappers/EnvActionMapper.kt | 142 +- .../IControlPlanThemeRepository.kt | 1 + .../controlPlan/GetControlPlansByYear.kt | 14 +- .../missions/MissionEnvActionDataInput.kt | 150 +- .../outputs/ControlPlanSubThemeDataOutput.kt | 20 +- .../MissionEnvActionControlDataOutput.kt | 109 +- .../missions/MissionEnvActionDataOutput.kt | 50 +- .../endpoints/bff/ControlPlansController.kt | 30 +- .../endpoints/bff/ControlThemesController.kt | 10 +- .../model/ControlPlanSubThemeModel.kt | 32 +- .../database/model/ControlPlanTagModel.kt | 28 +- .../database/model/EnvActionModel.kt | 267 +-- .../EnvActionsControlPlanSubThemeModel.kt | 46 +- .../model/EnvActionsControlPlanTagModel.kt | 46 +- .../database/model/EnvActionsSubThemeModel.kt | 68 - .../JpaControlPlanSubThemeRepository.kt | 2 +- .../JpaControlPlanTagRepository.kt | 2 +- .../JpaControlPlanThemeRepository.kt | 7 +- .../repositories/JpaMissionRepository.kt | 128 +- .../repositories/JpaReportingRepository.kt | 172 +- .../IDBControlPlanSubThemeRepository.kt | 7 + .../interfaces/IDBControlPlanTagRepository.kt | 6 +- .../controlPlan/GetControlPlansByYearUTest.kt | 84 +- .../bff/ControlPlansControllerITests.kt | 158 +- .../endpoints/bff/MissionsControllerITests.kt | 1490 ++++++++--------- .../JpaControlPlanSubThemeRepositoryITests.kt | 14 +- .../JpaControlPlanTagRepositoryITests.kt | 6 +- .../JpaMissionRepositoryITests.kt | 1478 +++++++--------- 35 files changed, 2231 insertions(+), 2636 deletions(-) delete mode 100644 backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt index 5b6f86efc..13219a9a5 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionEntity.kt @@ -3,32 +3,32 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity +import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.UUID -import org.locationtech.jts.geom.Geometry @JsonTypeInfo( - use = JsonTypeInfo.Id.NAME, - include = JsonTypeInfo.As.PROPERTY, - property = "actionType", - visible = true, + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "actionType", + visible = true, ) @JsonSubTypes( - JsonSubTypes.Type(EnvActionControlEntity::class, name = "CONTROL"), - JsonSubTypes.Type(EnvActionSurveillanceEntity::class, name = "SURVEILLANCE"), - JsonSubTypes.Type(EnvActionNoteEntity::class, name = "NOTE"), + JsonSubTypes.Type(EnvActionControlEntity::class, name = "CONTROL"), + JsonSubTypes.Type(EnvActionSurveillanceEntity::class, name = "SURVEILLANCE"), + JsonSubTypes.Type(EnvActionNoteEntity::class, name = "NOTE"), ) abstract class EnvActionEntity( - open val id: UUID, - open val actionType: ActionTypeEnum, - open val actionEndDateTimeUtc: ZonedDateTime? = null, - open val actionStartDateTimeUtc: ZonedDateTime? = null, - open val controlPlans: List<EnvActionControlPlanEntity>? = listOf(), - open val department: String? = null, - open val facade: String? = null, - open val geom: Geometry? = null, - open val isAdministrativeControl: Boolean? = null, - open val isComplianceWithWaterRegulationsControl: Boolean? = null, - open val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - open val isSeafarersControl: Boolean? = null, + open val id: UUID, + open val actionType: ActionTypeEnum, + open val actionEndDateTimeUtc: ZonedDateTime? = null, + open val actionStartDateTimeUtc: ZonedDateTime? = null, + open val controlPlans: List<EnvActionControlPlanEntity>? = listOf(), + open val department: String? = null, + open val facade: String? = null, + open val geom: Geometry? = null, + open val isAdministrativeControl: Boolean? = null, + open val isComplianceWithWaterRegulationsControl: Boolean? = null, + open val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, + open val isSeafarersControl: Boolean? = null, ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteEntity.kt index f3223c098..ad79ba695 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteEntity.kt @@ -4,11 +4,11 @@ import java.time.ZonedDateTime import java.util.UUID data class EnvActionNoteEntity( - override val id: UUID, - override val actionStartDateTimeUtc: ZonedDateTime? = null, - val observations: String? = null, + override val id: UUID, + override val actionStartDateTimeUtc: ZonedDateTime? = null, + val observations: String? = null, ) : - EnvActionEntity( - actionType = ActionTypeEnum.NOTE, - id = id, - ) + EnvActionEntity( + actionType = ActionTypeEnum.NOTE, + id = id, + ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteProperties.kt index 8077d8d4a..36d6f9cde 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionNoteProperties.kt @@ -4,21 +4,21 @@ import java.time.ZonedDateTime import java.util.* data class EnvActionNoteProperties( - val observations: String? = null, + val observations: String? = null, ) { fun toEnvActionNoteEntity( - id: UUID, - actionStartDateTimeUtc: ZonedDateTime?, + id: UUID, + actionStartDateTimeUtc: ZonedDateTime?, ) = - EnvActionNoteEntity( - id = id, - actionStartDateTimeUtc = actionStartDateTimeUtc, - observations = observations, - ) + EnvActionNoteEntity( + id = id, + actionStartDateTimeUtc = actionStartDateTimeUtc, + observations = observations, + ) companion object { fun fromEnvActionNoteEntity(envAction: EnvActionNoteEntity) = - EnvActionNoteProperties( - envAction.observations, - ) + EnvActionNoteProperties( + envAction.observations, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt index 10c288ec3..64eeded94 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceEntity.kt @@ -1,22 +1,22 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction +import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.UUID -import org.locationtech.jts.geom.Geometry data class EnvActionSurveillanceEntity( - override val id: UUID, - override val actionEndDateTimeUtc: ZonedDateTime? = null, - override val actionStartDateTimeUtc: ZonedDateTime? = null, - override val controlPlans: List<EnvActionControlPlanEntity>? = listOf(), - override val geom: Geometry? = null, - override val facade: String? = null, - override val department: String? = null, - val coverMissionZone: Boolean? = null, - val observations: String? = null, - @Deprecated("Use controlPlan instead") val themes: List<ThemeEntity>? = listOf(), + override val id: UUID, + override val actionEndDateTimeUtc: ZonedDateTime? = null, + override val actionStartDateTimeUtc: ZonedDateTime? = null, + override val controlPlans: List<EnvActionControlPlanEntity>? = listOf(), + override val geom: Geometry? = null, + override val facade: String? = null, + override val department: String? = null, + val coverMissionZone: Boolean? = null, + val observations: String? = null, + @Deprecated("Use controlPlan instead") val themes: List<ThemeEntity>? = listOf(), ) : - EnvActionEntity( - actionType = ActionTypeEnum.SURVEILLANCE, - id = id, - ) + EnvActionEntity( + actionType = ActionTypeEnum.SURVEILLANCE, + id = id, + ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt index a3af9484d..0d1a51d03 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionSurveillanceProperties.kt @@ -1,41 +1,41 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction +import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.* -import org.locationtech.jts.geom.Geometry data class EnvActionSurveillanceProperties( - val coverMissionZone: Boolean? = null, - val observations: String? = null, - @Deprecated("Use controlPlans instead") val themes: List<ThemeEntity>? = listOf(), + val coverMissionZone: Boolean? = null, + val observations: String? = null, + @Deprecated("Use controlPlans instead") val themes: List<ThemeEntity>? = listOf(), ) { fun toEnvActionSurveillanceEntity( - id: UUID, - actionStartDateTimeUtc: ZonedDateTime?, - actionEndDateTimeUtc: ZonedDateTime?, - controlPlans: List<EnvActionControlPlanEntity>?, - department: String?, - facade: String?, - geom: Geometry?, + id: UUID, + actionStartDateTimeUtc: ZonedDateTime?, + actionEndDateTimeUtc: ZonedDateTime?, + controlPlans: List<EnvActionControlPlanEntity>?, + department: String?, + facade: String?, + geom: Geometry?, ) = - EnvActionSurveillanceEntity( - id = id, - actionStartDateTimeUtc = actionStartDateTimeUtc, - actionEndDateTimeUtc = actionEndDateTimeUtc, - controlPlans = controlPlans, - coverMissionZone = coverMissionZone, - department = department, - facade = facade, - geom = geom, - observations = observations, - themes = themes, - ) + EnvActionSurveillanceEntity( + id = id, + actionStartDateTimeUtc = actionStartDateTimeUtc, + actionEndDateTimeUtc = actionEndDateTimeUtc, + controlPlans = controlPlans, + coverMissionZone = coverMissionZone, + department = department, + facade = facade, + geom = geom, + observations = observations, + themes = themes, + ) companion object { fun fromEnvActionSurveillanceEntity(envAction: EnvActionSurveillanceEntity) = - EnvActionSurveillanceProperties( - coverMissionZone = envAction.coverMissionZone, - observations = envAction.observations, - themes = envAction.themes, - ) + EnvActionSurveillanceProperties( + coverMissionZone = envAction.coverMissionZone, + observations = envAction.observations, + themes = envAction.themes, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt index fb52b98c7..15e94287e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlEntity.kt @@ -6,30 +6,30 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionContr import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.InfractionEntity +import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.UUID -import org.locationtech.jts.geom.Geometry data class EnvActionControlEntity( - override val id: UUID, - override val actionEndDateTimeUtc: ZonedDateTime? = null, - override val actionStartDateTimeUtc: ZonedDateTime? = null, - override val controlPlans: List<EnvActionControlPlanEntity>? = listOf(), - override val department: String? = null, - override val facade: String? = null, - override val geom: Geometry? = null, - override val isAdministrativeControl: Boolean? = null, - override val isComplianceWithWaterRegulationsControl: Boolean? = null, - override val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - override val isSeafarersControl: Boolean? = null, - val actionNumberOfControls: Int? = null, - val actionTargetType: ActionTargetTypeEnum? = null, - val infractions: List<InfractionEntity>? = listOf(), - val observations: String? = null, - @Deprecated("Use controlPlan instead") val themes: List<ThemeEntity>? = listOf(), - val vehicleType: VehicleTypeEnum? = null, + override val id: UUID, + override val actionEndDateTimeUtc: ZonedDateTime? = null, + override val actionStartDateTimeUtc: ZonedDateTime? = null, + override val controlPlans: List<EnvActionControlPlanEntity>? = listOf(), + override val department: String? = null, + override val facade: String? = null, + override val geom: Geometry? = null, + override val isAdministrativeControl: Boolean? = null, + override val isComplianceWithWaterRegulationsControl: Boolean? = null, + override val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, + override val isSeafarersControl: Boolean? = null, + val actionNumberOfControls: Int? = null, + val actionTargetType: ActionTargetTypeEnum? = null, + val infractions: List<InfractionEntity>? = listOf(), + val observations: String? = null, + @Deprecated("Use controlPlan instead") val themes: List<ThemeEntity>? = listOf(), + val vehicleType: VehicleTypeEnum? = null, ) : - EnvActionEntity( - id = id, - actionType = ActionTypeEnum.CONTROL, - ) + EnvActionEntity( + id = id, + actionType = ActionTypeEnum.CONTROL, + ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt index aaeb43e46..a2e24cff0 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/envActionControl/EnvActionControlProperties.kt @@ -4,62 +4,62 @@ import fr.gouv.cacem.monitorenv.domain.entities.VehicleTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.InfractionEntity +import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.UUID -import org.locationtech.jts.geom.Geometry data class EnvActionControlProperties( - val actionNumberOfControls: Int? = null, - val actionTargetType: ActionTargetTypeEnum? = null, - val infractions: List<InfractionEntity>? = listOf(), - val observations: String? = null, - @Deprecated("Use controlPlans instead") val themes: List<ThemeEntity>? = listOf(), - val vehicleType: VehicleTypeEnum? = null, + val actionNumberOfControls: Int? = null, + val actionTargetType: ActionTargetTypeEnum? = null, + val infractions: List<InfractionEntity>? = listOf(), + val observations: String? = null, + @Deprecated("Use controlPlans instead") val themes: List<ThemeEntity>? = listOf(), + val vehicleType: VehicleTypeEnum? = null, ) { fun toEnvActionControlEntity( - id: UUID, - actionEndDateTimeUtc: ZonedDateTime?, - actionStartDateTimeUtc: ZonedDateTime?, - controlPlans: List<EnvActionControlPlanEntity>?, - department: String?, - facade: String?, - geom: Geometry?, - isAdministrativeControl: Boolean?, - isComplianceWithWaterRegulationsControl: Boolean?, - isSafetyEquipmentAndStandardsComplianceControl: Boolean?, - isSeafarersControl: Boolean?, + id: UUID, + actionEndDateTimeUtc: ZonedDateTime?, + actionStartDateTimeUtc: ZonedDateTime?, + controlPlans: List<EnvActionControlPlanEntity>?, + department: String?, + facade: String?, + geom: Geometry?, + isAdministrativeControl: Boolean?, + isComplianceWithWaterRegulationsControl: Boolean?, + isSafetyEquipmentAndStandardsComplianceControl: Boolean?, + isSeafarersControl: Boolean?, ) = - EnvActionControlEntity( - id = id, - actionEndDateTimeUtc = actionEndDateTimeUtc, - actionNumberOfControls = actionNumberOfControls, - actionStartDateTimeUtc = actionStartDateTimeUtc, - actionTargetType = actionTargetType, - controlPlans = controlPlans, - department = department, - facade = facade, - geom = geom, - infractions = infractions, - isAdministrativeControl = isAdministrativeControl, - isComplianceWithWaterRegulationsControl = - isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = isSeafarersControl, - observations = observations, - themes = themes, - vehicleType = vehicleType, - ) + EnvActionControlEntity( + id = id, + actionEndDateTimeUtc = actionEndDateTimeUtc, + actionNumberOfControls = actionNumberOfControls, + actionStartDateTimeUtc = actionStartDateTimeUtc, + actionTargetType = actionTargetType, + controlPlans = controlPlans, + department = department, + facade = facade, + geom = geom, + infractions = infractions, + isAdministrativeControl = isAdministrativeControl, + isComplianceWithWaterRegulationsControl = + isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = isSeafarersControl, + observations = observations, + themes = themes, + vehicleType = vehicleType, + ) companion object { fun fromEnvActionControlEntity(envAction: EnvActionControlEntity) = - EnvActionControlProperties( - actionNumberOfControls = envAction.actionNumberOfControls, - actionTargetType = envAction.actionTargetType, - infractions = envAction.infractions, - observations = envAction.observations, - themes = envAction.themes, - vehicleType = envAction.vehicleType, - ) + EnvActionControlProperties( + actionNumberOfControls = envAction.actionNumberOfControls, + actionTargetType = envAction.actionTargetType, + infractions = envAction.infractions, + observations = envAction.observations, + themes = envAction.themes, + vehicleType = envAction.vehicleType, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt index 314c618d6..67493d44e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/mappers/EnvActionMapper.kt @@ -11,77 +11,77 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionSurve import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlProperties import fr.gouv.cacem.monitorenv.domain.exceptions.EntityConversionException -import java.time.ZonedDateTime -import java.util.UUID import org.locationtech.jts.geom.Geometry import org.springframework.stereotype.Component +import java.time.ZonedDateTime +import java.util.UUID @Component object EnvActionMapper { private const val jsonbNullString = "null" fun getEnvActionEntityFromJSON( - mapper: ObjectMapper, - id: UUID, - actionEndDateTimeUtc: ZonedDateTime?, - actionType: ActionTypeEnum, - actionStartDateTimeUtc: ZonedDateTime?, - controlPlans: List<EnvActionControlPlanEntity>?, - department: String?, - facade: String?, - geom: Geometry?, - isAdministrativeControl: Boolean?, - isComplianceWithWaterRegulationsControl: Boolean?, - isSafetyEquipmentAndStandardsComplianceControl: Boolean?, - isSeafarersControl: Boolean?, - value: String?, + mapper: ObjectMapper, + id: UUID, + actionEndDateTimeUtc: ZonedDateTime?, + actionType: ActionTypeEnum, + actionStartDateTimeUtc: ZonedDateTime?, + controlPlans: List<EnvActionControlPlanEntity>?, + department: String?, + facade: String?, + geom: Geometry?, + isAdministrativeControl: Boolean?, + isComplianceWithWaterRegulationsControl: Boolean?, + isSafetyEquipmentAndStandardsComplianceControl: Boolean?, + isSeafarersControl: Boolean?, + value: String?, ): EnvActionEntity { return try { if (!value.isNullOrEmpty() && value != jsonbNullString) { when (actionType) { ActionTypeEnum.SURVEILLANCE -> - mapper.readValue( - value, - EnvActionSurveillanceProperties::class.java, - ) - .toEnvActionSurveillanceEntity( - id = id, - actionEndDateTimeUtc = actionEndDateTimeUtc, - actionStartDateTimeUtc = actionStartDateTimeUtc, - controlPlans = controlPlans, - department = department, - facade = facade, - geom = geom, - ) + mapper.readValue( + value, + EnvActionSurveillanceProperties::class.java, + ) + .toEnvActionSurveillanceEntity( + id = id, + actionEndDateTimeUtc = actionEndDateTimeUtc, + actionStartDateTimeUtc = actionStartDateTimeUtc, + controlPlans = controlPlans, + department = department, + facade = facade, + geom = geom, + ) ActionTypeEnum.CONTROL -> - mapper.readValue( - value, - EnvActionControlProperties::class.java, - ) - .toEnvActionControlEntity( - id = id, - actionEndDateTimeUtc = actionEndDateTimeUtc, - actionStartDateTimeUtc = actionStartDateTimeUtc, - controlPlans = controlPlans, - department = department, - facade = facade, - geom = geom, - isAdministrativeControl = isAdministrativeControl, - isComplianceWithWaterRegulationsControl = - isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = isSeafarersControl, - ) + mapper.readValue( + value, + EnvActionControlProperties::class.java, + ) + .toEnvActionControlEntity( + id = id, + actionEndDateTimeUtc = actionEndDateTimeUtc, + actionStartDateTimeUtc = actionStartDateTimeUtc, + controlPlans = controlPlans, + department = department, + facade = facade, + geom = geom, + isAdministrativeControl = isAdministrativeControl, + isComplianceWithWaterRegulationsControl = + isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = isSeafarersControl, + ) ActionTypeEnum.NOTE -> - mapper.readValue( - value, - EnvActionNoteProperties::class.java, - ) - .toEnvActionNoteEntity( - id = id, - actionStartDateTimeUtc = actionStartDateTimeUtc, - ) + mapper.readValue( + value, + EnvActionNoteProperties::class.java, + ) + .toEnvActionNoteEntity( + id = id, + actionStartDateTimeUtc = actionStartDateTimeUtc, + ) } } else { throw EntityConversionException("No action value found.") @@ -95,23 +95,23 @@ object EnvActionMapper { return try { when (envAction.actionType) { ActionTypeEnum.SURVEILLANCE -> - mapper.writeValueAsString( - EnvActionSurveillanceProperties.fromEnvActionSurveillanceEntity( - envAction as EnvActionSurveillanceEntity, - ), - ) + mapper.writeValueAsString( + EnvActionSurveillanceProperties.fromEnvActionSurveillanceEntity( + envAction as EnvActionSurveillanceEntity, + ), + ) ActionTypeEnum.CONTROL -> - mapper.writeValueAsString( - EnvActionControlProperties.fromEnvActionControlEntity( - envAction as EnvActionControlEntity, - ), - ) + mapper.writeValueAsString( + EnvActionControlProperties.fromEnvActionControlEntity( + envAction as EnvActionControlEntity, + ), + ) ActionTypeEnum.NOTE -> - mapper.writeValueAsString( - EnvActionNoteProperties.fromEnvActionNoteEntity( - envAction as EnvActionNoteEntity, - ), - ) + mapper.writeValueAsString( + EnvActionNoteProperties.fromEnvActionNoteEntity( + envAction as EnvActionNoteEntity, + ), + ) } } catch (e: Exception) { throw EntityConversionException("Error while converting action to json $envAction", e) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt index 4724bc020..413466018 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/repositories/IControlPlanThemeRepository.kt @@ -3,5 +3,6 @@ package fr.gouv.cacem.monitorenv.domain.repositories import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanThemeEntity interface IControlPlanThemeRepository { + fun findAll(): List<ControlPlanThemeEntity> fun findByYear(year: Int): List<ControlPlanThemeEntity> } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt index 192fc7e06..9881f6668 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYear.kt @@ -11,9 +11,9 @@ import org.slf4j.LoggerFactory @UseCase class GetControlPlansByYear( - private val controlPlanThemeRepository: IControlPlanThemeRepository, - private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository, - private val controlPlanTagRepository: IControlPlanTagRepository, + private val controlPlanThemeRepository: IControlPlanThemeRepository, + private val controlPlanSubThemeRepository: IControlPlanSubThemeRepository, + private val controlPlanTagRepository: IControlPlanTagRepository, ) { private val logger = LoggerFactory.getLogger(GetControlPlansByYear::class.java) fun execute(year: Int): ControlPlanByYear { @@ -26,8 +26,8 @@ class GetControlPlansByYear( } typealias ControlPlanByYear = - Triple< - List<ControlPlanThemeEntity>, - List<ControlPlanSubThemeEntity>, - List<ControlPlanTagEntity>, + Triple< + List<ControlPlanThemeEntity>, + List<ControlPlanSubThemeEntity>, + List<ControlPlanTagEntity>, > diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt index 7cae0a424..80d0ce145 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionDataInput.kt @@ -8,57 +8,57 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionSurve import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.ActionTargetTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity +import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.Optional import java.util.UUID -import org.locationtech.jts.geom.Geometry data class MissionEnvActionDataInput( - val id: UUID, - val actionType: ActionTypeEnum, - val actionStartDateTimeUtc: ZonedDateTime? = null, + val id: UUID, + val actionType: ActionTypeEnum, + val actionStartDateTimeUtc: ZonedDateTime? = null, - // Common to all action Types - val observations: String? = null, + // Common to all action Types + val observations: String? = null, - // EnvActionControl + EnvSurveillance Properties - val actionEndDateTimeUtc: ZonedDateTime? = null, - val controlPlans: List<MissionEnvActionControlPlanDataInput>? = null, - @Deprecated("Use controlPlans instead") val themes: List<ThemeEntity>? = null, - val department: String? = null, - val facade: String? = null, - val geom: Geometry? = null, + // EnvActionControl + EnvSurveillance Properties + val actionEndDateTimeUtc: ZonedDateTime? = null, + val controlPlans: List<MissionEnvActionControlPlanDataInput>? = null, + @Deprecated("Use controlPlans instead") val themes: List<ThemeEntity>? = null, + val department: String? = null, + val facade: String? = null, + val geom: Geometry? = null, - // EnvActionControl Properties - val actionNumberOfControls: Int? = null, - val actionTargetType: ActionTargetTypeEnum? = null, - val vehicleType: VehicleTypeEnum? = null, - val infractions: List<MissionEnvActionControlInfractionDataInput>? = listOf(), - val isAdministrativeControl: Boolean? = null, - val isComplianceWithWaterRegulationsControl: Boolean? = null, - val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - val isSeafarersControl: Boolean? = null, + // EnvActionControl Properties + val actionNumberOfControls: Int? = null, + val actionTargetType: ActionTargetTypeEnum? = null, + val vehicleType: VehicleTypeEnum? = null, + val infractions: List<MissionEnvActionControlInfractionDataInput>? = listOf(), + val isAdministrativeControl: Boolean? = null, + val isComplianceWithWaterRegulationsControl: Boolean? = null, + val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, + val isSeafarersControl: Boolean? = null, - // EnvActionSurveillance Properties - val coverMissionZone: Boolean? = null, + // EnvActionSurveillance Properties + val coverMissionZone: Boolean? = null, - // complementary properties - val reportingIds: Optional<List<Int>>, + // complementary properties + val reportingIds: Optional<List<Int>>, ) { fun validate() { when (actionType) { ActionTypeEnum.CONTROL -> - require(this.reportingIds.isPresent && this.reportingIds.get().size < 2) { - "ReportingIds must not be null and maximum 1 id for Controls" - } + require(this.reportingIds.isPresent && this.reportingIds.get().size < 2) { + "ReportingIds must not be null and maximum 1 id for Controls" + } ActionTypeEnum.SURVEILLANCE -> - require(this.reportingIds.isPresent) { - "ReportingIds must not be null for Surveillance Action" - } + require(this.reportingIds.isPresent) { + "ReportingIds must not be null for Surveillance Action" + } ActionTypeEnum.NOTE -> - require( - !this.reportingIds.isPresent, - ) { "ReportingIds must not be present for Notes" } + require( + !this.reportingIds.isPresent, + ) { "ReportingIds must not be present for Notes" } } } @@ -67,48 +67,48 @@ data class MissionEnvActionDataInput( when (this.actionType) { ActionTypeEnum.CONTROL -> - return EnvActionControlEntity( - id = this.id, - actionEndDateTimeUtc = this.actionEndDateTimeUtc, - actionNumberOfControls = this.actionNumberOfControls, - actionTargetType = this.actionTargetType, - actionStartDateTimeUtc = this.actionStartDateTimeUtc, - controlPlans = - this.controlPlans?.map { it.toEnvActionControlPlanEntity() }, - department = this.department, - facade = this.facade, - geom = this.geom, - infractions = this.infractions?.map { it.toInfractionEntity() }, - isAdministrativeControl = this.isAdministrativeControl, - isComplianceWithWaterRegulationsControl = - this.isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - this.isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = this.isSeafarersControl, - observations = this.observations, - themes = this.themes, - vehicleType = this.vehicleType, - ) + return EnvActionControlEntity( + id = this.id, + actionEndDateTimeUtc = this.actionEndDateTimeUtc, + actionNumberOfControls = this.actionNumberOfControls, + actionTargetType = this.actionTargetType, + actionStartDateTimeUtc = this.actionStartDateTimeUtc, + controlPlans = + this.controlPlans?.map { it.toEnvActionControlPlanEntity() }, + department = this.department, + facade = this.facade, + geom = this.geom, + infractions = this.infractions?.map { it.toInfractionEntity() }, + isAdministrativeControl = this.isAdministrativeControl, + isComplianceWithWaterRegulationsControl = + this.isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + this.isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = this.isSeafarersControl, + observations = this.observations, + themes = this.themes, + vehicleType = this.vehicleType, + ) ActionTypeEnum.SURVEILLANCE -> - return EnvActionSurveillanceEntity( - id = this.id, - actionStartDateTimeUtc = this.actionStartDateTimeUtc, - actionEndDateTimeUtc = this.actionEndDateTimeUtc, - controlPlans = - this.controlPlans?.map { it.toEnvActionControlPlanEntity() }, - department = this.department, - facade = this.facade, - geom = this.geom, - themes = this.themes, - coverMissionZone = this.coverMissionZone, - observations = this.observations, - ) + return EnvActionSurveillanceEntity( + id = this.id, + actionStartDateTimeUtc = this.actionStartDateTimeUtc, + actionEndDateTimeUtc = this.actionEndDateTimeUtc, + controlPlans = + this.controlPlans?.map { it.toEnvActionControlPlanEntity() }, + department = this.department, + facade = this.facade, + geom = this.geom, + themes = this.themes, + coverMissionZone = this.coverMissionZone, + observations = this.observations, + ) ActionTypeEnum.NOTE -> - return EnvActionNoteEntity( - id = this.id, - actionStartDateTimeUtc = this.actionStartDateTimeUtc, - observations = this.observations, - ) + return EnvActionNoteEntity( + id = this.id, + actionStartDateTimeUtc = this.actionStartDateTimeUtc, + observations = this.observations, + ) else -> throw Exception("Action type not supported") } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt index f032df8ab..2c5ce4f14 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/ControlPlanSubThemeDataOutput.kt @@ -3,18 +3,18 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs import fr.gouv.cacem.monitorenv.domain.entities.controlPlan.ControlPlanSubThemeEntity data class ControlPlanSubThemeDataOutput( - val id: Int, - val themeId: Int, - val subTheme: String, - val year: Int, + val id: Int, + val themeId: Int, + val subTheme: String, + val year: Int, ) { companion object { fun fromControlPlanSubThemeEntity(controlPlanSubTheme: ControlPlanSubThemeEntity) = - ControlPlanSubThemeDataOutput( - id = controlPlanSubTheme.id, - themeId = controlPlanSubTheme.themeId, - subTheme = controlPlanSubTheme.subTheme, - year = controlPlanSubTheme.year, - ) + ControlPlanSubThemeDataOutput( + id = controlPlanSubTheme.id, + themeId = controlPlanSubTheme.themeId, + subTheme = controlPlanSubTheme.subTheme, + year = controlPlanSubTheme.year, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt index 9615de67e..142dab4b4 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlDataOutput.kt @@ -6,68 +6,67 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ThemeEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.ActionTargetTypeEnum import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.InfractionEntity +import org.locationtech.jts.geom.Geometry import java.time.ZonedDateTime import java.util.UUID -import org.locationtech.jts.geom.Geometry data class MissionEnvActionControlDataOutput( - override val id: UUID, - val actionEndDateTimeUtc: ZonedDateTime? = null, - val actionNumberOfControls: Int? = null, - override val actionStartDateTimeUtc: ZonedDateTime? = null, - val actionTargetType: ActionTargetTypeEnum? = null, - override val actionType: ActionTypeEnum = ActionTypeEnum.CONTROL, - val controlPlans: List<MissionEnvActionControlPlanDataOutput>? = listOf(), - val department: String? = null, - val facade: String? = null, - val geom: Geometry? = null, - val infractions: List<InfractionEntity>? = listOf(), - val isAdministrativeControl: Boolean? = null, - val isComplianceWithWaterRegulationsControl: Boolean? = null, - val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - val isSeafarersControl: Boolean? = null, - val observations: String? = null, - val reportingIds: List<Int>, - @Deprecated("Use controlPlans instead") val themes: List<ThemeEntity>? = listOf(), - val controlPlanSubThemes: List<MissionEnvActionSubThemeDataOutput>? = listOf(), - val vehicleType: VehicleTypeEnum? = null, + override val id: UUID, + val actionEndDateTimeUtc: ZonedDateTime? = null, + val actionNumberOfControls: Int? = null, + override val actionStartDateTimeUtc: ZonedDateTime? = null, + val actionTargetType: ActionTargetTypeEnum? = null, + override val actionType: ActionTypeEnum = ActionTypeEnum.CONTROL, + val controlPlans: List<MissionEnvActionControlPlanDataOutput>? = listOf(), + val department: String? = null, + val facade: String? = null, + val geom: Geometry? = null, + val infractions: List<InfractionEntity>? = listOf(), + val isAdministrativeControl: Boolean? = null, + val isComplianceWithWaterRegulationsControl: Boolean? = null, + val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, + val isSeafarersControl: Boolean? = null, + val observations: String? = null, + val reportingIds: List<Int>, + @Deprecated("Use controlPlans instead") val themes: List<ThemeEntity>? = listOf(), + val vehicleType: VehicleTypeEnum? = null, ) : - MissionEnvActionDataOutput( - id = id, - actionStartDateTimeUtc = actionStartDateTimeUtc, - actionType = ActionTypeEnum.CONTROL, - ) { + MissionEnvActionDataOutput( + id = id, + actionStartDateTimeUtc = actionStartDateTimeUtc, + actionType = ActionTypeEnum.CONTROL, + ) { companion object { fun fromEnvActionControlEntity( - envActionControlEntity: EnvActionControlEntity, - reportingIds: List<Int>, + envActionControlEntity: EnvActionControlEntity, + reportingIds: List<Int>, ) = - MissionEnvActionControlDataOutput( - id = envActionControlEntity.id, - actionNumberOfControls = envActionControlEntity.actionNumberOfControls, - actionStartDateTimeUtc = envActionControlEntity.actionStartDateTimeUtc, - actionEndDateTimeUtc = envActionControlEntity.actionEndDateTimeUtc, - actionTargetType = envActionControlEntity.actionTargetType, - controlPlans = - envActionControlEntity.controlPlans?.map { - MissionEnvActionControlPlanDataOutput - .fromEnvActionControlPlanEntity(it) - }, - department = envActionControlEntity.department, - facade = envActionControlEntity.facade, - geom = envActionControlEntity.geom, - infractions = envActionControlEntity.infractions, - isAdministrativeControl = envActionControlEntity.isAdministrativeControl, - isComplianceWithWaterRegulationsControl = - envActionControlEntity.isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - envActionControlEntity - .isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = envActionControlEntity.isSeafarersControl, - observations = envActionControlEntity.observations, - themes = envActionControlEntity.themes, - vehicleType = envActionControlEntity.vehicleType, - reportingIds = reportingIds, - ) + MissionEnvActionControlDataOutput( + id = envActionControlEntity.id, + actionNumberOfControls = envActionControlEntity.actionNumberOfControls, + actionStartDateTimeUtc = envActionControlEntity.actionStartDateTimeUtc, + actionEndDateTimeUtc = envActionControlEntity.actionEndDateTimeUtc, + actionTargetType = envActionControlEntity.actionTargetType, + controlPlans = + envActionControlEntity.controlPlans?.map { + MissionEnvActionControlPlanDataOutput + .fromEnvActionControlPlanEntity(it) + }, + department = envActionControlEntity.department, + facade = envActionControlEntity.facade, + geom = envActionControlEntity.geom, + infractions = envActionControlEntity.infractions, + isAdministrativeControl = envActionControlEntity.isAdministrativeControl, + isComplianceWithWaterRegulationsControl = + envActionControlEntity.isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + envActionControlEntity + .isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = envActionControlEntity.isSeafarersControl, + observations = envActionControlEntity.observations, + themes = envActionControlEntity.themes, + vehicleType = envActionControlEntity.vehicleType, + reportingIds = reportingIds, + ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt index c2b0c3979..2072a27e0 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionDataOutput.kt @@ -10,39 +10,39 @@ import java.time.ZonedDateTime import java.util.UUID abstract class MissionEnvActionDataOutput( - open val id: UUID, - open val actionStartDateTimeUtc: ZonedDateTime? = null, - open val actionType: ActionTypeEnum, + open val id: UUID, + open val actionStartDateTimeUtc: ZonedDateTime? = null, + open val actionType: ActionTypeEnum, ) { companion object { fun fromEnvActionEntity( - envActionEntity: EnvActionEntity, - envActionsAttachedToReportingIds: List<EnvActionAttachedToReportingIds>?, + envActionEntity: EnvActionEntity, + envActionsAttachedToReportingIds: List<EnvActionAttachedToReportingIds>?, ): MissionEnvActionDataOutput { return when (envActionEntity.actionType) { ActionTypeEnum.CONTROL -> - MissionEnvActionControlDataOutput.fromEnvActionControlEntity( - envActionControlEntity = envActionEntity as EnvActionControlEntity, - reportingIds = - envActionsAttachedToReportingIds - ?.find { id -> id.first == envActionEntity.id } - ?.second - ?: listOf(), - ) + MissionEnvActionControlDataOutput.fromEnvActionControlEntity( + envActionControlEntity = envActionEntity as EnvActionControlEntity, + reportingIds = + envActionsAttachedToReportingIds + ?.find { id -> id.first == envActionEntity.id } + ?.second + ?: listOf(), + ) ActionTypeEnum.SURVEILLANCE -> - MissionEnvActionSurveillanceDataOutput.fromEnvActionSurveillanceEntity( - envActionSurveillanceEntity = - envActionEntity as EnvActionSurveillanceEntity, - reportingIds = - envActionsAttachedToReportingIds - ?.find { id -> id.first == envActionEntity.id } - ?.second - ?: listOf(), - ) + MissionEnvActionSurveillanceDataOutput.fromEnvActionSurveillanceEntity( + envActionSurveillanceEntity = + envActionEntity as EnvActionSurveillanceEntity, + reportingIds = + envActionsAttachedToReportingIds + ?.find { id -> id.first == envActionEntity.id } + ?.second + ?: listOf(), + ) ActionTypeEnum.NOTE -> - MissionEnvActionNoteDataOutput.fromEnvActionNoteEntity( - envActionEntity as EnvActionNoteEntity, - ) + MissionEnvActionNoteDataOutput.fromEnvActionNoteEntity( + envActionEntity as EnvActionNoteEntity, + ) } } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt index 6ee352e48..a8b487b5c 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansController.kt @@ -14,12 +14,12 @@ import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/bff/v1/control_plans") @Tag( - name = "Control Plan Themes, SubThemes and tags", - description = "API des sous thématiques des plan de contrôle", + name = "Control Plan Themes, SubThemes and tags", + description = "API des sous thématiques des plan de contrôle", ) class ControlPlansController( - private val getControlPlans: GetControlPlans, - private val getControlPlansByYear: GetControlPlansByYear, + private val getControlPlans: GetControlPlans, + private val getControlPlansByYear: GetControlPlansByYear, ) { @GetMapping("") @@ -27,27 +27,27 @@ class ControlPlansController( fun getAll(): ControlPlanDataOutput { val controlPlan = getControlPlans.execute() return ControlPlanDataOutput.fromControlPlanEntities( - themes = controlPlan.first, - subThemes = controlPlan.second, - tags = controlPlan.third, + themes = controlPlan.first, + subThemes = controlPlan.second, + tags = controlPlan.third, ) } @GetMapping("/{year}") @Operation( - summary = - "Get control plan themes, subthemes and tags and allowed tags for a given year", + summary = + "Get control plan themes, subthemes and tags and allowed tags for a given year", ) fun getControlPlansByYear( - @PathParam("validity year of the control plan themes") - @PathVariable(name = "year") - year: Int, + @PathParam("validity year of the control plan themes") + @PathVariable(name = "year") + year: Int, ): ControlPlanDataOutput { val controlPlan = getControlPlansByYear.execute(year) return ControlPlanDataOutput.fromControlPlanEntities( - themes = controlPlan.first, - subThemes = controlPlan.second, - tags = controlPlan.third, + themes = controlPlan.first, + subThemes = controlPlan.second, + tags = controlPlan.third, ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt index 65d3a0438..fe39e6cb8 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlThemesController.kt @@ -16,8 +16,8 @@ import org.springframework.web.bind.annotation.RestController @RequestMapping("/bff/v1/controlthemes") @Tag(name = "BFF.Control Themes", description = "API control themes") class ControlThemesController( - private val getAllControlThemes: GetAllControlThemes, - private val getControlThemeById: GetControlThemeById, + private val getAllControlThemes: GetAllControlThemes, + private val getControlThemeById: GetControlThemeById, ) { @GetMapping("") @@ -30,9 +30,9 @@ class ControlThemesController( @GetMapping("/{controlThemeId}") @Operation(summary = "Get regulatory area by Id") fun getControlThemeByIdController( - @PathParam("controlTheme id") - @PathVariable(name = "controlThemeId") - controlThemeId: Int, + @PathParam("controlTheme id") + @PathVariable(name = "controlThemeId") + controlThemeId: Int, ): ControlThemeDataOutput { val controlTheme = getControlThemeById.execute(controlThemeId = controlThemeId) return ControlThemeDataOutput.fromControlThemeEntity(controlTheme) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt index 5ebc5c52a..a5b8c5a01 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanSubThemeModel.kt @@ -17,26 +17,26 @@ import org.hibernate.annotations.CacheConcurrencyStrategy @Entity @Table(name = "control_plan_sub_themes") @Cache( - usage = CacheConcurrencyStrategy.READ_WRITE, + usage = CacheConcurrencyStrategy.READ_WRITE, ) class ControlPlanSubThemeModel( - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id", nullable = false, updatable = false) - val id: Int, - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "theme_id") - val ControlPlanTheme: ControlPlanThemeModel, - @Column(name = "subtheme") val subTheme: String, - @Column(name = "year") val year: Int, + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false, updatable = false) + val id: Int, + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "theme_id") + val controlPlanTheme: ControlPlanThemeModel, + @Column(name = "subtheme") val subTheme: String, + @Column(name = "year") val year: Int, ) { fun toControlPlanSubThemeEntity() = - ControlPlanSubThemeEntity( - id = id, - themeId = controlPlanTheme.id, - subTheme = subTheme, - year = year, - ) + ControlPlanSubThemeEntity( + id = id, + themeId = controlPlanTheme.id, + subTheme = subTheme, + year = year, + ) override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt index 2aaf24d1b..1de80039f 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/ControlPlanTagModel.kt @@ -17,24 +17,24 @@ import org.hibernate.annotations.CacheConcurrencyStrategy @Entity @Table(name = "control_plan_tags") @Cache( - usage = CacheConcurrencyStrategy.READ_WRITE, + usage = CacheConcurrencyStrategy.READ_WRITE, ) class ControlPlanTagModel( - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id", nullable = false, updatable = false) - val id: Int, - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "theme_id") - val controlPlanTheme: ControlPlanThemeModel, - @Column(name = "tag") val tag: String, + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false, updatable = false) + val id: Int, + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "theme_id") + val controlPlanTheme: ControlPlanThemeModel, + @Column(name = "tag") val tag: String, ) { fun toControlPlanTagEntity() = - ControlPlanTagEntity( - id = this.id, - tag = this.tag, - themeId = this.controlPlanTheme.id, - ) + ControlPlanTagEntity( + id = this.id, + tag = this.tag, + themeId = this.controlPlanTheme.id, + ) override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt index 4b053a910..061b14b46 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt @@ -23,9 +23,6 @@ import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne import jakarta.persistence.OneToMany import jakarta.persistence.Table -import java.time.Instant -import java.time.ZoneOffset.UTC -import java.util.UUID import org.hibernate.Hibernate import org.hibernate.annotations.JdbcType import org.hibernate.annotations.Type @@ -33,162 +30,168 @@ import org.hibernate.type.descriptor.jdbc.UUIDJdbcType import org.locationtech.jts.geom.Geometry import org.n52.jackson.datatype.jts.GeometryDeserializer import org.n52.jackson.datatype.jts.GeometrySerializer +import java.time.Instant +import java.time.ZoneOffset.UTC +import java.util.UUID @JsonIdentityInfo( - generator = ObjectIdGenerators.PropertyGenerator::class, - property = "id", + generator = ObjectIdGenerators.PropertyGenerator::class, + property = "id", ) @Entity @Table(name = "env_actions") class EnvActionModel( - @Id - @JdbcType(UUIDJdbcType::class) - @Column(name = "id", nullable = false, updatable = false, columnDefinition = "uuid") - val id: UUID, - @Column(name = "action_start_datetime_utc") val actionStartDateTime: Instant? = null, - @Column(name = "action_end_datetime_utc") val actionEndDateTime: Instant? = null, - @JsonSerialize(using = GeometrySerializer::class) - @JsonDeserialize(contentUsing = GeometryDeserializer::class) - @Column(name = "geom") - val geom: Geometry? = null, - @Column(name = "action_type") @Enumerated(EnumType.STRING) val actionType: ActionTypeEnum, - @Type(JsonBinaryType::class) - @Column(name = "value", columnDefinition = "jsonb") - val value: String, - @Column(name = "facade") val facade: String? = null, - @Column(name = "department") val department: String? = null, - @ManyToOne(fetch = FetchType.LAZY, optional = false) - @JoinColumn(name = "mission_id") - @JsonBackReference - val mission: MissionModel, - @Column(name = "is_administrative_control") val isAdministrativeControl: Boolean? = null, - @Column(name = "is_compliance_with_water_regulations_control") - val isComplianceWithWaterRegulationsControl: Boolean? = null, - @Column(name = "is_safety_equipment_and_standards_compliance_control") - val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, - @Column(name = "is_seafarers_control") val isSeafarersControl: Boolean? = null, - @OneToMany( - fetch = FetchType.LAZY, - mappedBy = "attachedEnvAction", - ) - @JsonManagedReference - val attachedReporting: List<ReportingModel>? = listOf(), - @OneToMany( - fetch = FetchType.EAGER, - cascade = [CascadeType.ALL], - orphanRemoval = true, - mappedBy = "envAction", - ) - val controlPlanThemes: MutableList<EnvActionsControlPlanThemeModel>? = ArrayList(), - @OneToMany( - fetch = FetchType.EAGER, - cascade = [CascadeType.ALL], - orphanRemoval = true, - mappedBy = "envAction", - ) - val controlPlanSubThemes: MutableList<EnvActionsControlPlanSubThemeModel>? = ArrayList(), - @OneToMany( - fetch = FetchType.EAGER, - cascade = [CascadeType.ALL], - orphanRemoval = true, - mappedBy = "envAction", - ) - val controlPlanTags: MutableList<EnvActionsControlPlanTagModel>? = ArrayList(), + @Id + @JdbcType(UUIDJdbcType::class) + @Column(name = "id", nullable = false, updatable = false, columnDefinition = "uuid") + val id: UUID, + @Column(name = "action_start_datetime_utc") val actionStartDateTime: Instant? = null, + @Column(name = "action_end_datetime_utc") val actionEndDateTime: Instant? = null, + @JsonSerialize(using = GeometrySerializer::class) + @JsonDeserialize(contentUsing = GeometryDeserializer::class) + @Column(name = "geom") + val geom: Geometry? = null, + @Column(name = "action_type") + @Enumerated(EnumType.STRING) + val actionType: ActionTypeEnum, + @Type(JsonBinaryType::class) + @Column(name = "value", columnDefinition = "jsonb") + val value: String, + @Column(name = "facade") val facade: String? = null, + @Column(name = "department") val department: String? = null, + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "mission_id") + @JsonBackReference + val mission: MissionModel, + @Column(name = "is_administrative_control") val isAdministrativeControl: Boolean? = null, + @Column(name = "is_compliance_with_water_regulations_control") + val isComplianceWithWaterRegulationsControl: Boolean? = null, + @Column(name = "is_safety_equipment_and_standards_compliance_control") + val isSafetyEquipmentAndStandardsComplianceControl: Boolean? = null, + @Column(name = "is_seafarers_control") val isSeafarersControl: Boolean? = null, + @OneToMany( + fetch = FetchType.LAZY, + mappedBy = "attachedEnvAction", + ) + @JsonManagedReference + val attachedReporting: List<ReportingModel>? = listOf(), + @OneToMany( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + orphanRemoval = true, + mappedBy = "envAction", + ) + val controlPlanThemes: MutableList<EnvActionsControlPlanThemeModel>? = ArrayList(), + @OneToMany( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + orphanRemoval = true, + mappedBy = "envAction", + ) + val controlPlanSubThemes: MutableList<EnvActionsControlPlanSubThemeModel>? = ArrayList(), + @OneToMany( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + orphanRemoval = true, + mappedBy = "envAction", + ) + val controlPlanTags: MutableList<EnvActionsControlPlanTagModel>? = ArrayList(), ) { fun toActionEntity(mapper: ObjectMapper): EnvActionEntity { val controlPlans = - controlPlanThemes?.map { it -> - EnvActionControlPlanEntity( - themeId = it.id.themeId, - subThemeIds = - controlPlanSubThemes - ?.filter { subTheme -> - it.id.themeId == - subTheme.controlPlanSubTheme - ?.controlPlanTheme - ?.id - } - ?.map { it.id.subthemeId }, - tagIds = - controlPlanTags - ?.filter { tag -> - it.id.themeId == - tag.controlPlanTag?.controlPlanTheme?.id - } - ?.map { it.id.tagId }, - ) - } + controlPlanThemes?.map { it -> + EnvActionControlPlanEntity( + themeId = it.id.themeId, + subThemeIds = + controlPlanSubThemes + ?.filter { subTheme -> + it.id.themeId == + subTheme.controlPlanSubTheme + ?.controlPlanTheme + ?.id + } + ?.map { it.id.subthemeId }, + tagIds = + controlPlanTags + ?.filter { tag -> + it.id.themeId == + tag.controlPlanTag?.controlPlanTheme?.id + } + ?.map { it.id.tagId }, + ) + } return EnvActionMapper.getEnvActionEntityFromJSON( - mapper = mapper, - id = id, - actionEndDateTimeUtc = actionEndDateTime?.atZone(UTC), - actionType = actionType, - actionStartDateTimeUtc = actionStartDateTime?.atZone(UTC), - controlPlans = controlPlans, - department = department, - facade = facade, - geom = geom, - isAdministrativeControl = isAdministrativeControl, - isComplianceWithWaterRegulationsControl = isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = isSeafarersControl, - value = value, + mapper = mapper, + id = id, + actionEndDateTimeUtc = actionEndDateTime?.atZone(UTC), + actionType = actionType, + actionStartDateTimeUtc = actionStartDateTime?.atZone(UTC), + controlPlans = controlPlans, + department = department, + facade = facade, + geom = geom, + isAdministrativeControl = isAdministrativeControl, + isComplianceWithWaterRegulationsControl = isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = isSeafarersControl, + value = value, ) } companion object { fun fromEnvActionEntity( - action: EnvActionEntity, - mission: MissionModel, - controlPlanThemesReferenceModelMap: Map<Int, ControlPlanThemeModel>, - controlPlanSubThemesReferenceModelMap: Map<Int, ControlPlanSubThemeModel>, - controlPlanTagsReferenceModelMap: Map<Int, ControlPlanTagModel>, - mapper: ObjectMapper, + action: EnvActionEntity, + mission: MissionModel, + controlPlanThemesReferenceModelMap: Map<Int, ControlPlanThemeModel>, + controlPlanSubThemesReferenceModelMap: Map<Int, ControlPlanSubThemeModel>, + controlPlanTagsReferenceModelMap: Map<Int, ControlPlanTagModel>, + mapper: ObjectMapper, ): EnvActionModel { val envActionModel = - EnvActionModel( - id = action.id, - actionEndDateTime = action.actionEndDateTimeUtc?.toInstant(), - actionType = action.actionType, - actionStartDateTime = action.actionStartDateTimeUtc?.toInstant(), - department = action.department, - facade = action.facade, - isAdministrativeControl = action.isAdministrativeControl, - isComplianceWithWaterRegulationsControl = - action.isComplianceWithWaterRegulationsControl, - isSafetyEquipmentAndStandardsComplianceControl = - action.isSafetyEquipmentAndStandardsComplianceControl, - isSeafarersControl = action.isSeafarersControl, - mission = mission, - geom = action.geom, - value = EnvActionMapper.envActionEntityToJSON(mapper, action), - ) + EnvActionModel( + id = action.id, + actionEndDateTime = action.actionEndDateTimeUtc?.toInstant(), + actionType = action.actionType, + actionStartDateTime = action.actionStartDateTimeUtc?.toInstant(), + department = action.department, + facade = action.facade, + isAdministrativeControl = action.isAdministrativeControl, + isComplianceWithWaterRegulationsControl = + action.isComplianceWithWaterRegulationsControl, + isSafetyEquipmentAndStandardsComplianceControl = + action.isSafetyEquipmentAndStandardsComplianceControl, + isSeafarersControl = action.isSeafarersControl, + mission = mission, + geom = action.geom, + value = EnvActionMapper.envActionEntityToJSON(mapper, action), + ) action.controlPlans?.forEach { envActionModel.controlPlanThemes?.add( - EnvActionsControlPlanThemeModel.fromEnvActionControlPlanThemeEntity( - envAction = envActionModel, - controlPlanTheme = controlPlanThemesReferenceModelMap[it.themeId]!!, - ), + EnvActionsControlPlanThemeModel.fromEnvActionControlPlanThemeEntity( + envAction = envActionModel, + controlPlanTheme = controlPlanThemesReferenceModelMap[it.themeId]!!, + ), ) it.subThemeIds?.forEach { subThemeId -> envActionModel.controlPlanSubThemes?.add( - EnvActionsControlPlanSubThemeModel - .fromEnvActionControlPlanSubThemeEntity( - envAction = envActionModel, - controlPlanSubTheme = - controlPlanSubThemesReferenceModelMap[ - subThemeId]!!, - ), + EnvActionsControlPlanSubThemeModel + .fromEnvActionControlPlanSubThemeEntity( + envAction = envActionModel, + controlPlanSubTheme = + controlPlanSubThemesReferenceModelMap[ + subThemeId, + ]!!, + ), ) } it.tagIds?.forEach { tagId -> envActionModel.controlPlanTags?.add( - EnvActionsControlPlanTagModel.fromEnvActionControlPlanTagEntity( - envAction = envActionModel, - controlPlanTag = controlPlanTagsReferenceModelMap[tagId]!!, - ), + EnvActionsControlPlanTagModel.fromEnvActionControlPlanTagEntity( + envAction = envActionModel, + controlPlanTag = controlPlanTagsReferenceModelMap[tagId]!!, + ), ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt index b0f82f94c..e03a108ed 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanSubThemeModel.kt @@ -9,37 +9,37 @@ import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne import jakarta.persistence.MapsId import jakarta.persistence.Table +import org.hibernate.Hibernate import java.io.Serializable import java.util.UUID -import org.hibernate.Hibernate @Entity @Table(name = "env_actions_control_plan_sub_themes") class EnvActionsControlPlanSubThemeModel( - @EmbeddedId val id: EnvActionsSubThemePk, - @ManyToOne(fetch = FetchType.LAZY) - @MapsId("envActionId") - @JoinColumn(name = "env_action_id") - val envAction: EnvActionModel? = null, - @ManyToOne(fetch = FetchType.LAZY) - @MapsId("subthemeId") - @JoinColumn(name = "subtheme_id") - val controlPlanSubTheme: ControlPlanSubThemeModel? = null, + @EmbeddedId val id: EnvActionsSubThemePk, + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("envActionId") + @JoinColumn(name = "env_action_id") + val envAction: EnvActionModel? = null, + @ManyToOne(fetch = FetchType.EAGER) + @MapsId("subthemeId") + @JoinColumn(name = "subtheme_id") + val controlPlanSubTheme: ControlPlanSubThemeModel? = null, ) { companion object { fun fromEnvActionControlPlanSubThemeEntity( - envAction: EnvActionModel, - controlPlanSubTheme: ControlPlanSubThemeModel, + envAction: EnvActionModel, + controlPlanSubTheme: ControlPlanSubThemeModel, ) = - EnvActionsControlPlanSubThemeModel( - id = - EnvActionsSubThemePk( - envActionId = envAction.id, - subthemeId = controlPlanSubTheme.id, - ), - envAction = envAction, - controlPlanSubTheme = controlPlanSubTheme, - ) + EnvActionsControlPlanSubThemeModel( + id = + EnvActionsSubThemePk( + envActionId = envAction.id, + subthemeId = controlPlanSubTheme.id, + ), + envAction = envAction, + controlPlanSubTheme = controlPlanSubTheme, + ) } override fun equals(other: Any?): Boolean { @@ -55,8 +55,8 @@ class EnvActionsControlPlanSubThemeModel( @Embeddable data class EnvActionsSubThemePk( - @Column(name = "env_action_id") val envActionId: UUID, - @Column(name = "subtheme_id") val subthemeId: Int, + @Column(name = "env_action_id") val envActionId: UUID, + @Column(name = "subtheme_id") val subthemeId: Int, ) : Serializable { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt index f579bdc5e..0d6d5b750 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsControlPlanTagModel.kt @@ -9,37 +9,37 @@ import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne import jakarta.persistence.MapsId import jakarta.persistence.Table +import org.hibernate.Hibernate import java.io.Serializable import java.util.UUID -import org.hibernate.Hibernate @Entity @Table(name = "env_actions_control_plan_tags") class EnvActionsControlPlanTagModel( - @EmbeddedId val id: EnvActionsTagPk, - @ManyToOne(fetch = FetchType.LAZY) - @MapsId("envActionId") - @JoinColumn(name = "env_action_id") - val envAction: EnvActionModel? = null, - @ManyToOne(fetch = FetchType.EAGER) - @MapsId("tagId") - @JoinColumn(name = "tag_id") - val controlPlanTag: ControlPlanTagModel? = null, + @EmbeddedId val id: EnvActionsTagPk, + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("envActionId") + @JoinColumn(name = "env_action_id") + val envAction: EnvActionModel? = null, + @ManyToOne(fetch = FetchType.EAGER) + @MapsId("tagId") + @JoinColumn(name = "tag_id") + val controlPlanTag: ControlPlanTagModel? = null, ) { companion object { fun fromEnvActionControlPlanTagEntity( - envAction: EnvActionModel, - controlPlanTag: ControlPlanTagModel, + envAction: EnvActionModel, + controlPlanTag: ControlPlanTagModel, ) = - EnvActionsControlPlanTagModel( - id = - EnvActionsTagPk( - envActionId = envAction.id!!, - tagId = controlPlanTag.id!!, - ), - envAction = envAction, - controlPlanTag = controlPlanTag, - ) + EnvActionsControlPlanTagModel( + id = + EnvActionsTagPk( + envActionId = envAction.id!!, + tagId = controlPlanTag.id!!, + ), + envAction = envAction, + controlPlanTag = controlPlanTag, + ) } override fun equals(other: Any?): Boolean { @@ -55,8 +55,8 @@ class EnvActionsControlPlanTagModel( @Embeddable data class EnvActionsTagPk( - @Column(name = "env_action_id") val envActionId: UUID, - @Column(name = "tag_id") val tagId: Int, + @Column(name = "env_action_id") val envActionId: UUID, + @Column(name = "tag_id") val tagId: Int, ) : Serializable { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt deleted file mode 100644 index 78fb12a7e..000000000 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionsSubThemeModel.kt +++ /dev/null @@ -1,68 +0,0 @@ -package fr.gouv.cacem.monitorenv.infrastructure.database.model - -import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanSubThemeEntity -import io.hypersistence.utils.hibernate.type.array.ListArrayType -import jakarta.persistence.Column -import jakarta.persistence.Embeddable -import jakarta.persistence.EmbeddedId -import jakarta.persistence.Entity -import jakarta.persistence.JoinColumn -import jakarta.persistence.ManyToOne -import jakarta.persistence.MapsId -import jakarta.persistence.Table -import org.hibernate.annotations.Type -import java.io.Serializable -import java.util.UUID - -@Entity -@Table(name = "env_actions_subthemes") -data class EnvActionsSubThemeModel( - - @EmbeddedId - val id: EnvActionsSubThemePk, - - @ManyToOne - @MapsId("envActionId") - @JoinColumn(name = "env_action_id") - val envAction: EnvActionModel? = null, - - @ManyToOne - @MapsId("subthemeId") - @JoinColumn(name = "subtheme_id") - val controlPlanSubTheme: ControlPlanSubThemeModel? = null, - - @Column(name = "tags") - @Type(ListArrayType::class) - val tags: List<String>? = null, -) { - fun toEnvActionControlPlanSubThemeEntity(): EnvActionControlPlanSubThemeEntity { - require(controlPlanSubTheme != null) { "controlPlanSubTheme must not be null when converting to Entity" } - return EnvActionControlPlanSubThemeEntity( - subThemeId = controlPlanSubTheme.id, - theme = controlPlanSubTheme.ControlPlanTheme.theme, - subTheme = controlPlanSubTheme.subTheme, - tags = tags ?: emptyList(), - ) - } - companion object { - fun fromEnvActionControlPlanSubThemeEntity( - envActionId: UUID, - envActionControlPlanSubTheme: EnvActionControlPlanSubThemeEntity, - ) = EnvActionsSubThemeModel( - id = EnvActionsSubThemePk( - envActionId = envActionId, - subthemeId = envActionControlPlanSubTheme.subThemeId, - ), - tags = envActionControlPlanSubTheme.tags, - ) - } -} - -@Embeddable -data class EnvActionsSubThemePk( - @Column(name = "env_action_id") - val envActionId: UUID, - - @Column(name = "subtheme_id") - val subthemeId: Int, -) : Serializable diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt index 4f4b2bfc2..f73e74ec0 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepository.kt @@ -7,7 +7,7 @@ import org.springframework.stereotype.Repository @Repository class JpaControlPlanSubThemeRepository( - private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, + private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, ) : IControlPlanSubThemeRepository { override fun findAll(): List<ControlPlanSubThemeEntity> { return dbControlPlanSubThemeRepository.findAll().map { it.toControlPlanSubThemeEntity() } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt index 97530bf41..5da1764cc 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepository.kt @@ -7,7 +7,7 @@ import org.springframework.stereotype.Repository @Repository class JpaControlPlanTagRepository( - private val dbControlPlanTagRepository: IDBControlPlanTagRepository, + private val dbControlPlanTagRepository: IDBControlPlanTagRepository, ) : IControlPlanTagRepository { override fun findAll(): List<ControlPlanTagEntity> { return dbControlPlanTagRepository.findAll().map { it.toControlPlanTagEntity() } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt index ee9ef244b..1826e74a8 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepository.kt @@ -9,7 +9,12 @@ import org.springframework.stereotype.Repository class JpaControlPlanThemeRepository( private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, ) : IControlPlanThemeRepository { + override fun findAll(): List<ControlPlanThemeEntity> { + return dbControlPlanThemeRepository.findAll().map { it.toControlPlanThemeEntity() } + } override fun findByYear(year: Int): List<ControlPlanThemeEntity> { - return dbControlPlanThemeRepository.findByYearOrderById(year).map { it.toControlPlanThemeEntity() } + return dbControlPlanThemeRepository.findByYearOrderById(year).map { + it.toControlPlanThemeEntity() + } } } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt index f72a687fc..b824c09ff 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepository.kt @@ -11,20 +11,20 @@ import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces. import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlPlanThemeRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBControlUnitResourceRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBMissionRepository -import java.time.Instant import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.Modifying import org.springframework.stereotype.Repository import org.springframework.transaction.annotation.Transactional +import java.time.Instant @Repository class JpaMissionRepository( - private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, - private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, - private val dbControlPlanTagRepository: IDBControlPlanTagRepository, - private val dbControlUnitResourceRepository: IDBControlUnitResourceRepository, - private val dbMissionRepository: IDBMissionRepository, - private val mapper: ObjectMapper, + private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, + private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, + private val dbControlPlanTagRepository: IDBControlPlanTagRepository, + private val dbControlUnitResourceRepository: IDBControlUnitResourceRepository, + private val dbMissionRepository: IDBMissionRepository, + private val mapper: ObjectMapper, ) : IMissionRepository { override fun count(): Long { return dbMissionRepository.count() @@ -37,25 +37,25 @@ class JpaMissionRepository( } override fun findAllFullMissions( - startedAfter: Instant, - startedBefore: Instant?, - missionTypes: List<String>?, - missionStatuses: List<String>?, - missionSources: List<MissionSourceEnum>?, - seaFronts: List<String>?, - pageable: Pageable, + startedAfter: Instant, + startedBefore: Instant?, + missionTypes: List<String>?, + missionStatuses: List<String>?, + missionSources: List<MissionSourceEnum>?, + seaFronts: List<String>?, + pageable: Pageable, ): List<MissionDTO> { val missionSourcesAsStringArray = missionSources?.map { it.name } return dbMissionRepository.findAll( - startedAfter = startedAfter, - startedBefore = startedBefore, - missionTypes = convertToPGArray(missionTypes), - missionStatuses = convertToPGArray(missionStatuses), - missionSources = convertToPGArray(missionSourcesAsStringArray), - seaFronts = convertToPGArray(seaFronts), - pageable = pageable, - ) - .map { it.toMissionDTO(mapper) } + startedAfter = startedAfter, + startedBefore = startedBefore, + missionTypes = convertToPGArray(missionTypes), + missionStatuses = convertToPGArray(missionStatuses), + missionSources = convertToPGArray(missionSourcesAsStringArray), + seaFronts = convertToPGArray(seaFronts), + pageable = pageable, + ) + .map { it.toMissionDTO(mapper) } } override fun findByIds(ids: List<Int>): List<MissionEntity> { @@ -75,25 +75,25 @@ class JpaMissionRepository( } override fun findAll( - startedAfter: Instant, - startedBefore: Instant?, - missionTypes: List<String>?, - missionStatuses: List<String>?, - missionSources: List<MissionSourceEnum>?, - seaFronts: List<String>?, - pageable: Pageable, + startedAfter: Instant, + startedBefore: Instant?, + missionTypes: List<String>?, + missionStatuses: List<String>?, + missionSources: List<MissionSourceEnum>?, + seaFronts: List<String>?, + pageable: Pageable, ): List<MissionEntity> { val missionSourcesAsStringArray = missionSources?.map { it.name } return dbMissionRepository.findAll( - startedAfter = startedAfter, - startedBefore = startedBefore, - missionTypes = convertToPGArray(missionTypes), - missionStatuses = convertToPGArray(missionStatuses), - missionSources = convertToPGArray(missionSourcesAsStringArray), - seaFronts = convertToPGArray(seaFronts), - pageable = pageable, - ) - .map { it.toMissionEntity(mapper) } + startedAfter = startedAfter, + startedBefore = startedBefore, + missionTypes = convertToPGArray(missionTypes), + missionStatuses = convertToPGArray(missionStatuses), + missionSources = convertToPGArray(missionSourcesAsStringArray), + seaFronts = convertToPGArray(seaFronts), + pageable = pageable, + ) + .map { it.toMissionEntity(mapper) } } override fun findFullMissionById(missionId: Int): MissionDTO { @@ -109,15 +109,15 @@ class JpaMissionRepository( override fun save(mission: MissionEntity): MissionDTO { // Extract all control units resources unique control unit resource IDs val uniqueControlUnitResourceIds = - mission.controlUnits - .flatMap { controlUnit -> controlUnit.resources.map { it.id } } - .distinct() + mission.controlUnits + .flatMap { controlUnit -> controlUnit.resources.map { it.id } } + .distinct() // Fetch all of them as models val controlUnitResourceModels = - dbControlUnitResourceRepository.findAllById(uniqueControlUnitResourceIds) + dbControlUnitResourceRepository.findAllById(uniqueControlUnitResourceIds) // Create an `[id] → ControlUnitResourceModel` map val controlUnitResourceModelMap = - controlUnitResourceModels.associateBy { requireNotNull(it.id) } + controlUnitResourceModels.associateBy { requireNotNull(it.id) } val controlPlanThemes = ArrayList<Int>() val controlPlanSubThemes = ArrayList<Int>() @@ -135,32 +135,32 @@ class JpaMissionRepository( // Create a map from controlPlanThemes mapping each id to a reference to the model val controlPlanThemesReferenceModelMap = - controlPlanThemes?.distinct()?.associateWith { id -> - dbControlPlanThemeRepository.getReferenceById(id) - } + controlPlanThemes?.distinct()?.associateWith { id -> + dbControlPlanThemeRepository.getReferenceById(id) + } // Create a map from controlPlanSubThemes mapping each id to a reference to the model val controlPlanSubThemesReferenceModelMap = - controlPlanSubThemes?.distinct()?.associateWith { id -> - dbControlPlanSubThemeRepository.getReferenceById(id) - } + controlPlanSubThemes?.distinct()?.associateWith { id -> + dbControlPlanSubThemeRepository.getReferenceById(id) + } // Create a map from controlPlanTags mapping each id to a reference to the model val controlPlanTagsReferenceModelMap = - controlPlanTags?.distinct()?.associateWith { id -> - dbControlPlanTagRepository.getReferenceById(id) - } + controlPlanTags?.distinct()?.associateWith { id -> + dbControlPlanTagRepository.getReferenceById(id) + } val missionModel = - MissionModel.fromMissionEntity( - mission = mission, - controlUnitResourceModelMap = controlUnitResourceModelMap, - controlPlanThemesReferenceModelMap = controlPlanThemesReferenceModelMap - ?: emptyMap(), - controlPlanSubThemesReferenceModelMap = - controlPlanSubThemesReferenceModelMap ?: emptyMap(), - controlPlanTagsReferenceModelMap = controlPlanTagsReferenceModelMap - ?: emptyMap(), - mapper = mapper, - ) + MissionModel.fromMissionEntity( + mission = mission, + controlUnitResourceModelMap = controlUnitResourceModelMap, + controlPlanThemesReferenceModelMap = controlPlanThemesReferenceModelMap + ?: emptyMap(), + controlPlanSubThemesReferenceModelMap = + controlPlanSubThemesReferenceModelMap ?: emptyMap(), + controlPlanTagsReferenceModelMap = controlPlanTagsReferenceModelMap + ?: emptyMap(), + mapper = mapper, + ) return dbMissionRepository.saveAndFlush(missionModel).toMissionDTO(mapper) } diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt index e8ee86b32..f8f84cf0b 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaReportingRepository.kt @@ -16,25 +16,25 @@ import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces. import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBMissionRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBReportingRepository import fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces.IDBSemaphoreRepository -import java.time.Instant -import java.util.UUID import org.springframework.dao.DataIntegrityViolationException import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.Modifying import org.springframework.orm.jpa.JpaObjectRetrievalFailureException import org.springframework.stereotype.Repository import org.springframework.transaction.annotation.Transactional +import java.time.Instant +import java.util.UUID @Repository class JpaReportingRepository( - private val dbReportingRepository: IDBReportingRepository, - private val dbMissionRepository: IDBMissionRepository, - private val dbSemaphoreRepository: IDBSemaphoreRepository, - private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, - private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, - private val dbControlUnitRepository: IDBControlUnitRepository, - private val dbEnvActionRepository: IDBEnvActionRepository, - private val mapper: ObjectMapper, + private val dbReportingRepository: IDBReportingRepository, + private val dbMissionRepository: IDBMissionRepository, + private val dbSemaphoreRepository: IDBSemaphoreRepository, + private val dbControlPlanThemeRepository: IDBControlPlanThemeRepository, + private val dbControlPlanSubThemeRepository: IDBControlPlanSubThemeRepository, + private val dbControlUnitRepository: IDBControlUnitRepository, + private val dbEnvActionRepository: IDBEnvActionRepository, + private val mapper: ObjectMapper, ) : IReportingRepository { @Transactional @@ -57,26 +57,26 @@ class JpaReportingRepository( } override fun findAll( - pageable: Pageable, - reportingType: List<ReportingTypeEnum>?, - seaFronts: List<String>?, - sourcesType: List<SourceTypeEnum>?, - startedAfter: Instant, - startedBefore: Instant?, - status: List<String>?, + pageable: Pageable, + reportingType: List<ReportingTypeEnum>?, + seaFronts: List<String>?, + sourcesType: List<SourceTypeEnum>?, + startedAfter: Instant, + startedBefore: Instant?, + status: List<String>?, ): List<ReportingDTO> { val sourcesTypeAsStringArray = sourcesType?.map { it.name } val reportingTypeAsStringArray = reportingType?.map { it.name } return dbReportingRepository.findAll( - pageable, - reportingType = convertToString(reportingTypeAsStringArray), - seaFronts = convertToString(seaFronts), - sourcesType = convertToString(sourcesTypeAsStringArray), - startedAfter = startedAfter, - startedBefore = startedBefore, - status = convertToString(status), - ) - .map { it.toReportingDTO(mapper) } + pageable, + reportingType = convertToString(reportingTypeAsStringArray), + seaFronts = convertToString(seaFronts), + sourcesType = convertToString(sourcesTypeAsStringArray), + startedAfter = startedAfter, + startedBefore = startedBefore, + status = convertToString(status), + ) + .map { it.toReportingDTO(mapper) } } override fun findByControlUnitId(controlUnitId: Int): List<ReportingEntity> { @@ -92,92 +92,92 @@ class JpaReportingRepository( override fun save(reporting: ReportingEntity): ReportingDTO { return try { val semaphoreReference = - if (reporting.semaphoreId != null) { - dbSemaphoreRepository.getReferenceById( - reporting.semaphoreId, - ) - } else { - null - } + if (reporting.semaphoreId != null) { + dbSemaphoreRepository.getReferenceById( + reporting.semaphoreId, + ) + } else { + null + } val controlUnitReference = - if (reporting.controlUnitId != null) { - dbControlUnitRepository.getReferenceById( - reporting.controlUnitId, - ) - } else { - null - } + if (reporting.controlUnitId != null) { + dbControlUnitRepository.getReferenceById( + reporting.controlUnitId, + ) + } else { + null + } val missionReference = - if (reporting.missionId != null) { - dbMissionRepository.getReferenceById( - reporting.missionId, - ) - } else { - null - } + if (reporting.missionId != null) { + dbMissionRepository.getReferenceById( + reporting.missionId, + ) + } else { + null + } val envActionReference = - if (reporting.attachedEnvActionId != null) { - dbEnvActionRepository.getReferenceById( - reporting.attachedEnvActionId, - ) - } else { - null - } + if (reporting.attachedEnvActionId != null) { + dbEnvActionRepository.getReferenceById( + reporting.attachedEnvActionId, + ) + } else { + null + } val controlPlanThemeReference = - if (reporting.themeId != null) { - dbControlPlanThemeRepository.getReferenceById( - reporting.themeId, - ) - } else { - null - } + if (reporting.themeId != null) { + dbControlPlanThemeRepository.getReferenceById( + reporting.themeId, + ) + } else { + null + } val controlPlanSubThemesReferenceList = - reporting.subThemeIds?.map { - dbControlPlanSubThemeRepository.getReferenceById(it) - } + reporting.subThemeIds?.map { + dbControlPlanSubThemeRepository.getReferenceById(it) + } // To save controlPlanSubThemes we must ensure that reportingId is set // to simplify the understandability of the code, we do the same steps for creation and // update // even if it is not necessary for update // first save (ensure id is set) - var reportingModel: ReportingModel + val reportingModel: ReportingModel if (reporting.id == null) { reportingModel = - dbReportingRepository.save( - ReportingModel.fromReportingEntity( - reporting = reporting, - semaphoreReference = semaphoreReference, - controlUnitReference = controlUnitReference, - missionReference = missionReference, - envActionReference = envActionReference, - controlPlanThemeReference = controlPlanThemeReference, - ), - ) + dbReportingRepository.save( + ReportingModel.fromReportingEntity( + reporting = reporting, + semaphoreReference = semaphoreReference, + controlUnitReference = controlUnitReference, + missionReference = missionReference, + envActionReference = envActionReference, + controlPlanThemeReference = controlPlanThemeReference, + ), + ) } else { reportingModel = - ReportingModel.fromReportingEntity( - reporting = reporting, - semaphoreReference = semaphoreReference, - controlUnitReference = controlUnitReference, - missionReference = missionReference, - envActionReference = envActionReference, - controlPlanThemeReference = controlPlanThemeReference, - ) + ReportingModel.fromReportingEntity( + reporting = reporting, + semaphoreReference = semaphoreReference, + controlUnitReference = controlUnitReference, + missionReference = missionReference, + envActionReference = envActionReference, + controlPlanThemeReference = controlPlanThemeReference, + ) } // set controlPlanSubThemes and save again (and flush) controlPlanSubThemesReferenceList?.forEach { it -> reportingModel.controlPlanSubThemes?.add( - ReportingsControlPlanSubThemeModel.fromModels(reportingModel, it), + ReportingsControlPlanSubThemeModel.fromModels(reportingModel, it), ) } dbReportingRepository.saveAndFlush(reportingModel).toReportingDTO(mapper) } catch (e: JpaObjectRetrievalFailureException) { throw NotFoundException( - "Invalid reference to semaphore, control unit or mission: not found in referential", - e, + "Invalid reference to semaphore, control unit or mission: not found in referential", + e, ) } catch (e: DataIntegrityViolationException) { throw NotFoundException("Invalid combination of mission and/or envAction", e) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt index 8b1378917..21fad8c5e 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanSubThemeRepository.kt @@ -1 +1,8 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories.interfaces +import fr.gouv.cacem.monitorenv.infrastructure.database.model.ControlPlanSubThemeModel +import org.springframework.data.jpa.repository.JpaRepository + +interface IDBControlPlanSubThemeRepository : JpaRepository<ControlPlanSubThemeModel, Int> { + fun findByYearOrderById(year: Int): List<ControlPlanSubThemeModel> +} diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt index fe7ffe8a8..371bed3fc 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/interfaces/IDBControlPlanTagRepository.kt @@ -7,8 +7,8 @@ import org.springframework.data.jpa.repository.Query interface IDBControlPlanTagRepository : JpaRepository<ControlPlanTagModel, Int> { @Query( - value = - """ + value = + """ SELECT tags.* FROM control_plan_tags tags, control_plan_sub_themes s, control_plan_themes th WHERE tags.theme_id = th.id @@ -16,7 +16,7 @@ interface IDBControlPlanTagRepository : JpaRepository<ControlPlanTagModel, Int> AND s.year = :year ORDER BY tags.id ASC """, - nativeQuery = true, + nativeQuery = true, ) fun findByYearOrderById(year: Int): List<ControlPlanTagModel> } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt index a79557bef..b537b15a1 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/controlPlan/GetControlPlansByYearUTest.kt @@ -20,56 +20,56 @@ class GetControlPlansByYearUTest { fun `execute should return all ControlPlanThemes, ControlPlanSubThemes and ControlPlanTags for the given year`() { val controlPlanThemes = - listOf( - ControlPlanThemeEntity( - id = 1, - theme = "ControlPlanTheme Name", - ), - ControlPlanThemeEntity( - id = 2, - theme = "ControlPlanTheme Name 2", - ), - ) + listOf( + ControlPlanThemeEntity( + id = 1, + theme = "ControlPlanTheme Name", + ), + ControlPlanThemeEntity( + id = 2, + theme = "ControlPlanTheme Name 2", + ), + ) val controlPlanSubThemes = - listOf( - ControlPlanSubThemeEntity( - id = 1, - themeId = 1, - subTheme = "ControlPlanSubTheme Name", - year = 2023, - ), - ControlPlanSubThemeEntity( - id = 2, - themeId = 1, - subTheme = "ControlPlanSubTheme Name 2", - year = 2023, - ), - ) + listOf( + ControlPlanSubThemeEntity( + id = 1, + themeId = 1, + subTheme = "ControlPlanSubTheme Name", + year = 2023, + ), + ControlPlanSubThemeEntity( + id = 2, + themeId = 1, + subTheme = "ControlPlanSubTheme Name 2", + year = 2023, + ), + ) val controlPlanTags = - listOf( - ControlPlanTagEntity( - id = 1, - tag = "ControlPlanTag Name", - themeId = 1, - ), - ControlPlanTagEntity( - id = 2, - tag = "ControlPlanTag Name 2", - themeId = 2, - ), - ) + listOf( + ControlPlanTagEntity( + id = 1, + tag = "ControlPlanTag Name", + themeId = 1, + ), + ControlPlanTagEntity( + id = 2, + tag = "ControlPlanTag Name 2", + themeId = 2, + ), + ) given(controlPlanThemeRepository.findByYear(2023)).willReturn(controlPlanThemes) given(controlPlanSubThemeRepository.findByYear(2023)).willReturn(controlPlanSubThemes) given(controlPlanTagRepository.findByYear(2023)).willReturn(controlPlanTags) val result = - GetControlPlansByYear( - controlPlanThemeRepository = controlPlanThemeRepository, - controlPlanSubThemeRepository = controlPlanSubThemeRepository, - controlPlanTagRepository = controlPlanTagRepository, - ) - .execute(2023) + GetControlPlansByYear( + controlPlanThemeRepository = controlPlanThemeRepository, + controlPlanSubThemeRepository = controlPlanSubThemeRepository, + controlPlanTagRepository = controlPlanTagRepository, + ) + .execute(2023) assertThat(result.first.size).isEqualTo(2) assertThat(result).isEqualTo(controlPlanSubThemes) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt index da1117c03..c6a0a9b2d 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/ControlPlansControllerITests.kt @@ -31,52 +31,52 @@ class ControlPlansControllerITests { fun `Should get all control plan themes`() { // Given val controlPlanTheme1 = - ControlPlanThemeEntity( - id = 1, - theme = "Theme Police des mouillages", - ) + ControlPlanThemeEntity( + id = 1, + theme = "Theme Police des mouillages", + ) val controlPlanTheme2 = - ControlPlanThemeEntity( - id = 2, - theme = "Theme Protection des espèces", - ) + ControlPlanThemeEntity( + id = 2, + theme = "Theme Protection des espèces", + ) val controlPlanSubTheme1 = - ControlPlanSubThemeEntity( - id = 10, - themeId = 1, - subTheme = "SubTheme ZMEL", - year = 2024, - ) + ControlPlanSubThemeEntity( + id = 10, + themeId = 1, + subTheme = "SubTheme ZMEL", + year = 2024, + ) val controlPlanTag = - ControlPlanTagEntity( - id = 100, - themeId = 2, - tag = "Tag Bichique", - ) + ControlPlanTagEntity( + id = 100, + themeId = 2, + tag = "Tag Bichique", + ) val controlPlan = - Triple( - listOf(controlPlanTheme1, controlPlanTheme2), - listOf(controlPlanSubTheme1), - listOf(controlPlanTag), - ) + Triple( + listOf(controlPlanTheme1, controlPlanTheme2), + listOf(controlPlanSubTheme1), + listOf(controlPlanTag), + ) BDDMockito.given(getControlPlans.execute()).willReturn(controlPlan) // When - mockMvc.perform(get("/bff/v1/control_plans/")) - // Then - .andExpect(status().isOk) - .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) - .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) - .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) - .andExpect( - jsonPath("$.subThemes[\"10\"].subTheme") - .value(controlPlanSubTheme1.subTheme), - ) - .andExpect( - jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId), - ) - .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) - .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) - .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) + mockMvc.perform(get("/bff/v1/control_plans")) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) + .andExpect( + jsonPath("$.subThemes[\"10\"].subTheme") + .value(controlPlanSubTheme1.subTheme), + ) + .andExpect( + jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId), + ) + .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) + .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) + .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) verify(getControlPlans).execute() } @@ -85,52 +85,52 @@ class ControlPlansControllerITests { fun `Should get all control plan themes by year`() { // Given val controlPlanTheme1 = - ControlPlanThemeEntity( - id = 1, - theme = "Theme Police des mouillages", - ) + ControlPlanThemeEntity( + id = 1, + theme = "Theme Police des mouillages", + ) val controlPlanTheme2 = - ControlPlanThemeEntity( - id = 2, - theme = "Theme Protection des espèces", - ) + ControlPlanThemeEntity( + id = 2, + theme = "Theme Protection des espèces", + ) val controlPlanSubTheme1 = - ControlPlanSubThemeEntity( - id = 10, - themeId = 1, - subTheme = "SubTheme ZMEL", - year = 2024, - ) + ControlPlanSubThemeEntity( + id = 10, + themeId = 1, + subTheme = "SubTheme ZMEL", + year = 2024, + ) val controlPlanTag = - ControlPlanTagEntity( - id = 100, - themeId = 2, - tag = "Tag Bichique", - ) + ControlPlanTagEntity( + id = 100, + themeId = 2, + tag = "Tag Bichique", + ) val controlPlan = - Triple( - listOf(controlPlanTheme1, controlPlanTheme2), - listOf(controlPlanSubTheme1), - listOf(controlPlanTag), - ) + Triple( + listOf(controlPlanTheme1, controlPlanTheme2), + listOf(controlPlanSubTheme1), + listOf(controlPlanTag), + ) BDDMockito.given(getControlPlansByYear.execute(2024)).willReturn(controlPlan) // When mockMvc.perform(get("/bff/v1/control_plans/2024")) - // Then - .andExpect(status().isOk) - .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) - .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) - .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) - .andExpect( - jsonPath("$.subThemes[\"10\"].subTheme") - .value(controlPlanSubTheme1.subTheme), - ) - .andExpect( - jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId), - ) - .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) - .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) - .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.themes[\"1\"].id").value(controlPlanTheme1.id)) + .andExpect(jsonPath("$.subThemes[\"10\"].id").value(controlPlanSubTheme1.id)) + .andExpect( + jsonPath("$.subThemes[\"10\"].subTheme") + .value(controlPlanSubTheme1.subTheme), + ) + .andExpect( + jsonPath("$.subThemes[\"10\"].themeId").value(controlPlanSubTheme1.themeId), + ) + .andExpect(jsonPath("$.tags[\"100\"].id").value(controlPlanTag.id)) + .andExpect(jsonPath("$.tags[\"100\"].tag").value(controlPlanTag.tag)) + .andExpect(jsonPath("$.tags[\"100\"].themeId").value(controlPlanTag.themeId)) verify(getControlPlansByYear).execute(2024) } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt index 4b3af7d64..350d93e7c 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/bff/MissionsControllerITests.kt @@ -26,8 +26,6 @@ import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos.ReportingDTO import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions.CreateOrUpdateMissionDataInput import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.missions.MissionEnvActionDataInput -import java.time.ZonedDateTime -import java.util.* import org.hamcrest.Matchers.equalTo import org.junit.jupiter.api.Test import org.locationtech.jts.geom.MultiPolygon @@ -46,6 +44,8 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* import org.springframework.test.web.servlet.result.MockMvcResultHandlers import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import java.time.ZonedDateTime +import java.util.* @Import(WebSecurityConfig::class, MapperConfiguration::class) @WebMvcTest(value = [(MissionsController::class)]) @@ -55,7 +55,7 @@ class MissionsControllerITests { @MockBean private lateinit var createOrUpdateMissionWithAttachedReporting: - CreateOrUpdateMissionWithAttachedReporting + CreateOrUpdateMissionWithAttachedReporting @MockBean private lateinit var getFullMissions: GetFullMissions @@ -68,67 +68,67 @@ class MissionsControllerITests { @Autowired private lateinit var objectMapper: ObjectMapper private val polygon = - WKTReader() - .read( - "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))", - ) as - MultiPolygon + WKTReader() + .read( + "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))", + ) as + MultiPolygon private val point = WKTReader().read("POINT (-4.54877816747593 48.305559876971)") as Point @Test fun `Should create a new mission`() { // Given val expectedNewMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - facade = "Outre-Mer", - geom = polygon, - observationsCacem = null, - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = - ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isDeleted = false, - isClosed = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ), - ) + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + facade = "Outre-Mer", + geom = polygon, + observationsCacem = null, + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = + ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isDeleted = false, + isClosed = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ), + ) val newMissionRequest = - CreateOrUpdateMissionDataInput( - missionTypes = listOf(MissionTypeEnum.LAND), - observationsCacem = null, - facade = "Outre-Mer", - geom = polygon, - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isClosed = false, - missionSource = MissionSourceEnum.MONITORENV, - attachedReportingIds = listOf(), - ) + CreateOrUpdateMissionDataInput( + missionTypes = listOf(MissionTypeEnum.LAND), + observationsCacem = null, + facade = "Outre-Mer", + geom = polygon, + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isClosed = false, + missionSource = MissionSourceEnum.MONITORENV, + attachedReportingIds = listOf(), + ) val requestbody = objectMapper.writeValueAsString(newMissionRequest) given( - createOrUpdateMissionWithAttachedReporting.execute( - mission = newMissionRequest.toMissionEntity(), - attachedReportingIds = listOf(), - envActionsAttachedToReportingIds = listOf(), - ), - ) - .willReturn(expectedNewMission) + createOrUpdateMissionWithAttachedReporting.execute( + mission = newMissionRequest.toMissionEntity(), + attachedReportingIds = listOf(), + envActionsAttachedToReportingIds = listOf(), + ), + ) + .willReturn(expectedNewMission) // When mockMvc.perform( - put("/bff/v1/missions") - .content(requestbody) - .contentType(MediaType.APPLICATION_JSON), - ) - // Then - .andDo(MockMvcResultHandlers.print()) - .andExpect(status().isOk) + put("/bff/v1/missions") + .content(requestbody) + .contentType(MediaType.APPLICATION_JSON), + ) + // Then + .andDo(MockMvcResultHandlers.print()) + .andExpect(status().isOk) } @Test @@ -136,332 +136,332 @@ class MissionsControllerITests { // Given val controlEnvAction = - EnvActionControlEntity( - id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - controlPlans = - listOf( - EnvActionControlPlanEntity( - subThemeIds = listOf(1), - tagIds = listOf(1, 2), - themeId = 1, - ), - ), - geom = point, - facade = "Outre-Mer", - department = "29", - isAdministrativeControl = false, - isComplianceWithWaterRegulationsControl = false, - isSafetyEquipmentAndStandardsComplianceControl = false, - isSeafarersControl = false, - themes = - listOf( - ThemeEntity( - theme = "Theme 1", - subThemes = listOf("sous theme 1", "sous theme 2"), - ), - ), - observations = "Observations de l'action de contrôle", - actionNumberOfControls = 2, - actionTargetType = ActionTargetTypeEnum.VEHICLE, - vehicleType = VehicleTypeEnum.VEHICLE_LAND, - infractions = - listOf( - InfractionEntity( - id = "d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b", - natinf = listOf("27001"), - observations = "Observations de l'infraction", - registrationNumber = "AB-123-CD", - companyName = "Company Name", - relevantCourt = "LOCAL_COURT", - infractionType = InfractionTypeEnum.WAITING, - formalNotice = FormalNoticeEnum.NO, - toProcess = false, - controlledPersonIdentity = "Captain Flame", - vesselType = VesselTypeEnum.COMMERCIAL, - vesselSize = VesselSizeEnum.FROM_12_TO_24m, - ), - ), - ) + EnvActionControlEntity( + id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + controlPlans = + listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(1), + tagIds = listOf(1, 2), + themeId = 1, + ), + ), + geom = point, + facade = "Outre-Mer", + department = "29", + isAdministrativeControl = false, + isComplianceWithWaterRegulationsControl = false, + isSafetyEquipmentAndStandardsComplianceControl = false, + isSeafarersControl = false, + themes = + listOf( + ThemeEntity( + theme = "Theme 1", + subThemes = listOf("sous theme 1", "sous theme 2"), + ), + ), + observations = "Observations de l'action de contrôle", + actionNumberOfControls = 2, + actionTargetType = ActionTargetTypeEnum.VEHICLE, + vehicleType = VehicleTypeEnum.VEHICLE_LAND, + infractions = + listOf( + InfractionEntity( + id = "d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b", + natinf = listOf("27001"), + observations = "Observations de l'infraction", + registrationNumber = "AB-123-CD", + companyName = "Company Name", + relevantCourt = "LOCAL_COURT", + infractionType = InfractionTypeEnum.WAITING, + formalNotice = FormalNoticeEnum.NO, + toProcess = false, + controlledPersonIdentity = "Captain Flame", + vesselType = VesselTypeEnum.COMMERCIAL, + vesselSize = VesselSizeEnum.FROM_12_TO_24m, + ), + ), + ) val expectedFirstMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.SEA), - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 1, - name = "CU1", - administration = "Admin 1", - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 2, - controlUnitId = - 1, - name = - "Ressource 2", - ), - ), - isArchived = false, - ), - ), - openBy = "OpenBy", - closedBy = "ClosedBy", - facade = "Outre-Mer", - geom = polygon, - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = - ZonedDateTime.parse("2022-01-23T20:29:03Z"), - observationsCacem = "obs cacem", - observationsCnsp = "obs cnsp", - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - envActions = listOf(controlEnvAction), + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.SEA), + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 1, + name = "CU1", + administration = "Admin 1", + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 2, + controlUnitId = + 1, + name = + "Ressource 2", ), - attachedReportingIds = listOf(1), - attachedReportings = - listOf( - ReportingDTO( - reporting = - ReportingEntity( - id = 1, - reportingId = 2300001, - sourceType = - SourceTypeEnum.SEMAPHORE, - semaphoreId = 1, - targetType = TargetTypeEnum.VEHICLE, - vehicleType = - VehicleTypeEnum - .VEHICLE_LAND, - geom = polygon, - seaFront = "SeaFront", - description = "Description", - reportType = - ReportingTypeEnum - .INFRACTION_SUSPICION, - themeId = 12, - subThemeIds = listOf(82), - actionTaken = "ActionTaken", - isControlRequired = true, - hasNoUnitAvailable = true, - createdAt = - ZonedDateTime.parse( - "2022-01-15T04:50:09Z", - ), - validityTime = 4, - isArchived = false, - isDeleted = false, - openBy = "OpenBy", - ), - semaphore = - SemaphoreEntity( - id = 1, - name = "Semaphore 1", - geom = point, - department = "29", - facade = "Outre-Mer", - administration = "Admin 1", - unit = "Unit 1", - email = "semaphore@", - phoneNumber = "0299999999", - base = "Base 1", - ), - ), - ), - ) + ), + isArchived = false, + ), + ), + openBy = "OpenBy", + closedBy = "ClosedBy", + facade = "Outre-Mer", + geom = polygon, + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = + ZonedDateTime.parse("2022-01-23T20:29:03Z"), + observationsCacem = "obs cacem", + observationsCnsp = "obs cnsp", + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + envActions = listOf(controlEnvAction), + ), + attachedReportingIds = listOf(1), + attachedReportings = + listOf( + ReportingDTO( + reporting = + ReportingEntity( + id = 1, + reportingId = 2300001, + sourceType = + SourceTypeEnum.SEMAPHORE, + semaphoreId = 1, + targetType = TargetTypeEnum.VEHICLE, + vehicleType = + VehicleTypeEnum + .VEHICLE_LAND, + geom = polygon, + seaFront = "SeaFront", + description = "Description", + reportType = + ReportingTypeEnum + .INFRACTION_SUSPICION, + themeId = 12, + subThemeIds = listOf(82), + actionTaken = "ActionTaken", + isControlRequired = true, + hasNoUnitAvailable = true, + createdAt = + ZonedDateTime.parse( + "2022-01-15T04:50:09Z", + ), + validityTime = 4, + isArchived = false, + isDeleted = false, + openBy = "OpenBy", + ), + semaphore = + SemaphoreEntity( + id = 1, + name = "Semaphore 1", + geom = point, + department = "29", + facade = "Outre-Mer", + administration = "Admin 1", + unit = "Unit 1", + email = "semaphore@", + phoneNumber = "0299999999", + base = "Base 1", + ), + ), + ), + ) given( - getFullMissions.execute( - startedAfterDateTime = null, - startedBeforeDateTime = null, - seaFronts = null, - missionSources = null, - missionTypes = null, - missionStatuses = null, - pageNumber = null, - pageSize = null, - ), - ) - .willReturn(listOf(expectedFirstMission)) + getFullMissions.execute( + startedAfterDateTime = null, + startedBeforeDateTime = null, + seaFronts = null, + missionSources = null, + missionTypes = null, + missionStatuses = null, + pageNumber = null, + pageSize = null, + ), + ) + .willReturn(listOf(expectedFirstMission)) // When mockMvc.perform(get("/bff/v1/missions")) - // Then - .andExpect(status().isOk) - .andDo(MockMvcResultHandlers.print()) - .andExpect(jsonPath("$.length()", equalTo(1))) - .andExpect(jsonPath("$[0].id", equalTo(10))) - .andExpect( - jsonPath("$[0].missionTypes[0]", equalTo(MissionTypeEnum.SEA.toString())), - ) - .andExpect(jsonPath("$[0].controlUnits[0].id", equalTo(1))) - .andExpect(jsonPath("$[0].openBy", equalTo("OpenBy"))) - .andExpect(jsonPath("$[0].closedBy", equalTo("ClosedBy"))) - .andExpect(jsonPath("$[0].facade", equalTo("Outre-Mer"))) - .andExpect(jsonPath("$[0].geom.type", equalTo("MultiPolygon"))) - .andExpect(jsonPath("$[0].startDateTimeUtc", equalTo("2022-01-15T04:50:09Z"))) - .andExpect(jsonPath("$[0].endDateTimeUtc", equalTo("2022-01-23T20:29:03Z"))) - .andExpect(jsonPath("$[0].observationsCacem", equalTo("obs cacem"))) - .andExpect(jsonPath("$[0].observationsCnsp", equalTo("obs cnsp"))) - .andExpect(jsonPath("$[0].isClosed", equalTo(false))) - .andExpect(jsonPath("$[0].isDeleted").doesNotExist()) - .andExpect( - jsonPath( - "$[0].missionSource", - equalTo(MissionSourceEnum.MONITORENV.toString()), - ), - ) - .andExpect(jsonPath("$[0].hasMissionOrder", equalTo(false))) - .andExpect(jsonPath("$[0].isUnderJdp", equalTo(false))) - .andExpect(jsonPath("$[0].attachedReportingIds", equalTo(listOf(1)))) - .andExpect(jsonPath("$[0].envActions.length()", equalTo(1))) - .andExpect( - jsonPath( - "$[0].envActions[0].id", - equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - ), - ) - .andExpect(jsonPath("$[0].envActions[0].actionType", equalTo("CONTROL"))) - .andExpect( - jsonPath( - "$[0].envActions[0].actionStartDateTimeUtc", - equalTo("2022-01-15T04:50:09Z"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].actionEndDateTimeUtc", - equalTo("2022-01-23T20:29:03Z"), - ), - ) - .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].themeId", equalTo(1))) - .andExpect( - jsonPath("$[0].envActions[0].controlPlans[0].subThemeIds[0]", equalTo(1)) - ) - .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].tagIds[0]", equalTo(1))) - .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].tagIds[1]", equalTo(2))) - .andExpect(jsonPath("$[0].envActions[0].geom.type", equalTo("Point"))) - .andExpect(jsonPath("$[0].envActions[0].facade", equalTo("Outre-Mer"))) - .andExpect(jsonPath("$[0].envActions[0].department", equalTo("29"))) - .andExpect(jsonPath("$[0].envActions[0].isAdministrativeControl", equalTo(false))) - .andExpect( - jsonPath( - "$[0].envActions[0].isComplianceWithWaterRegulationsControl", - equalTo(false), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].isSafetyEquipmentAndStandardsComplianceControl", - equalTo(false), - ), - ) - .andExpect(jsonPath("$[0].envActions[0].isSeafarersControl", equalTo(false))) - .andExpect(jsonPath("$[0].envActions[0].themes[0].theme", equalTo("Theme 1"))) - .andExpect( - jsonPath( - "$[0].envActions[0].themes[0].subThemes[0]", - equalTo("sous theme 1"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].themes[0].subThemes[1]", - equalTo("sous theme 2"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].observations", - equalTo("Observations de l'action de contrôle"), - ), - ) - .andExpect(jsonPath("$[0].envActions[0].actionNumberOfControls", equalTo(2))) - .andExpect( - jsonPath( - "$[0].envActions[0].actionTargetType", - equalTo(ActionTargetTypeEnum.VEHICLE.toString()), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].vehicleType", - equalTo(VehicleTypeEnum.VEHICLE_LAND.toString()), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].id", - equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - ), - ) - .andExpect( - jsonPath("$[0].envActions[0].infractions[0].natinf[0]", equalTo("27001")), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].observations", - equalTo("Observations de l'infraction"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].registrationNumber", - equalTo("AB-123-CD"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].companyName", - equalTo("Company Name"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].relevantCourt", - equalTo("LOCAL_COURT"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].infractionType", - equalTo(InfractionTypeEnum.WAITING.toString()), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].formalNotice", - equalTo(FormalNoticeEnum.NO.toString()), - ), - ) - .andExpect(jsonPath("$[0].envActions[0].infractions[0].toProcess", equalTo(false))) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].controlledPersonIdentity", - equalTo("Captain Flame"), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].vesselType", - equalTo(VesselTypeEnum.COMMERCIAL.toString()), - ), - ) - .andExpect( - jsonPath( - "$[0].envActions[0].infractions[0].vesselSize", - equalTo(VesselSizeEnum.FROM_12_TO_24m.toString()), - ), - ) + // Then + .andExpect(status().isOk) + .andDo(MockMvcResultHandlers.print()) + .andExpect(jsonPath("$.length()", equalTo(1))) + .andExpect(jsonPath("$[0].id", equalTo(10))) + .andExpect( + jsonPath("$[0].missionTypes[0]", equalTo(MissionTypeEnum.SEA.toString())), + ) + .andExpect(jsonPath("$[0].controlUnits[0].id", equalTo(1))) + .andExpect(jsonPath("$[0].openBy", equalTo("OpenBy"))) + .andExpect(jsonPath("$[0].closedBy", equalTo("ClosedBy"))) + .andExpect(jsonPath("$[0].facade", equalTo("Outre-Mer"))) + .andExpect(jsonPath("$[0].geom.type", equalTo("MultiPolygon"))) + .andExpect(jsonPath("$[0].startDateTimeUtc", equalTo("2022-01-15T04:50:09Z"))) + .andExpect(jsonPath("$[0].endDateTimeUtc", equalTo("2022-01-23T20:29:03Z"))) + .andExpect(jsonPath("$[0].observationsCacem", equalTo("obs cacem"))) + .andExpect(jsonPath("$[0].observationsCnsp", equalTo("obs cnsp"))) + .andExpect(jsonPath("$[0].isClosed", equalTo(false))) + .andExpect(jsonPath("$[0].isDeleted").doesNotExist()) + .andExpect( + jsonPath( + "$[0].missionSource", + equalTo(MissionSourceEnum.MONITORENV.toString()), + ), + ) + .andExpect(jsonPath("$[0].hasMissionOrder", equalTo(false))) + .andExpect(jsonPath("$[0].isUnderJdp", equalTo(false))) + .andExpect(jsonPath("$[0].attachedReportingIds", equalTo(listOf(1)))) + .andExpect(jsonPath("$[0].envActions.length()", equalTo(1))) + .andExpect( + jsonPath( + "$[0].envActions[0].id", + equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + ), + ) + .andExpect(jsonPath("$[0].envActions[0].actionType", equalTo("CONTROL"))) + .andExpect( + jsonPath( + "$[0].envActions[0].actionStartDateTimeUtc", + equalTo("2022-01-15T04:50:09Z"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].actionEndDateTimeUtc", + equalTo("2022-01-23T20:29:03Z"), + ), + ) + .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].themeId", equalTo(1))) + .andExpect( + jsonPath("$[0].envActions[0].controlPlans[0].subThemeIds[0]", equalTo(1)), + ) + .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].tagIds[0]", equalTo(1))) + .andExpect(jsonPath("$[0].envActions[0].controlPlans[0].tagIds[1]", equalTo(2))) + .andExpect(jsonPath("$[0].envActions[0].geom.type", equalTo("Point"))) + .andExpect(jsonPath("$[0].envActions[0].facade", equalTo("Outre-Mer"))) + .andExpect(jsonPath("$[0].envActions[0].department", equalTo("29"))) + .andExpect(jsonPath("$[0].envActions[0].isAdministrativeControl", equalTo(false))) + .andExpect( + jsonPath( + "$[0].envActions[0].isComplianceWithWaterRegulationsControl", + equalTo(false), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].isSafetyEquipmentAndStandardsComplianceControl", + equalTo(false), + ), + ) + .andExpect(jsonPath("$[0].envActions[0].isSeafarersControl", equalTo(false))) + .andExpect(jsonPath("$[0].envActions[0].themes[0].theme", equalTo("Theme 1"))) + .andExpect( + jsonPath( + "$[0].envActions[0].themes[0].subThemes[0]", + equalTo("sous theme 1"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].themes[0].subThemes[1]", + equalTo("sous theme 2"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].observations", + equalTo("Observations de l'action de contrôle"), + ), + ) + .andExpect(jsonPath("$[0].envActions[0].actionNumberOfControls", equalTo(2))) + .andExpect( + jsonPath( + "$[0].envActions[0].actionTargetType", + equalTo(ActionTargetTypeEnum.VEHICLE.toString()), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].vehicleType", + equalTo(VehicleTypeEnum.VEHICLE_LAND.toString()), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].id", + equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + ), + ) + .andExpect( + jsonPath("$[0].envActions[0].infractions[0].natinf[0]", equalTo("27001")), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].observations", + equalTo("Observations de l'infraction"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].registrationNumber", + equalTo("AB-123-CD"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].companyName", + equalTo("Company Name"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].relevantCourt", + equalTo("LOCAL_COURT"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].infractionType", + equalTo(InfractionTypeEnum.WAITING.toString()), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].formalNotice", + equalTo(FormalNoticeEnum.NO.toString()), + ), + ) + .andExpect(jsonPath("$[0].envActions[0].infractions[0].toProcess", equalTo(false))) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].controlledPersonIdentity", + equalTo("Captain Flame"), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].vesselType", + equalTo(VesselTypeEnum.COMMERCIAL.toString()), + ), + ) + .andExpect( + jsonPath( + "$[0].envActions[0].infractions[0].vesselSize", + equalTo(VesselSizeEnum.FROM_12_TO_24m.toString()), + ), + ) } @Test @@ -470,310 +470,310 @@ class MissionsControllerITests { val requestedId = 0 val controlEnvAction = - EnvActionControlEntity( - id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - controlPlans = - listOf( - EnvActionControlPlanEntity( - subThemeIds = listOf(1), - tagIds = listOf(1, 2), - themeId = 1, - ), - ), - geom = point, - facade = "Outre-Mer", - department = "29", - isAdministrativeControl = false, - isComplianceWithWaterRegulationsControl = false, - isSafetyEquipmentAndStandardsComplianceControl = false, - isSeafarersControl = false, - themes = - listOf( - ThemeEntity( - theme = "Theme 1", - subThemes = listOf("sous theme 1", "sous theme 2"), - ), - ), - observations = "Observations de l'action de contrôle", - actionNumberOfControls = 2, - actionTargetType = ActionTargetTypeEnum.VEHICLE, - vehicleType = VehicleTypeEnum.VEHICLE_LAND, - infractions = - listOf( - InfractionEntity( - id = "d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b", - natinf = listOf("27001"), - observations = "Observations de l'infraction", - registrationNumber = "AB-123-CD", - companyName = "Company Name", - relevantCourt = "LOCAL_COURT", - infractionType = InfractionTypeEnum.WAITING, - formalNotice = FormalNoticeEnum.NO, - toProcess = false, - controlledPersonIdentity = "Captain Flame", - vesselType = VesselTypeEnum.COMMERCIAL, - vesselSize = VesselSizeEnum.FROM_12_TO_24m, - ), - ), - ) + EnvActionControlEntity( + id = UUID.fromString("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + actionEndDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + controlPlans = + listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(1), + tagIds = listOf(1, 2), + themeId = 1, + ), + ), + geom = point, + facade = "Outre-Mer", + department = "29", + isAdministrativeControl = false, + isComplianceWithWaterRegulationsControl = false, + isSafetyEquipmentAndStandardsComplianceControl = false, + isSeafarersControl = false, + themes = + listOf( + ThemeEntity( + theme = "Theme 1", + subThemes = listOf("sous theme 1", "sous theme 2"), + ), + ), + observations = "Observations de l'action de contrôle", + actionNumberOfControls = 2, + actionTargetType = ActionTargetTypeEnum.VEHICLE, + vehicleType = VehicleTypeEnum.VEHICLE_LAND, + infractions = + listOf( + InfractionEntity( + id = "d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b", + natinf = listOf("27001"), + observations = "Observations de l'infraction", + registrationNumber = "AB-123-CD", + companyName = "Company Name", + relevantCourt = "LOCAL_COURT", + infractionType = InfractionTypeEnum.WAITING, + formalNotice = FormalNoticeEnum.NO, + toProcess = false, + controlledPersonIdentity = "Captain Flame", + vesselType = VesselTypeEnum.COMMERCIAL, + vesselSize = VesselSizeEnum.FROM_12_TO_24m, + ), + ), + ) val expectedFirstMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.SEA), - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 1, - name = "CU1", - administration = "Admin 1", - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 2, - controlUnitId = - 1, - name = - "Ressource 2", - ), - ), - isArchived = false, - ), - ), - openBy = "OpenBy", - closedBy = "ClosedBy", - facade = "Outre-Mer", - geom = polygon, - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = - ZonedDateTime.parse("2022-01-23T20:29:03Z"), - observationsCacem = "obs cacem", - observationsCnsp = "obs cnsp", - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - envActions = listOf(controlEnvAction), + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.SEA), + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 1, + name = "CU1", + administration = "Admin 1", + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 2, + controlUnitId = + 1, + name = + "Ressource 2", ), - attachedReportingIds = listOf(1), - attachedReportings = - listOf( - ReportingDTO( - reporting = - ReportingEntity( - id = 1, - reportingId = 2300001, - sourceType = - SourceTypeEnum.SEMAPHORE, - semaphoreId = 1, - targetType = TargetTypeEnum.VEHICLE, - vehicleType = - VehicleTypeEnum - .VEHICLE_LAND, - geom = polygon, - seaFront = "SeaFront", - description = "Description", - reportType = - ReportingTypeEnum - .INFRACTION_SUSPICION, - themeId = 12, - subThemeIds = listOf(82), - actionTaken = "ActionTaken", - isControlRequired = true, - hasNoUnitAvailable = true, - createdAt = - ZonedDateTime.parse( - "2022-01-15T04:50:09Z", - ), - validityTime = 4, - isArchived = false, - isDeleted = false, - openBy = "OpenBy", - ), - semaphore = - SemaphoreEntity( - id = 1, - name = "Semaphore 1", - geom = point, - department = "29", - facade = "Outre-Mer", - administration = "Admin 1", - unit = "Unit 1", - email = "semaphore@", - phoneNumber = "0299999999", - base = "Base 1", - ), - ), - ), - ) + ), + isArchived = false, + ), + ), + openBy = "OpenBy", + closedBy = "ClosedBy", + facade = "Outre-Mer", + geom = polygon, + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = + ZonedDateTime.parse("2022-01-23T20:29:03Z"), + observationsCacem = "obs cacem", + observationsCnsp = "obs cnsp", + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + envActions = listOf(controlEnvAction), + ), + attachedReportingIds = listOf(1), + attachedReportings = + listOf( + ReportingDTO( + reporting = + ReportingEntity( + id = 1, + reportingId = 2300001, + sourceType = + SourceTypeEnum.SEMAPHORE, + semaphoreId = 1, + targetType = TargetTypeEnum.VEHICLE, + vehicleType = + VehicleTypeEnum + .VEHICLE_LAND, + geom = polygon, + seaFront = "SeaFront", + description = "Description", + reportType = + ReportingTypeEnum + .INFRACTION_SUSPICION, + themeId = 12, + subThemeIds = listOf(82), + actionTaken = "ActionTaken", + isControlRequired = true, + hasNoUnitAvailable = true, + createdAt = + ZonedDateTime.parse( + "2022-01-15T04:50:09Z", + ), + validityTime = 4, + isArchived = false, + isDeleted = false, + openBy = "OpenBy", + ), + semaphore = + SemaphoreEntity( + id = 1, + name = "Semaphore 1", + geom = point, + department = "29", + facade = "Outre-Mer", + administration = "Admin 1", + unit = "Unit 1", + email = "semaphore@", + phoneNumber = "0299999999", + base = "Base 1", + ), + ), + ), + ) // we test only if the route is called with the right arg given(getFullMissionById.execute(requestedId)).willReturn(expectedFirstMission) // When mockMvc.perform(get("/bff/v1/missions/$requestedId")) - // Then - .andDo(MockMvcResultHandlers.print()) - .andExpect(status().isOk) - .andExpect(jsonPath("$.missionTypes[0]", equalTo(MissionTypeEnum.SEA.toString()))) - .andExpect(jsonPath("$.id", equalTo(10))) - .andExpect(jsonPath("$.controlUnits[0].id", equalTo(1))) - .andExpect(jsonPath("$.openBy", equalTo("OpenBy"))) - .andExpect(jsonPath("$.closedBy", equalTo("ClosedBy"))) - .andExpect(jsonPath("$.facade", equalTo("Outre-Mer"))) - .andExpect(jsonPath("$.geom.type", equalTo("MultiPolygon"))) - .andExpect(jsonPath("$.startDateTimeUtc", equalTo("2022-01-15T04:50:09Z"))) - .andExpect(jsonPath("$.endDateTimeUtc", equalTo("2022-01-23T20:29:03Z"))) - .andExpect(jsonPath("$.observationsCacem", equalTo("obs cacem"))) - .andExpect(jsonPath("$.observationsCnsp", equalTo("obs cnsp"))) - .andExpect(jsonPath("$.isClosed", equalTo(false))) - .andExpect(jsonPath("$.isDeleted").doesNotExist()) - .andExpect( - jsonPath( - "$.missionSource", - equalTo(MissionSourceEnum.MONITORENV.toString()), - ), - ) - .andExpect(jsonPath("$.hasMissionOrder", equalTo(false))) - .andExpect(jsonPath("$.isUnderJdp", equalTo(false))) - .andExpect(jsonPath("$.attachedReportingIds", equalTo(listOf(1)))) - .andExpect(jsonPath("$.envActions.length()", equalTo(1))) - .andExpect( - jsonPath( - "$.envActions[0].id", - equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - ), - ) - .andExpect(jsonPath("$.envActions[0].actionType", equalTo("CONTROL"))) - .andExpect( - jsonPath( - "$.envActions[0].actionStartDateTimeUtc", - equalTo("2022-01-15T04:50:09Z"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].actionEndDateTimeUtc", - equalTo("2022-01-23T20:29:03Z"), - ), - ) - .andExpect(jsonPath("$.envActions[0].controlPlans[0].themeId", equalTo(1))) - .andExpect(jsonPath("$.envActions[0].controlPlans[0].subThemeIds[0]", equalTo(1))) - .andExpect(jsonPath("$.envActions[0].controlPlans[0].tagIds[0]", equalTo(1))) - .andExpect(jsonPath("$.envActions[0].controlPlans[0].tagIds[1]", equalTo(2))) - .andExpect(jsonPath("$.envActions[0].geom.type", equalTo("Point"))) - .andExpect(jsonPath("$.envActions[0].facade", equalTo("Outre-Mer"))) - .andExpect(jsonPath("$.envActions[0].department", equalTo("29"))) - .andExpect(jsonPath("$.envActions[0].isAdministrativeControl", equalTo(false))) - .andExpect( - jsonPath( - "$.envActions[0].isComplianceWithWaterRegulationsControl", - equalTo(false), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].isSafetyEquipmentAndStandardsComplianceControl", - equalTo(false), - ), - ) - .andExpect(jsonPath("$.envActions[0].isSeafarersControl", equalTo(false))) - .andExpect(jsonPath("$.envActions[0].themes[0].theme", equalTo("Theme 1"))) - .andExpect( - jsonPath("$.envActions[0].themes[0].subThemes[0]", equalTo("sous theme 1")), - ) - .andExpect( - jsonPath("$.envActions[0].themes[0].subThemes[1]", equalTo("sous theme 2")), - ) - .andExpect( - jsonPath( - "$.envActions[0].observations", - equalTo("Observations de l'action de contrôle"), - ), - ) - .andExpect(jsonPath("$.envActions[0].actionNumberOfControls", equalTo(2))) - .andExpect( - jsonPath( - "$.envActions[0].actionTargetType", - equalTo(ActionTargetTypeEnum.VEHICLE.toString()), - ), - ) - .andExpect(jsonPath("$.envActions[0].reportingIds.length()", equalTo(0))) - .andExpect( - jsonPath( - "$.envActions[0].vehicleType", - equalTo(VehicleTypeEnum.VEHICLE_LAND.toString()), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].id", - equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), - ), - ) - .andExpect(jsonPath("$.envActions[0].infractions[0].natinf[0]", equalTo("27001"))) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].observations", - equalTo("Observations de l'infraction"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].registrationNumber", - equalTo("AB-123-CD"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].companyName", - equalTo("Company Name"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].relevantCourt", - equalTo("LOCAL_COURT"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].infractionType", - equalTo(InfractionTypeEnum.WAITING.toString()), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].formalNotice", - equalTo(FormalNoticeEnum.NO.toString()), - ), - ) - .andExpect(jsonPath("$.envActions[0].infractions[0].toProcess", equalTo(false))) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].controlledPersonIdentity", - equalTo("Captain Flame"), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].vesselType", - equalTo(VesselTypeEnum.COMMERCIAL.toString()), - ), - ) - .andExpect( - jsonPath( - "$.envActions[0].infractions[0].vesselSize", - equalTo(VesselSizeEnum.FROM_12_TO_24m.toString()), - ), - ) + // Then + .andDo(MockMvcResultHandlers.print()) + .andExpect(status().isOk) + .andExpect(jsonPath("$.missionTypes[0]", equalTo(MissionTypeEnum.SEA.toString()))) + .andExpect(jsonPath("$.id", equalTo(10))) + .andExpect(jsonPath("$.controlUnits[0].id", equalTo(1))) + .andExpect(jsonPath("$.openBy", equalTo("OpenBy"))) + .andExpect(jsonPath("$.closedBy", equalTo("ClosedBy"))) + .andExpect(jsonPath("$.facade", equalTo("Outre-Mer"))) + .andExpect(jsonPath("$.geom.type", equalTo("MultiPolygon"))) + .andExpect(jsonPath("$.startDateTimeUtc", equalTo("2022-01-15T04:50:09Z"))) + .andExpect(jsonPath("$.endDateTimeUtc", equalTo("2022-01-23T20:29:03Z"))) + .andExpect(jsonPath("$.observationsCacem", equalTo("obs cacem"))) + .andExpect(jsonPath("$.observationsCnsp", equalTo("obs cnsp"))) + .andExpect(jsonPath("$.isClosed", equalTo(false))) + .andExpect(jsonPath("$.isDeleted").doesNotExist()) + .andExpect( + jsonPath( + "$.missionSource", + equalTo(MissionSourceEnum.MONITORENV.toString()), + ), + ) + .andExpect(jsonPath("$.hasMissionOrder", equalTo(false))) + .andExpect(jsonPath("$.isUnderJdp", equalTo(false))) + .andExpect(jsonPath("$.attachedReportingIds", equalTo(listOf(1)))) + .andExpect(jsonPath("$.envActions.length()", equalTo(1))) + .andExpect( + jsonPath( + "$.envActions[0].id", + equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + ), + ) + .andExpect(jsonPath("$.envActions[0].actionType", equalTo("CONTROL"))) + .andExpect( + jsonPath( + "$.envActions[0].actionStartDateTimeUtc", + equalTo("2022-01-15T04:50:09Z"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].actionEndDateTimeUtc", + equalTo("2022-01-23T20:29:03Z"), + ), + ) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].themeId", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].subThemeIds[0]", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].tagIds[0]", equalTo(1))) + .andExpect(jsonPath("$.envActions[0].controlPlans[0].tagIds[1]", equalTo(2))) + .andExpect(jsonPath("$.envActions[0].geom.type", equalTo("Point"))) + .andExpect(jsonPath("$.envActions[0].facade", equalTo("Outre-Mer"))) + .andExpect(jsonPath("$.envActions[0].department", equalTo("29"))) + .andExpect(jsonPath("$.envActions[0].isAdministrativeControl", equalTo(false))) + .andExpect( + jsonPath( + "$.envActions[0].isComplianceWithWaterRegulationsControl", + equalTo(false), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].isSafetyEquipmentAndStandardsComplianceControl", + equalTo(false), + ), + ) + .andExpect(jsonPath("$.envActions[0].isSeafarersControl", equalTo(false))) + .andExpect(jsonPath("$.envActions[0].themes[0].theme", equalTo("Theme 1"))) + .andExpect( + jsonPath("$.envActions[0].themes[0].subThemes[0]", equalTo("sous theme 1")), + ) + .andExpect( + jsonPath("$.envActions[0].themes[0].subThemes[1]", equalTo("sous theme 2")), + ) + .andExpect( + jsonPath( + "$.envActions[0].observations", + equalTo("Observations de l'action de contrôle"), + ), + ) + .andExpect(jsonPath("$.envActions[0].actionNumberOfControls", equalTo(2))) + .andExpect( + jsonPath( + "$.envActions[0].actionTargetType", + equalTo(ActionTargetTypeEnum.VEHICLE.toString()), + ), + ) + .andExpect(jsonPath("$.envActions[0].reportingIds.length()", equalTo(0))) + .andExpect( + jsonPath( + "$.envActions[0].vehicleType", + equalTo(VehicleTypeEnum.VEHICLE_LAND.toString()), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].id", + equalTo("d0f5f3a0-0b1a-4b0e-9b0a-0b0b0b0b0b0b"), + ), + ) + .andExpect(jsonPath("$.envActions[0].infractions[0].natinf[0]", equalTo("27001"))) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].observations", + equalTo("Observations de l'infraction"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].registrationNumber", + equalTo("AB-123-CD"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].companyName", + equalTo("Company Name"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].relevantCourt", + equalTo("LOCAL_COURT"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].infractionType", + equalTo(InfractionTypeEnum.WAITING.toString()), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].formalNotice", + equalTo(FormalNoticeEnum.NO.toString()), + ), + ) + .andExpect(jsonPath("$.envActions[0].infractions[0].toProcess", equalTo(false))) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].controlledPersonIdentity", + equalTo("Captain Flame"), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].vesselType", + equalTo(VesselTypeEnum.COMMERCIAL.toString()), + ), + ) + .andExpect( + jsonPath( + "$.envActions[0].infractions[0].vesselSize", + equalTo(VesselSizeEnum.FROM_12_TO_24m.toString()), + ), + ) verify(getFullMissionById).execute(requestedId) } @@ -782,71 +782,71 @@ class MissionsControllerITests { fun `update mission should return updated mission`() { // Given val expectedUpdatedMission = - MissionDTO( - mission = - MissionEntity( - id = 14, - missionTypes = listOf(MissionTypeEnum.SEA), - observationsCacem = "updated observationsCacem", - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ), - ) + MissionDTO( + mission = + MissionEntity( + id = 14, + missionTypes = listOf(MissionTypeEnum.SEA), + observationsCacem = "updated observationsCacem", + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ), + ) val envAction = - MissionEnvActionDataInput( - id = UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), - actionType = ActionTypeEnum.CONTROL, - actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - actionTargetType = ActionTargetTypeEnum.VEHICLE, - vehicleType = VehicleTypeEnum.VESSEL, - actionNumberOfControls = 4, - reportingIds = Optional.of(listOf(1)), - ) + MissionEnvActionDataInput( + id = UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), + actionType = ActionTypeEnum.CONTROL, + actionStartDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + actionTargetType = ActionTargetTypeEnum.VEHICLE, + vehicleType = VehicleTypeEnum.VESSEL, + actionNumberOfControls = 4, + reportingIds = Optional.of(listOf(1)), + ) val requestBody = - CreateOrUpdateMissionDataInput( - id = 14, - missionTypes = listOf(MissionTypeEnum.SEA), - observationsCacem = "updated observationsCacem", - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - envActions = listOf(envAction), - missionSource = MissionSourceEnum.MONITORENV, - isClosed = false, - attachedReportingIds = listOf(1), - ) + CreateOrUpdateMissionDataInput( + id = 14, + missionTypes = listOf(MissionTypeEnum.SEA), + observationsCacem = "updated observationsCacem", + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + envActions = listOf(envAction), + missionSource = MissionSourceEnum.MONITORENV, + isClosed = false, + attachedReportingIds = listOf(1), + ) val envActionsAttachedToReportingIds = - listOf( - Pair(UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), listOf(1)), - ) as - List<EnvActionAttachedToReportingIds> + listOf( + Pair(UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), listOf(1)), + ) as + List<EnvActionAttachedToReportingIds> given( - createOrUpdateMissionWithAttachedReporting.execute( - mission = requestBody.toMissionEntity(), - attachedReportingIds = listOf(1), - envActionsAttachedToReportingIds = envActionsAttachedToReportingIds, - ), - ) - .willReturn(expectedUpdatedMission) + createOrUpdateMissionWithAttachedReporting.execute( + mission = requestBody.toMissionEntity(), + attachedReportingIds = listOf(1), + envActionsAttachedToReportingIds = envActionsAttachedToReportingIds, + ), + ) + .willReturn(expectedUpdatedMission) // When mockMvc.perform( - put("/bff/v1/missions/14") - .content(objectMapper.writeValueAsString(requestBody)) - .contentType(MediaType.APPLICATION_JSON), - ) - // Then - .andExpect(status().isOk) - .andExpect( - jsonPath( - "$.observationsCacem", - equalTo(expectedUpdatedMission.mission.observationsCacem), - ), - ) + put("/bff/v1/missions/14") + .content(objectMapper.writeValueAsString(requestBody)) + .contentType(MediaType.APPLICATION_JSON), + ) + // Then + .andExpect(status().isOk) + .andExpect( + jsonPath( + "$.observationsCacem", + equalTo(expectedUpdatedMission.mission.observationsCacem), + ), + ) } @Test @@ -854,8 +854,8 @@ class MissionsControllerITests { // Given // When mockMvc.perform(delete("/bff/v1/missions/20")) - // Then - .andExpect(status().isOk) + // Then + .andExpect(status().isOk) Mockito.verify(deleteMission).execute(20) } @@ -863,26 +863,26 @@ class MissionsControllerITests { fun `Should get all engaged control units`() { // Given given(getEngagedControlUnits.execute()) - .willReturn( - listOf( - Pair( - LegacyControlUnitEntity( - id = 123, - administration = "Admin", - resources = listOf(), - isArchived = false, - name = "Control Unit Name", - ), - listOf(MissionSourceEnum.MONITORFISH), - ), - ), - ) + .willReturn( + listOf( + Pair( + LegacyControlUnitEntity( + id = 123, + administration = "Admin", + resources = listOf(), + isArchived = false, + name = "Control Unit Name", + ), + listOf(MissionSourceEnum.MONITORFISH), + ), + ), + ) // When mockMvc.perform(get("/bff/v1/missions/engaged_control_units")) - // Then - .andExpect(status().isOk) - .andExpect(jsonPath("$[0].controlUnit.name", equalTo("Control Unit Name"))) - .andExpect(jsonPath("$[0].missionSources[0]", equalTo("MONITORFISH"))) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$[0].controlUnit.name", equalTo("Control Unit Name"))) + .andExpect(jsonPath("$[0].missionSources[0]", equalTo("MONITORFISH"))) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt index d30ad986e..508abe92b 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt @@ -13,13 +13,13 @@ class JpaControlPlanSubThemeRepositoryITests : AbstractDBTests() { // When val requestedControlPlanSubThemes = jpaControlPlanSubThemeRepository.findAll() // Then - assertThat(requestedControlPlanSubThemes.size).isEqualTo(89) + assertThat(requestedControlPlanSubThemes.size).isEqualTo(95) assertThat(requestedControlPlanSubThemes[5].id).isEqualTo(6) assertThat(requestedControlPlanSubThemes[5].themeId).isEqualTo(4) assertThat(requestedControlPlanSubThemes[5].subTheme) - .isEqualTo( - "Atteinte aux biens culturels", - ) + .isEqualTo( + "Atteinte aux biens culturels", + ) assertThat(requestedControlPlanSubThemes[5].year).isEqualTo(2023) } @@ -34,9 +34,9 @@ class JpaControlPlanSubThemeRepositoryITests : AbstractDBTests() { assertThat(requestedControlPlanSubThemesFor2024[5].id).isEqualTo(6) assertThat(requestedControlPlanSubThemesFor2024[5].themeId).isEqualTo(11) assertThat(requestedControlPlanSubThemesFor2024[5].subTheme) - .isEqualTo( - "Destruction, capture, arrachage", - ) + .isEqualTo( + "Destruction, capture, arrachage", + ) assertThat(requestedControlPlanSubThemesFor2024[5].year).isEqualTo(2024) } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt index c7e2d2edd..1ddd04a4d 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt @@ -28,12 +28,12 @@ class JpaControlPlanTagRepositoryITests : AbstractDBTests() { val requestedControlPlanTagsFor2024 = jpaControlPlanTagRepository.findByYear(2024) // Then assertThat(requestedControlPlanTagsFor2023.size).isEqualTo(48) - assertThat(requestedControlPlanTagsFor2024.size).isEqualTo(6) - assertThat(requestedControlPlanTagsFor2024[5].id).isEqualTo(6) + assertThat(requestedControlPlanTagsFor2024.size).isEqualTo(18) + assertThat(requestedControlPlanTagsFor2024[5].id).isEqualTo(2) assertThat(requestedControlPlanTagsFor2024[5].themeId).isEqualTo(11) assertThat(requestedControlPlanTagsFor2024[5].tag) .isEqualTo( - "Mammifères marins", + "Habitat", ) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt index 4ade9340b..8c9d912e5 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaMissionRepositoryITests.kt @@ -13,8 +13,6 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionContr import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.EnvActionControlEntity import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.envActionControl.infraction.* import fr.gouv.cacem.monitorenv.domain.use_cases.missions.dtos.MissionDTO -import java.time.ZonedDateTime -import java.util.* import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.catchThrowable import org.junit.jupiter.api.Test @@ -27,6 +25,8 @@ import org.springframework.dao.InvalidDataAccessApiUsageException import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Pageable import org.springframework.transaction.annotation.Transactional +import java.time.ZonedDateTime +import java.util.* class JpaMissionRepositoryITests : AbstractDBTests() { @Autowired private lateinit var jpaMissionRepository: JpaMissionRepository @@ -36,12 +36,9 @@ class JpaMissionRepositoryITests : AbstractDBTests() { @Autowired private lateinit var jpaControlUnitResourceRepository: JpaControlUnitResourceRepository - private val polygon = - WKTReader() - .read( - "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))", - ) as - MultiPolygon + private val polygon = WKTReader().read( + "MULTIPOLYGON (((-4.54877817 48.30555988, -4.54997332 48.30597601, -4.54998501 48.30718823, -4.5487929 48.30677461, -4.54877817 48.30555988)))", + ) as MultiPolygon private val point = WKTReader().read("POINT (-4.54877816747593 48.305559876971)") as Point @Test @@ -49,14 +46,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `delete Should set the deleted flag as true`() { // Given val missionsList = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missionsList).hasSize(21) // When @@ -64,14 +61,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { // Then val nextMissionList = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(nextMissionList).hasSize(20) } @@ -80,14 +77,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return all missions when only required startedAfter is set to a very old date`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(54) } @@ -96,14 +93,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when startedAfter & startedBefore are set`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(21) } @@ -112,14 +109,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when missionTypes is set`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = listOf("SEA"), - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = listOf("SEA"), + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(22) } @@ -128,14 +125,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when multiple missionTypes are set`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = listOf("SEA", "LAND"), - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = listOf("SEA", "LAND"), + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(45) } @@ -144,14 +141,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when seaFront is set to MEMN`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = listOf("MEMN"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = listOf("MEMN"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(9) } @@ -160,14 +157,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when seaFront is set to MEMN and NAMO`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = listOf("MEMN", "NAMO"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = listOf("MEMN", "NAMO"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(27) } @@ -176,14 +173,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when status is set to UPCOMING`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("UPCOMING"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("UPCOMING"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(7) } @@ -192,14 +189,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when status is set to PENDING`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("PENDING"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("PENDING"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(14) } @@ -208,14 +205,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when status is set to ENDED`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("ENDED"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("ENDED"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(15) } @@ -224,14 +221,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when status is set to CLOSED`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("CLOSED"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("CLOSED"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(18) } @@ -240,14 +237,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll Should return filtered missions when status is set to CLOSED or UPCOMING`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("CLOSED", "UPCOMING"), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + seaFronts = null, + missionStatuses = listOf("CLOSED", "UPCOMING"), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(25) } @@ -256,14 +253,14 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll with pagenumber and pagesize Should return subset of missions`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = PageRequest.of(1, 10), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = PageRequest.of(1, 10), + ) assertThat(missions).hasSize(10) } @@ -272,265 +269,20 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findAll should filter missions based on MissionSources`() { // When val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = null, - missionSources = - listOf( - MissionSourceEnum.MONITORFISH, - MissionSourceEnum.POSEIDON_CACEM, - MissionSourceEnum.POSEIDON_CNSP, - ), - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(3) - } - - @Test - @Transactional - fun `delete Should set the deleted flag as true`() { - // Given - val missionsList = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) - assertThat(missionsList).hasSize(21) - - // When - jpaMissionRepository.delete(3) - - // Then - val nextMissionList = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) - assertThat(nextMissionList).hasSize(20) - } - - @Test - @Transactional - fun `findAll Should return all missions when only required startedAfter is set to a very old date`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(53) - } - - @Test - @Transactional - fun `findAll Should return filtered missions when startedAfter & startedBefore are set`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(21) - } - - @Test - @Transactional - fun `findAll Should return filtered missions when missionTypes is set`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = listOf("SEA"), - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(21) - } - - @Test - @Transactional - fun `findAll Should return filtered missions when multiple missionTypes are set`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = listOf("SEA", "LAND"), - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(44) - } - - @Test - @Transactional - fun `findAll Should return filtered missions when seaFront is set to MEMN`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = listOf("MEMN"), - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(9) - } - - @Test - @Transactional - fun `findAll Should return filtered missions when seaFront is set to MEMN and NAMO`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = listOf("MEMN", "NAMO"), - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(26) - } - - @Test - @Transactional - fun `findAll Should return filtered missions when status is set to UPCOMING`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("UPCOMING"), - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(6) - } - - @Test - @Transactional - fun `findAll Should return filtered missions when status is set to PENDING`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("PENDING"), - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(14) - } - - @Test - @Transactional - fun `findAll Should return filtered missions when status is set to ENDED`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("ENDED"), - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(15) - } - - @Test - @Transactional - fun `findAll Should return filtered missions when status is set to CLOSED`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("CLOSED"), - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(18) - } - - @Test - @Transactional - fun `findAll Should return filtered missions when status is set to CLOSED or UPCOMING`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - seaFronts = null, - missionStatuses = listOf("CLOSED", "UPCOMING"), - pageable = Pageable.unpaged(), - ) - assertThat(missions).hasSize(24) - } - - @Test - @Transactional - fun `findAll with pagenumber and pagesize Should return subset of missions`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = PageRequest.of(1, 10), - ) - assertThat(missions).hasSize(10) - } - - @Test - @Transactional - fun `findAll should filter missions based on MissionSources`() { - // When - val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), - startedBefore = null, - missionTypes = null, - missionStatuses = null, - seaFronts = null, - missionSources = - listOf( - MissionSourceEnum.MONITORFISH, - MissionSourceEnum.POSEIDON_CACEM, - MissionSourceEnum.POSEIDON_CNSP, - ), - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2000-01-01T00:01:00Z").toInstant(), + startedBefore = null, + missionTypes = null, + missionStatuses = null, + seaFronts = null, + missionSources = + listOf( + MissionSourceEnum.MONITORFISH, + MissionSourceEnum.POSEIDON_CACEM, + MissionSourceEnum.POSEIDON_CNSP, + ), + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(3) } @@ -555,154 +307,62 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `findById Should return specified mission`() { // When val firstMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - openBy = "KIM", - closedBy = "TRA", - facade = "NAMO", - observationsCacem = - "Remain vote several ok. Bring American play woman challenge. Throw low law positive seven.", - startDateTimeUtc = - ZonedDateTime.parse("2022-03-21T12:11:13Z"), - endDateTimeUtc = null, - geom = polygon, - isClosed = false, - isDeleted = false, - envActions = listOf(), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10002, - administration = "DDTM", - isArchived = false, - name = "DML 2A", - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 3, - controlUnitId = - 10002, - name = - "Semi-rigide 1", - ), - LegacyControlUnitResourceEntity( - id = 4, - controlUnitId = - 10002, - name = - "Semi-rigide 2", - ), - LegacyControlUnitResourceEntity( - id = 5, - controlUnitId = - 10002, - name = - "Voiture", - ), - ), - ), - ), - isGeometryComputedFromControls = false, + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + openBy = "KIM", + closedBy = "TRA", + facade = "NAMO", + observationsCacem = + "Remain vote several ok. Bring American play woman challenge. Throw low law positive seven.", + startDateTimeUtc = + ZonedDateTime.parse("2022-03-21T12:11:13Z"), + endDateTimeUtc = null, + geom = polygon, + isClosed = false, + isDeleted = false, + envActions = listOf(), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10002, + administration = "DDTM", + isArchived = false, + name = "DML 2A", + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 3, + controlUnitId = + 10002, + name = + "Semi-rigide 1", ), - ) - val mission = jpaMissionRepository.findFullMissionById(10) - - assertThat(mission).isEqualTo(firstMission) - } - - @Test - @Transactional - fun `findById Should return specified mission and associated env actions and associated envActionReportingIds`() { - // When - val missionDTO = jpaMissionRepository.findFullMissionById(34) - assertThat(missionDTO.mission.id).isEqualTo(34) - assertThat(missionDTO.mission.envActions).hasSize(2) - assertThat( - missionDTO.envActionsAttachedToReportingIds?.get(0)?.first, - ) - .isEqualTo(UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807")) - assertThat(missionDTO.envActionsAttachedToReportingIds?.get(0)?.second).isEqualTo(listOf(6)) - } - - @Test - @Transactional - fun `findByIds() should find the matching missions`() { - val foundMissions = jpaMissionRepository.findByIds(listOf(50, 51, 52)) - - assertThat(foundMissions).hasSize(3) - } - - @Test - @Transactional - fun `findById Should return specified mission`() { - // When - val wktReader = WKTReader() - val multipolygonString = - "MULTIPOLYGON (((-4.99360539 48.42853215, -4.99359905 48.42848997, -4.99359291 48.42844777, -4.99358697 48.42840556, -4.99358123 48.42836334, -4.99357569 48.4283211, -4.99357035 48.42827886, -4.9935652 48.4282366, -4.99356026 48.42819434, -4.99355552 48.42815206, -4.99355097 48.42810977, -4.99354663 48.42806748, -4.99354249 48.42802517, -4.99353854 48.42798286, -4.9935348 48.42794054, -4.99353125 48.42789821, -4.99352791 48.42785587, -4.99352476 48.42781353, -4.99352182 48.42777118, -4.99351907 48.42772882, -4.99351653 48.42768646, -4.99351418 48.4276441, -4.99351203 48.42760173, -4.99351009 48.42755935, -4.99350834 48.42751697, -4.9935068 48.42747459, -4.99350545 48.42743221, -4.99350431 48.42738982, -4.99350336 48.42734743, -4.99350262 48.42730504, -4.99350207 48.42726264, -4.99350173 48.42722025, -4.99350158 48.42717785, -4.99350164 48.42713546, -4.99350189 48.42709307, -4.99350235 48.42705067, -4.99350301 48.42700828, -4.99350386 48.42696589, -4.99350492 48.4269235, -4.99350617 48.42688111, -4.99350763 48.42683873, -4.99350929 48.42679635, -4.99351114 48.42675397, -4.9935132 48.4267116, -4.99351545 48.42666923, -4.99351791 48.42662687, -4.99352057 48.42658451, -4.99352342 48.42654216, -4.99352648 48.42649981, -4.99352973 48.42645747, -4.99353319 48.42641514, -4.99353685 48.42637282, -4.9935407 48.4263305, -4.99354476 48.42628819, -4.99354901 48.42624589, -4.99355346 48.4262036, -4.99355812 48.42616132, -4.99356297 48.42611905, -4.99356802 48.42607679, -4.99357328 48.42603454, -4.99357873 48.4259923, -4.99358438 48.42595007, -4.99359023 48.42590785, -4.99359628 48.42586565, -4.99360253 48.42582346, -4.99360898 48.42578128, -4.99361562 48.42573912, -4.99362247 48.42569697, -4.99362951 48.42565484, -4.99363676 48.42561272, -4.9936442 48.42557061, -4.99365184 48.42552853, -4.99365968 48.42548645, -4.99366772 48.4254444, -4.99367596 48.42540236, -4.99368439 48.42536034, -4.99369302 48.42531833, -4.99370186 48.42527635, -4.99371089 48.42523438, -4.99372011 48.42519243, -4.99372954 48.42515051, -4.99373916 48.4251086, -4.99374898 48.42506671, -4.993759 48.42502484, -4.99376922 48.424983, -4.99377963 48.42494117, -4.99379024 48.42489937, -4.99380105 48.42485759, -4.99381206 48.42481583, -4.99382326 48.4247741, -4.99383466 48.42473239, -4.99384626 48.4246907, -4.99385805 48.42464904, -4.99387004 48.42460741, -4.99388223 48.42456579, -4.99389461 48.42452421, -4.99390719 48.42448265, -4.99391996 48.42444111, -4.99393293 48.42439961, -4.9939461 48.42435813, -4.99395946 48.42431668, -4.99397302 48.42427525, -4.99398677 48.42423386, -4.99400072 48.42419249, -4.99401487 48.42415116, -4.9940292 48.42410985, -4.99404374 48.42406857, -4.99405847 48.42402733, -4.99407339 48.42398611, -4.99408851 48.42394493, -4.99410382 48.42390378, -4.99411932 48.42386266, -4.99413502 48.42382157, -4.99415092 48.42378052, -4.994167 48.4237395, -4.99418328 48.42369851, -4.99419976 48.42365756, -4.99421643 48.42361664, -4.99423329 48.42357576, -4.99425034 48.42353491, -4.99426759 48.4234941, -4.99428502 48.42345333, -4.99430265 48.42341259, -4.99432048 48.42337189, -4.99433849 48.42333122, -4.9943567 48.4232906, -4.9943751 48.42325001, -4.99439369 48.42320946, -4.99441247 48.42316895, -4.99443144 48.42312848, -4.9944506 48.42308805, -4.99446996 48.42304766, -4.9944895 48.42300731, -4.99450924 48.422967, -4.99452916 48.42292673, -4.99454928 48.42288651, -4.99456958 48.42284633, -4.99459007 48.42280619, -4.99461076 48.42276609, -4.99463163 48.42272603, -4.99465269 48.42268602, -4.99467394 48.42264606, -4.99469538 48.42260614, -4.99471701 48.42256626, -4.99473882 48.42252643, -4.99476082 48.42248665, -4.99478301 48.42244691, -4.99480539 48.42240721, -4.99482796 48.42236757, -4.99485071 48.42232797, -4.99487365 48.42228842, -4.99489677 48.42224892, -4.99492008 48.42220947, -4.99494358 48.42217006, -4.99496727 48.42213071, -4.99499113 48.4220914, -4.99501519 48.42205215, -4.99503943 48.42201294, -4.99506385 48.42197379, -4.99508846 48.42193469, -4.99511326 48.42189563, -4.99513823 48.42185664, -4.99516339 48.42181769, -4.99518874 48.4217788, -4.99521427 48.42173995, -4.99523998 48.42170117, -4.99526587 48.42166243, -4.99529195 48.42162376, -4.99531821 48.42158513, -4.99534465 48.42154656, -4.99537128 48.42150805, -4.99539808 48.42146959, -4.99542507 48.42143119, -4.99545224 48.42139285, -4.99547959 48.42135456, -4.99550711 48.42131633, -4.99553482 48.42127816, -4.99556271 48.42124004, -4.99559078 48.42120199, -4.99561903 48.42116399, -4.99564746 48.42112605, -4.99567606 48.42108817, -4.99570485 48.42105035, -4.99573381 48.4210126, -4.99576295 48.4209749, -4.99579227 48.42093726, -4.99582177 48.42089969, -4.99585144 48.42086218, -4.99588129 48.42082473, -4.99591132 48.42078734, -4.99594152 48.42075001, -4.9959719 48.42071275, -4.99600246 48.42067555, -4.99603319 48.42063842, -4.9960641 48.42060135, -4.99609518 48.42056435, -4.99612643 48.42052741, -4.99615786 48.42049053, -4.99618946 48.42045372, -4.99622124 48.42041698, -4.99625319 48.42038031, -4.99628531 48.4203437, -4.9963176 48.42030716, -4.99635007 48.42027069, -4.99638271 48.42023428, -4.99641552 48.42019794, -4.9964485 48.42016168, -4.99648166 48.42012548, -4.99651498 48.42008935, -4.99654847 48.42005329, -4.99658214 48.4200173, -4.99661597 48.41998138, -4.99664997 48.41994553, -4.99668415 48.41990976, -4.99671849 48.41987405, -4.996753 48.41983842, -4.99678767 48.41980286, -4.99682252 48.41976737, -4.99685753 48.41973196, -4.99689271 48.41969662, -4.99692805 48.41966135, -4.99696356 48.41962616, -4.99699924 48.41959104, -4.99703508 48.41955599, -4.99707109 48.41952102, -4.99710726 48.41948613, -4.9971436 48.41945131, -4.9971801 48.41941657, -4.99721677 48.4193819, -4.9972536 48.41934732, -4.99729059 48.4193128, -4.99732774 48.41927837, -4.99736506 48.41924402, -4.99740254 48.41920974, -4.99744018 48.41917554, -4.99747798 48.41914142, -4.99751594 48.41910738, -4.99755406 48.41907342, -4.99759234 48.41903953, -4.99763079 48.41900573, -4.99766939 48.41897201, -4.99770815 48.41893837, -4.99774707 48.41890481, -4.99778614 48.41887133, -4.99782538 48.41883794, -4.99786477 48.41880463, -4.99790432 48.4187714, -4.99794402 48.41873825, -4.99798388 48.41870518, -4.9980239 48.4186722, -4.99806408 48.4186393, -4.9981044 48.41860649, -4.99814489 48.41857376, -4.99818552 48.41854112, -4.99822631 48.41850856, -4.99826726 48.41847609, -4.99830835 48.4184437, -4.9983496 48.4184114, -4.99839101 48.41837918, -4.99843256 48.41834705, -4.99847426 48.41831501, -4.99851612 48.41828306, -4.99855813 48.41825119, -4.99860028 48.41821941, -4.99864259 48.41818772, -4.99868504 48.41815612, -4.99872765 48.41812461, -4.9987704 48.41809319, -4.9988133 48.41806185, -4.99885635 48.41803061, -4.99889955 48.41799946, -4.99894289 48.41796839, -4.99898638 48.41793742, -4.99903001 48.41790654, -4.99907379 48.41787575, -4.99911772 48.41784505, -4.99916179 48.41781444, -4.999206 48.41778393, -4.99925036 48.41775351, -4.99929486 48.41772318, -4.99933951 48.41769294, -4.99938429 48.4176628, -4.99942922 48.41763276, -4.99947429 48.4176028, -4.9995195 48.41757294, -4.99956485 48.41754318, -4.99961035 48.41751351, -4.99965598 48.41748393, -4.99970175 48.41745445, -4.99974766 48.41742507, -4.99979371 48.41739578, -4.99983989 48.41736659, -4.99988622 48.4173375, -4.99993268 48.4173085, -4.99997927 48.4172796, -5.00002601 48.4172508, -5.00007288 48.4172221, -5.00011988 48.41719349, -5.00016702 48.41716498, -5.00021429 48.41713657, -5.0002617 48.41710826, -5.00030924 48.41708005, -5.00035691 48.41705194, -5.00040472 48.41702393, -5.00045266 48.41699602, -5.00050072 48.41696821, -5.00054892 48.4169405, -5.00059725 48.41691289, -5.00064571 48.41688538, -5.0006943 48.41685797, -5.00074302 48.41683067, -5.00079187 48.41680346, -5.00084085 48.41677636, -5.00088995 48.41674937, -5.00093918 48.41672247, -5.00098854 48.41669568, -5.00103802 48.41666899, -5.00108763 48.4166424, -5.00113736 48.41661592, -5.00118722 48.41658954, -5.0012372 48.41656327, -5.00128731 48.4165371, -5.00133754 48.41651104, -5.00138789 48.41648508, -5.00143837 48.41645923, -5.00148896 48.41643348, -5.00153968 48.41640784, -5.00159052 48.4163823, -5.00164148 48.41635688, -5.00169256 48.41633155, -5.00174375 48.41630634, -5.00179507 48.41628123, -5.0018465 48.41625623, -5.00189805 48.41623134, -5.00194972 48.41620655, -5.00200151 48.41618187, -5.00205341 48.41615731, -5.00210543 48.41613285, -5.00215756 48.4161085, -5.00220981 48.41608425, -5.00226217 48.41606012, -5.00231465 48.4160361, -5.00236723 48.41601219, -5.00241993 48.41598838, -5.00247275 48.41596469, -5.00252567 48.41594111, -5.00257871 48.41591764, -5.00263185 48.41589428, -5.00268511 48.41587103, -5.00273847 48.41584789, -5.00279195 48.41582486, -5.00284553 48.41580195, -5.00289922 48.41577915, -5.00295301 48.41575646, -5.00300692 48.41573388, -5.00306093 48.41571142, -5.00311504 48.41568907, -5.00316927 48.41566683, -5.00322359 48.4156447, -5.00327802 48.41562269, -5.00333255 48.4156008, -5.00338719 48.41557901, -5.00344193 48.41555735, -5.00349677 48.41553579, -5.00355171 48.41551435, -5.00360676 48.41549303, -5.0036619 48.41547182, -5.00371714 48.41545073, -5.00377249 48.41542975, -5.00382793 48.41540889, -5.00388347 48.41538814, -5.0039391 48.41536751, -5.00399484 48.415347, -5.00405067 48.4153266, -5.00410659 48.41530632, -5.00416261 48.41528616, -5.00421873 48.41526611, -5.00427494 48.41524619, -5.00433125 48.41522638, -5.00438764 48.41520668, -5.00444413 48.41518711, -5.00450072 48.41516765, -5.00455739 48.41514831, -5.00461416 48.41512909, -5.00467101 48.41510999, -5.00472796 48.41509101, -5.00478499 48.41507215, -5.00484211 48.41505341, -5.00489932 48.41503478, -5.00495662 48.41501628, -5.00501401 48.4149979, -5.00507148 48.41497963, -5.00512904 48.41496149, -5.00518668 48.41494347, -5.00524441 48.41492556, -5.00530222 48.41490778, -5.00536012 48.41489012, -5.0054181 48.41487258, -5.00547616 48.41485516, -5.0055343 48.41483786, -5.00559252 48.41482069, -5.00565083 48.41480364, -5.00570921 48.4147867, -5.00576768 48.4147699, -5.00582622 48.41475321, -5.00588485 48.41473664, -5.00594355 48.4147202, -5.00600232 48.41470388, -5.00606118 48.41468769, -5.00612011 48.41467161, -5.00617911 48.41465566, -5.00623819 48.41463984, -5.00629735 48.41462414, -5.00635658 48.41460856, -5.00641588 48.4145931, -5.00647525 48.41457777, -5.0065347 48.41456257, -5.00659422 48.41454748, -5.00665381 48.41453253, -5.00671347 48.41451769, -5.0067732 48.41450298, -5.00683299 48.4144884, -5.00689286 48.41447394, -5.00695279 48.41445961, -5.0070128 48.4144454, -5.00707286 48.41443132, -5.007133 48.41441736, -5.0071932 48.41440353, -5.00725346 48.41438983, -5.00731379 48.41437625, -5.00737419 48.4143628, -5.00743464 48.41434947, -5.00749516 48.41433627, -5.00755574 48.4143232, -5.00761638 48.41431025, -5.00767709 48.41429743, -5.00773785 48.41428474, -5.00779867 48.41427218, -5.00785955 48.41425974, -5.00792049 48.41424743, -5.00798149 48.41423525, -5.00804255 48.41422319, -5.00810366 48.41421126, -5.00816482 48.41419946, -5.00822605 48.41418779, -5.00828732 48.41417625, -5.00834866 48.41416483, -5.00841004 48.41415354, -5.00847148 48.41414238, -5.00853297 48.41413135, -5.00859451 48.41412045, -5.0086561 48.41410968, -5.00871775 48.41409903, -5.00877944 48.41408852, -5.00884119 48.41407813, -5.00890298 48.41406787, -5.00896482 48.41405775, -5.0090267 48.41404775, -5.00908864 48.41403788, -5.00915062 48.41402814, -5.00921264 48.41401853, -5.00927471 48.41400905, -5.00933683 48.4139997, -5.00939899 48.41399048, -5.00946119 48.41398139, -5.00952344 48.41397243, -5.00958572 48.4139636, -5.00964805 48.4139549, -5.00971042 48.41394633, -5.00977283 48.41393789, -5.00983528 48.41392958, -5.00989777 48.4139214, -5.00996029 48.41391335, -5.01002285 48.41390544, -5.01008545 48.41389765, -5.01014809 48.41389, -5.01021076 48.41388247, -5.01027347 48.41387508, -5.01033621 48.41386782, -5.01039899 48.41386069, -5.0104618 48.41385369, -5.01052464 48.41384682, -5.01058752 48.41384009, -5.01065042 48.41383348, -5.01071336 48.41382701, -5.01077633 48.41382067, -5.01083932 48.41381446, -5.01090235 48.41380838, -5.0109654 48.41380243, -5.01102848 48.41379662, -5.01109159 48.41379094, -5.01115473 48.41378539, -5.01121789 48.41377997, -5.01128107 48.41377468, -5.01134429 48.41376953, -5.01140752 48.41376451, -5.01147078 48.41375962, -5.01153406 48.41375486, -5.01159736 48.41375023, -5.01166069 48.41374574, -5.01172403 48.41374138, -5.0117874 48.41373715, -5.01185078 48.41373306, -5.01191419 48.41372909, -5.01197761 48.41372526, -5.01204105 48.41372157, -5.01210451 48.413718, -5.01216798 48.41371457, -5.01223147 48.41371127, -5.01229498 48.4137081, -5.0123585 48.41370507, -5.01242203 48.41370217, -5.01248558 48.4136994, -5.01254914 48.41369676, -5.01261271 48.41369426, -5.0126763 48.41369189, -5.01273989 48.41368965, -5.0128035 48.41368755, -5.01286711 48.41368558, -5.01293073 48.41368374, -5.01299437 48.41368204, -5.013058 48.41368047, -5.01312165 48.41367903, -5.0131853 48.41367772, -5.01324896 48.41367655, -5.01331263 48.41367551, -5.0133763 48.41367461, -5.01343997 48.41367383, -5.01350364 48.41367319, -5.01356732 48.41367269, -5.013631 48.41367231, -5.01369469 48.41367207, -5.01375837 48.41367197, -5.01382205 48.41367199, -5.01388573 48.41367215, -5.01394942 48.41367244, -5.0140131 48.41367287, -5.01407677 48.41367343, -5.01414045 48.41367412, -5.01420412 48.41367494, -5.01426779 48.4136759, -5.01433145 48.41367699, -5.01439511 48.41367822, -5.01445876 48.41367957, -5.0145224 48.41368106, -5.01458604 48.41368269, -5.01464966 48.41368444, -5.01471328 48.41368633, -5.0147769 48.41368836, -5.0148405 48.41369051, -5.01490409 48.4136928, -5.01496767 48.41369522, -5.01503123 48.41369778, -5.01509479 48.41370046, -5.01515833 48.41370328, -5.01522186 48.41370624, -5.01528537 48.41370932, -5.01534887 48.41371254, -5.01541236 48.41371589, -5.01547582 48.41371938, -5.01553928 48.41372299, -5.01560271 48.41372674, -5.01566613 48.41373062, -5.01572952 48.41373464, -5.0157929 48.41373879, -5.01585626 48.41374307, -5.0159196 48.41374748, -5.01598291 48.41375202, -5.01604621 48.4137567, -5.01610948 48.41376151, -5.01617273 48.41376645, -5.01623595 48.41377152, -5.01629915 48.41377673, -5.01636233 48.41378207, -5.01642548 48.41378754, -5.01648861 48.41379314, -5.01655171 48.41379887, -5.01661478 48.41380474, -5.01667782 48.41381074, -5.01674083 48.41381687, -5.01680382 48.41382313, -5.01686677 48.41382952, -5.0169297 48.41383605, -5.01699259 48.4138427, -5.01705545 48.41384949, -5.01711828 48.41385641, -5.01718108 48.41386346, -5.01724384 48.41387064, -5.01730657 48.41387795, -5.01736927 48.4138854, -5.01743192 48.41389297, -5.01749455 48.41390068, -5.01755713 48.41390851, -5.01761968 48.41391648, -5.01768219 48.41392458, -5.01774467 48.41393281, -5.0178071 48.41394117, -5.01786949 48.41394966, -5.01793185 48.41395828, -5.01799416 48.41396703, -5.01805643 48.41397591, -5.01811866 48.41398492, -5.01818084 48.41399406, -5.01824298 48.41400333, -5.01830508 48.41401274, -5.01836714 48.41402227, -5.01842914 48.41403193, -5.01849111 48.41404172, -5.01855302 48.41405164, -5.01861489 48.41406169, -5.01867671 48.41407186, -5.01873848 48.41408217, -5.01880021 48.41409261, -5.01886188 48.41410317, -5.01892351 48.41411387, -5.01898508 48.41412469, -5.0190466 48.41413565, -5.01910807 48.41414673, -5.01916949 48.41415794, -5.01923085 48.41416927, -5.01929216 48.41418074, -5.01935342 48.41419233, -5.01941462 48.41420405, -5.01947577 48.4142159, -5.01953686 48.41422788, -5.01959789 48.41423999, -5.01965886 48.41425222, -5.01971978 48.41426458, -5.01978064 48.41427707, -5.01984144 48.41428968, -5.01990218 48.41430242, -5.01996286 48.41431529, -5.02002348 48.41432829, -5.02008403 48.41434141, -5.02014453 48.41435466, -5.02020496 48.41436804, -5.02026533 48.41438154, -5.02032563 48.41439517, -5.02038587 48.41440892, -5.02044604 48.4144228, -5.02050615 48.4144368, -5.0205662 48.41445093, -5.02062617 48.41446519, -5.02068608 48.41447957, -5.02074592 48.41449408, -5.02080569 48.41450871, -5.02086539 48.41452347, -5.02092502 48.41453835, -5.02098458 48.41455336, -5.02104407 48.41456849, -5.02110349 48.41458374, -5.02116284 48.41459912, -5.02122211 48.41461463, -5.02128131 48.41463025, -5.02134044 48.414646, -5.02139949 48.41466188, -5.02145847 48.41467788, -5.02151737 48.414694, -5.02157619 48.41471024, -5.02163494 48.41472661, -5.02169361 48.4147431, -5.0217522 48.41475971, -5.02181071 48.41477644, -5.02186915 48.4147933, -5.0219275 48.41481028, -5.02198577 48.41482738, -5.02204397 48.4148446, -5.02210208 48.41486195, -5.02216011 48.41487941, -5.02221805 48.414897, -5.02227592 48.41491471, -5.0223337 48.41493254, -5.02239139 48.41495049, -5.022449 48.41496856, -5.02250653 48.41498675, -5.02256396 48.41500506, -5.02262132 48.41502349, -5.02267858 48.41504204, -5.02273576 48.41506071, -5.02279285 48.4150795, -5.02284984 48.41509841, -5.02290675 48.41511744, -5.02296357 48.41513659, -5.0230203 48.41515585, -5.02307694 48.41517524, -5.02313349 48.41519474, -5.02318994 48.41521436, -5.0232463 48.4152341, -5.02330257 48.41525395, -5.02335875 48.41527393, -5.02341483 48.41529402, -5.02347081 48.41531423, -5.0235267 48.41533455, -5.02358249 48.41535499, -5.02363819 48.41537555, -5.02369379 48.41539623, -5.02374929 48.41541702, -5.02380469 48.41543793, -5.02385999 48.41545895, -5.0239152 48.41548009, -5.0239703 48.41550134, -5.02402531 48.41552271, -5.02408021 48.41554419, -5.02413501 48.41556579, -5.02418971 48.41558751, -5.02424431 48.41560933, -5.0242988 48.41563127, -5.02435319 48.41565333, -5.02440747 48.4156755, -5.02446165 48.41569778, -5.02451573 48.41572017, -5.0245697 48.41574268, -5.02462356 48.4157653, -5.02467731 48.41578804, -5.02473096 48.41581088, -5.0247845 48.41583384, -5.02483793 48.41585691, -5.02489126 48.41588009, -5.02494447 48.41590338, -5.02499757 48.41592679, -5.02505056 48.4159503, -5.02510344 48.41597393, -5.02515621 48.41599766, -5.02520887 48.41602151, -5.02526141 48.41604547, -5.02531384 48.41606953, -5.02536616 48.41609371, -5.02541836 48.41611799, -5.02547045 48.41614238, -5.02552242 48.41616689, -5.02557428 48.4161915, -5.02562602 48.41621622, -5.02567764 48.41624104, -5.02572915 48.41626598, -5.02578054 48.41629102, -5.02583181 48.41631617, -5.02588296 48.41634143, -5.02593399 48.41636679, -5.0259849 48.41639226, -5.02603569 48.41641784, -5.02608636 48.41644352, -5.02613691 48.41646931, -5.02618734 48.4164952, -5.02623764 48.4165212, -5.02628782 48.41654731, -5.02633788 48.41657352, -5.02638782 48.41659983, -5.02643763 48.41662625, -5.02648731 48.41665277, -5.02653687 48.4166794, -5.02658631 48.41670613, -5.02663561 48.41673296, -5.02668479 48.41675989, -5.02673385 48.41678693, -5.02678277 48.41681407, -5.02683157 48.41684132, -5.02688024 48.41686866, -5.02692878 48.41689611, -5.02697719 48.41692366, -5.02702547 48.4169513, -5.02707362 48.41697905, -5.02712163 48.4170069, -5.02716952 48.41703485, -5.02721727 48.4170629, -5.02726489 48.41709105, -5.02731238 48.4171193, -5.02735974 48.41714765, -5.02740696 48.4171761, -5.02745404 48.41720465, -5.027501 48.41723329, -5.02754781 48.41726203, -5.02759449 48.41729087, -5.02764104 48.41731981, -5.02768744 48.41734885, -5.02773371 48.41737798, -5.02777985 48.41740721, -5.02782584 48.41743653, -5.02787169 48.41746595, -5.02791741 48.41749547, -5.02796299 48.41752508, -5.02800843 48.41755479, -5.02805372 48.41758459, -5.02809888 48.41761449, -5.02814389 48.41764448, -5.02818877 48.41767456, -5.0282335 48.41770474, -5.02827809 48.41773501, -5.02832253 48.41776538, -5.02836683 48.41779583, -5.02841099 48.41782638, -5.028455 48.41785703, -5.02849887 48.41788776, -5.0285426 48.41791859, -5.02858617 48.4179495, -5.02862961 48.41798051, -5.02867289 48.41801161, -5.02871603 48.4180428, -5.02875902 48.41807408, -5.02880186 48.41810545, -5.02884456 48.4181369, -5.02888711 48.41816845, -5.0289295 48.41820009, -5.02897175 48.41823181, -5.02901385 48.41826362, -5.0290558 48.41829552, -5.02909759 48.41832751, -5.02913924 48.41835959, -5.02918073 48.41839175, -5.02922208 48.418424, -5.02926327 48.41845633, -5.0293043 48.41848876, -5.02934519 48.41852126, -5.02938592 48.41855385, -5.02942649 48.41858653, -5.02946692 48.41861929, -5.02950718 48.41865214, -5.0295473 48.41868507, -5.02958725 48.41871808, -5.02962705 48.41875118, -5.0296667 48.41878436, -5.02970619 48.41881762, -5.02974552 48.41885097, -5.02978469 48.4188844, -5.0298237 48.41891791, -5.02986256 48.4189515, -5.02990126 48.41898517, -5.0299398 48.41901892, -5.02997818 48.41905275, -5.0300164 48.41908667, -5.03005446 48.41912066, -5.03009236 48.41915473, -5.0301301 48.41918888, -5.03016767 48.41922311, -5.03020509 48.41925742, -5.03024234 48.41929181, -5.03027943 48.41932627, -5.03031636 48.41936081, -5.03035312 48.41939543, -5.03038972 48.41943013, -5.03042616 48.4194649, -5.03046243 48.41949974, -5.03049854 48.41953467, -5.03053449 48.41956967, -5.03057026 48.41960474, -5.03060588 48.41963989, -5.03064132 48.41967511, -5.0306766 48.41971041, -5.03071172 48.41974578, -5.03074666 48.41978122, -5.03078144 48.41981674, -5.03081605 48.41985233, -5.0308505 48.41988799, -5.03088477 48.41992372, -5.03091888 48.41995952, -5.03095281 48.4199954, -5.03098658 48.42003134, -5.03102018 48.42006736, -5.03105361 48.42010345, -5.03108686 48.4201396, -5.03111995 48.42017583, -5.03115287 48.42021212, -5.03118561 48.42024849, -5.03121818 48.42028492, -5.03125058 48.42032142, -5.03128281 48.42035799, -5.03131486 48.42039462, -5.03134675 48.42043132, -5.03137845 48.42046809, -5.03140999 48.42050492, -5.03144135 48.42054182, -5.03147254 48.42057879, -5.03150355 48.42061582, -5.03153439 48.42065291, -5.03156505 48.42069007, -5.03159553 48.42072729, -5.03162584 48.42076458, -5.03165598 48.42080193, -5.03168594 48.42083934, -5.03171572 48.42087682, -5.03174532 48.42091435, -5.03177475 48.42095195, -5.031804 48.42098961, -5.03183307 48.42102733, -5.03186197 48.42106511, -5.03189068 48.42110295, -5.03191922 48.42114086, -5.03194758 48.42117882, -5.03197575 48.42121684, -5.03200375 48.42125492, -5.03203157 48.42129305, -5.03205921 48.42133125, -5.03208667 48.4213695, -5.03211395 48.42140781, -5.03214105 48.42144618, -5.03216796 48.4214846, -5.0321947 48.42152308, -5.03222125 48.42156162, -5.03224762 48.42160021, -5.03227381 48.42163885, -5.03229981 48.42167755, -5.03232564 48.42171631, -5.03235128 48.42175511, -5.03237673 48.42179398, -5.03240201 48.42183289, -5.0324271 48.42187186, -5.032452 48.42191088, -5.03247672 48.42194995, -5.03250126 48.42198907, -5.03252561 48.42202824, -5.03254978 48.42206747, -5.03257376 48.42210674, -5.03259756 48.42214607, -5.03262117 48.42218544, -5.0326446 48.42222487, -5.03266783 48.42226434, -5.03269089 48.42230386, -5.03271375 48.42234343, -5.03273643 48.42238304, -5.03275892 48.42242271, -5.03278123 48.42246242, -5.03280334 48.42250217, -5.03282527 48.42254198, -5.03284702 48.42258183, -5.03286857 48.42262172, -5.03288993 48.42266166, -5.03291111 48.42270164, -5.0329321 48.42274167, -5.0329529 48.42278174, -5.03297351 48.42282185, -5.03299393 48.42286201, -5.03301416 48.42290221, -5.0330342 48.42294245, -5.03305405 48.42298274, -5.03307371 48.42302306, -5.03309318 48.42306343, -5.03311246 48.42310383, -5.03313155 48.42314428, -5.03315044 48.42318476, -5.03316915 48.42322529, -5.03318766 48.42326585, -5.03320599 48.42330646, -5.03322412 48.4233471, -5.03324206 48.42338777, -5.03325981 48.42342849, -5.03327736 48.42346924, -5.03329473 48.42351003, -5.0333119 48.42355086, -5.03332888 48.42359172, -5.03334566 48.42363261, -5.03336225 48.42367355, -5.03337865 48.42371451, -5.03339486 48.42375551, -5.03341087 48.42379654, -5.03342669 48.42383761, -5.03344231 48.42387871, -5.03345774 48.42391984, -5.03347298 48.42396101, -5.03348802 48.4240022, -5.03350286 48.42404343, -5.03351752 48.42408469, -5.03353197 48.42412598, -5.03354624 48.42416729, -5.0335603 48.42420864, -5.03357418 48.42425002, -5.03358785 48.42429142, -5.03360133 48.42433286, -5.03361462 48.42437432, -5.03362771 48.42441581, -5.0336406 48.42445733, -5.0336533 48.42449887, -5.0336658 48.42454044, -5.03367811 48.42458204, -5.03369022 48.42462366, -5.03370213 48.42466531, -5.03371385 48.42470698, -5.03372537 48.42474867, -5.03373669 48.42479039, -5.03374782 48.42483214, -5.03375875 48.4248739, -5.03376948 48.42491569, -5.03378001 48.4249575, -5.03379035 48.42499933, -5.03380049 48.42504119, -5.03381043 48.42508306, -5.03382017 48.42512496, -5.03382972 48.42516687, -5.03383907 48.42520881, -5.03384822 48.42525077, -5.03385717 48.42529274, -5.03386593 48.42533473, -5.03387448 48.42537674, -5.03388284 48.42541877, -5.033891 48.42546082, -5.03389896 48.42550288, -5.03390672 48.42554496, -5.03391428 48.42558705, -5.03392165 48.42562916, -5.03392882 48.42567129, -5.03393578 48.42571343, -5.03394255 48.42575558, -5.03394912 48.42579775, -5.03395549 48.42583993, -5.03396166 48.42588213, -5.03396763 48.42592434, -5.03397341 48.42596656, -5.03397898 48.42600879, -5.03398435 48.42605103, -5.03398953 48.42609329, -5.0339945 48.42613555, -5.03399928 48.42617783, -5.03400385 48.42622011, -5.03400823 48.42626241, -5.03401241 48.42630471, -5.03401638 48.42634702, -5.03402016 48.42638934, -5.03402374 48.42643167, -5.03402712 48.42647401, -5.03403029 48.42651635, -5.03403327 48.4265587, -5.03403605 48.42660105, -5.03403863 48.42664341, -5.03404101 48.42668577, -5.03404318 48.42672814, -5.03404516 48.42677052, -5.03404694 48.4268129, -5.03404852 48.42685528, -5.0340499 48.42689766, -5.03405107 48.42694005, -5.03405205 48.42698244, -5.03405283 48.42702483, -5.03405341 48.42706722, -5.03405379 48.42710962, -5.03405396 48.42715201, -5.03405394 48.42719441, -5.03405372 48.4272368, -5.03405329 48.4272792, -5.03405267 48.42732159, -5.03405185 48.42736398, -5.03405082 48.42740637, -5.0340496 48.42744876, -5.03404818 48.42749114, -5.03404655 48.42753352, -5.03404473 48.4275759, -5.03404271 48.42761827, -5.03404048 48.42766064, -5.03403806 48.427703, -5.03403544 48.42774536, -5.03403261 48.42778772, -5.03402959 48.42783006, -5.03402637 48.4278724, -5.03402294 48.42791474, -5.03401932 48.42795706, -5.0340155 48.42799938, -5.03401148 48.42804169, -5.03400725 48.42808399, -5.03400283 48.42812628, -5.03399821 48.42816857, -5.03399339 48.42821084, -5.03398837 48.4282531, -5.03398315 48.42829535, -5.03397773 48.4283376, -5.03397211 48.42837982, -5.03396629 48.42842204, -5.03396027 48.42846425, -5.03395406 48.42850644, -5.03394764 48.42854862, -5.03394103 48.42859078, -5.03393421 48.42863294, -5.0339272 48.42867507, -5.03391999 48.42871719, -5.03391258 48.4287593, -5.03390497 48.42880139, -5.03389716 48.42884347, -5.03388915 48.42888552, -5.03388095 48.42892757, -5.03387254 48.42896959, -5.03386394 48.4290116, -5.03385514 48.42905358, -5.03384614 48.42909555, -5.03383695 48.4291375, -5.03382755 48.42917944, -5.03381796 48.42922135, -5.03380817 48.42926324, -5.03379818 48.42930511, -5.033788 48.42934696, -5.03377761 48.42938878, -5.03376703 48.42943059, -5.03375626 48.42947237, -5.03374528 48.42951413, -5.03373411 48.42955587, -5.03372274 48.42959759, -5.03371117 48.42963928, -5.03369941 48.42968094, -5.03368745 48.42972258, -5.0336753 48.4297642, -5.03366294 48.42980579, -5.0336504 48.42984735, -5.03363765 48.42988889, -5.03362471 48.4299304, -5.03361157 48.42997188, -5.03359824 48.43001334, -5.03358471 48.43005477, -5.03357099 48.43009617, -5.03355707 48.43013754, -5.03354296 48.43017888, -5.03352865 48.43022019, -5.03351414 48.43026147, -5.03349944 48.43030272, -5.03348455 48.43034394, -5.03346946 48.43038513, -5.03345418 48.43042628, -5.0334387 48.43046741, -5.03342303 48.4305085, -5.03340717 48.43054956, -5.03339111 48.43059058, -5.03337486 48.43063158, -5.03335841 48.43067253, -5.03334177 48.43071346, -5.03332494 48.43075434, -5.03330791 48.4307952, -5.0332907 48.43083601, -5.03327329 48.43087679, -5.03325568 48.43091754, -5.03323789 48.43095824, -5.0332199 48.43099891, -5.03320172 48.43103954, -5.03318335 48.43108014, -5.03316479 48.43112069, -5.03314603 48.43116121, -5.03312709 48.43120169, -5.03310795 48.43124212, -5.03308862 48.43128252, -5.03306911 48.43132287, -5.0330494 48.43136319, -5.0330295 48.43140346, -5.03300941 48.43144369, -5.03298913 48.43148388, -5.03296866 48.43152403, -5.03294801 48.43156413, -5.03292716 48.43160419, -5.03290612 48.43164421, -5.0328849 48.43168418, -5.03286349 48.43172411, -5.03284189 48.43176399, -5.0328201 48.43180383, -5.03279812 48.43184362, -5.03277595 48.43188337, -5.0327536 48.43192307, -5.03273106 48.43196272, -5.03270833 48.43200232, -5.03268542 48.43204188, -5.03266232 48.43208139, -5.03263903 48.43212085, -5.03261555 48.43216026, -5.03259189 48.43219962, -5.03256805 48.43223894, -5.03254402 48.4322782, -5.0325198 48.43231741, -5.0324954 48.43235657, -5.03247081 48.43239568, -5.03244604 48.43243474, -5.03242109 48.43247375, -5.03239595 48.4325127, -5.03237063 48.4325516, -5.03234512 48.43259045, -5.03231943 48.43262925, -5.03229356 48.43266799, -5.0322675 48.43270667, -5.03224126 48.4327453, -5.03221484 48.43278388, -5.03218824 48.4328224, -5.03216146 48.43286087, -5.03213449 48.43289928, -5.03210735 48.43293763, -5.03208002 48.43297593, -5.03205251 48.43301416, -5.03202482 48.43305235, -5.03199695 48.43309047, -5.0319689 48.43312853, -5.03194067 48.43316654, -5.03191227 48.43320448, -5.03188368 48.43324237, -5.03185491 48.4332802, -5.03182597 48.43331796, -5.03179685 48.43335567, -5.03176755 48.43339331, -5.03173807 48.4334309, -5.03170841 48.43346842, -5.03167858 48.43350588, -5.03164857 48.43354327, -5.03161839 48.43358061, -5.03158802 48.43361788, -5.03155749 48.43365508, -5.03152677 48.43369223, -5.03149589 48.4337293, -5.03146482 48.43376632, -5.03143358 48.43380327, -5.03140217 48.43384015, -5.03137059 48.43387697, -5.03133883 48.43391372, -5.03130689 48.4339504, -5.03127479 48.43398702, -5.03124251 48.43402357, -5.03121006 48.43406005, -5.03117743 48.43409646, -5.03114464 48.43413281, -5.03111167 48.43416909, -5.03107853 48.4342053, -5.03104522 48.43424143, -5.03101175 48.4342775, -5.0309781 48.4343135, -5.03094428 48.43434943, -5.03091029 48.43438529, -5.03087613 48.43442107, -5.0308418 48.43445679, -5.03080731 48.43449243, -5.03077264 48.434528, -5.03073781 48.43456349, -5.03070281 48.43459892, -5.03066765 48.43463427, -5.03063232 48.43466955, -5.03059682 48.43470475, -5.03056115 48.43473988, -5.03052532 48.43477493, -5.03048933 48.43480991, -5.03045316 48.43484482, -5.03041684 48.43487964, -5.03038035 48.4349144, -5.03034369 48.43494907, -5.03030688 48.43498367, -5.0302699 48.43501819, -5.03023275 48.43505263, -5.03019545 48.435087, -5.03015798 48.43512129, -5.03012035 48.4351555, -5.03008256 48.43518963, -5.0300446 48.43522368, -5.03000649 48.43525765, -5.02996822 48.43529154, -5.02992979 48.43532535, -5.02989119 48.43535908, -5.02985244 48.43539273, -5.02981353 48.4354263, -5.02977446 48.43545979, -5.02973524 48.4354932, -5.02969585 48.43552652, -5.02965631 48.43555976, -5.02961661 48.43559292, -5.02957676 48.43562599, -5.02953675 48.43565898, -5.02949658 48.43569189, -5.02945626 48.43572472, -5.02941578 48.43575745, -5.02937515 48.43579011, -5.02933437 48.43582268, -5.02929343 48.43585516, -5.02925234 48.43588756, -5.02921109 48.43591987, -5.0291697 48.4359521, -5.02912815 48.43598423, -5.02908645 48.43601629, -5.0290446 48.43604825, -5.02900259 48.43608013, -5.02896044 48.43611192, -5.02891814 48.43614362, -5.02887569 48.43617523, -5.02883309 48.43620675, -5.02879034 48.43623818, -5.02874744 48.43626953, -5.02870439 48.43630078, -5.0286612 48.43633195, -5.02861786 48.43636302, -5.02857437 48.436394, -5.02853074 48.4364249, -5.02848696 48.4364557, -5.02844304 48.4364864, -5.02839897 48.43651702, -5.02835476 48.43654755, -5.0283104 48.43657798, -5.0282659 48.43660832, -5.02822126 48.43663856, -5.02817647 48.43666871, -5.02813154 48.43669877, -5.02808647 48.43672874, -5.02804126 48.43675861, -5.02799591 48.43678838, -5.02795041 48.43681806, -5.02790478 48.43684765, -5.02785901 48.43687714, -5.0278131 48.43690653, -5.02776705 48.43693583, -5.02772086 48.43696503, -5.02767454 48.43699413, -5.02762807 48.43702314, -5.02758147 48.43705205, -5.02753474 48.43708086, -5.02748787 48.43710958, -5.02744086 48.4371382, -5.02739372 48.43716671, -5.02734644 48.43719513, -5.02729903 48.43722345, -5.02725149 48.43725167, -5.02720381 48.4372798, -5.027156 48.43730782, -5.02710806 48.43733574, -5.02705998 48.43736356, -5.02701178 48.43739128, -5.02696344 48.4374189, -5.02691498 48.43744642, -5.02686638 48.43747384, -5.02681766 48.43750115, -5.02676881 48.43752836, -5.02671983 48.43755548, -5.02667072 48.43758248, -5.02662148 48.43760939, -5.02657212 48.43763619, -5.02652263 48.43766289, -5.02647301 48.43768949, -5.02642327 48.43771598, -5.0263734 48.43774237, -5.02632341 48.43776865, -5.0262733 48.43779483, -5.02622306 48.4378209, -5.0261727 48.43784687, -5.02612222 48.43787273, -5.02607161 48.43789849, -5.02602089 48.43792414, -5.02597004 48.43794969, -5.02591907 48.43797513, -5.02586798 48.43800046, -5.02581678 48.43802568, -5.02576545 48.4380508, -5.02571401 48.43807581, -5.02566245 48.43810072, -5.02561077 48.43812551, -5.02555897 48.4381502, -5.02550706 48.43817478, -5.02545503 48.43819924, -5.02540289 48.43822361, -5.02535063 48.43824786, -5.02529825 48.438272, -5.02524577 48.43829603, -5.02519317 48.43831995, -5.02514045 48.43834377, -5.02508763 48.43836747, -5.02503469 48.43839106, -5.02498165 48.43841454, -5.02492849 48.43843791, -5.02487522 48.43846117, -5.02482184 48.43848432, -5.02476835 48.43850735, -5.02471476 48.43853028, -5.02466105 48.43855309, -5.02460724 48.43857579, -5.02455332 48.43859837, -5.0244993 48.43862085, -5.02444517 48.43864321, -5.02439093 48.43866546, -5.02433659 48.43868759, -5.02428215 48.43870961, -5.0242276 48.43873151, -5.02417295 48.43875331, -5.02411819 48.43877498, -5.02406334 48.43879655, -5.02400838 48.43881799, -5.02395332 48.43883933, -5.02389816 48.43886055, -5.0238429 48.43888165, -5.02378754 48.43890263, -5.02373208 48.43892351, -5.02367653 48.43894426, -5.02362087 48.4389649, -5.02356512 48.43898542, -5.02350927 48.43900583, -5.02345333 48.43902611, -5.02339729 48.43904629, -5.02334115 48.43906634, -5.02328493 48.43908628, -5.0232286 48.4391061, -5.02317219 48.4391258, -5.02311568 48.43914538, -5.02305908 48.43916485, -5.02300238 48.43918419, -5.0229456 48.43920342, -5.02288872 48.43922253, -5.02283176 48.43924152, -5.02277471 48.43926039, -5.02271756 48.43927914, -5.02266033 48.43929777, -5.02260301 48.43931628, -5.02254561 48.43933468, -5.02248811 48.43935295, -5.02243054 48.4393711, -5.02237287 48.43938913, -5.02231512 48.43940704, -5.02225729 48.43942483, -5.02219937 48.4394425, -5.02214137 48.43946005, -5.02208329 48.43947747, -5.02202512 48.43949478, -5.02196688 48.43951196, -5.02190855 48.43952902, -5.02185014 48.43954596, -5.02179166 48.43956278, -5.02173309 48.43957947, -5.02167444 48.43959605, -5.02161572 48.4396125, -5.02155692 48.43962882, -5.02149804 48.43964502, -5.02143909 48.43966111, -5.02138006 48.43967706, -5.02132096 48.4396929, -5.02126178 48.4397086, -5.02120253 48.43972419, -5.0211432 48.43973965, -5.0210838 48.43975499, -5.02102433 48.4397702, -5.02096479 48.43978529, -5.02090517 48.43980026, -5.02084549 48.4398151, -5.02078574 48.43982981, -5.02072591 48.4398444, -5.02066602 48.43985887, -5.02060606 48.43987321, -5.02054604 48.43988742, -5.02048594 48.43990151, -5.02042578 48.43991547, -5.02036556 48.43992931, -5.02030527 48.43994302, -5.02024491 48.43995661, -5.02018449 48.43997006, -5.02012401 48.4399834, -5.02006346 48.4399966, -5.02000286 48.44000968, -5.01994219 48.44002263, -5.01988146 48.44003546, -5.01982067 48.44004816, -5.01975982 48.44006073, -5.01969891 48.44007317, -5.01963794 48.44008549, -5.01957692 48.44009768, -5.01951584 48.44010974, -5.0194547 48.44012167, -5.0193935 48.44013348, -5.01933225 48.44014515, -5.01927095 48.4401567, -5.01920959 48.44016812, -5.01914817 48.44017942, -5.01908671 48.44019058, -5.01902519 48.44020162, -5.01896362 48.44021253, -5.018902 48.4402233, -5.01884032 48.44023395, -5.0187786 48.44024447, -5.01871683 48.44025486, -5.01865501 48.44026513, -5.01859314 48.44027526, -5.01853122 48.44028526, -5.01846926 48.44029514, -5.01840725 48.44030488, -5.0183452 48.4403145, -5.0182831 48.44032398, -5.01822095 48.44033334, -5.01815876 48.44034256, -5.01809653 48.44035166, -5.01803426 48.44036062, -5.01797194 48.44036945, -5.01790958 48.44037816, -5.01784718 48.44038673, -5.01778474 48.44039518, -5.01772226 48.44040349, -5.01765975 48.44041167, -5.01759719 48.44041972, -5.0175346 48.44042764, -5.01747197 48.44043543, -5.0174093 48.44044309, -5.0173466 48.44045062, -5.01728386 48.44045801, -5.01722108 48.44046528, -5.01715828 48.44047241, -5.01709544 48.44047941, -5.01703256 48.44048629, -5.01696966 48.44049302, -5.01690672 48.44049963, -5.01684375 48.44050611, -5.01678075 48.44051245, -5.01671773 48.44051867, -5.01665467 48.44052475, -5.01659158 48.4405307, -5.01652847 48.44053651, -5.01646533 48.4405422, -5.01640216 48.44054775, -5.01633897 48.44055317, -5.01627575 48.44055846, -5.01621251 48.44056362, -5.01614924 48.44056864, -5.01608595 48.44057354, -5.01602264 48.4405783, -5.01595931 48.44058292, -5.01589595 48.44058742, -5.01583257 48.44059178, -5.01576917 48.44059601, -5.01570576 48.44060011, -5.01564232 48.44060407, -5.01557886 48.4406079, -5.01551539 48.4406116, -5.0154519 48.44061517, -5.0153884 48.4406186, -5.01532487 48.44062191, -5.01526134 48.44062507, -5.01519778 48.44062811, -5.01513422 48.44063101, -5.01507064 48.44063378, -5.01500704 48.44063642, -5.01494344 48.44063892, -5.01487982 48.44064129, -5.0148162 48.44064353, -5.01475256 48.44064564, -5.01468891 48.44064761, -5.01462526 48.44064945, -5.01456159 48.44065115, -5.01449792 48.44065272, -5.01443424 48.44065416, -5.01437056 48.44065547, -5.01430686 48.44065664, -5.01424317 48.44065768, -5.01417947 48.44065859, -5.01411576 48.44065936, -5.01405205 48.44066, -5.01398834 48.44066051, -5.01392463 48.44066088, -5.01386091 48.44066112, -5.0137972 48.44066123, -5.01373348 48.4406612, -5.01366977 48.44066104, -5.01360605 48.44066075, -5.01354234 48.44066033, -5.01347863 48.44065977, -5.01341492 48.44065907, -5.01335122 48.44065825, -5.01328752 48.44065729, -5.01322382 48.4406562, -5.01316013 48.44065497, -5.01309645 48.44065362, -5.01303277 48.44065212, -5.0129691 48.4406505, -5.01290544 48.44064874, -5.01284179 48.44064685, -5.01277815 48.44064483, -5.01271451 48.44064267, -5.01265089 48.44064038, -5.01258728 48.44063796, -5.01252368 48.4406354, -5.01246009 48.44063272, -5.01239652 48.44062989, -5.01233296 48.44062694, -5.01226941 48.44062385, -5.01220588 48.44062063, -5.01214236 48.44061728, -5.01207886 48.44061379, -5.01201538 48.44061018, -5.01195191 48.44060642, -5.01188846 48.44060254, -5.01182504 48.44059852, -5.01176163 48.44059437, -5.01169824 48.44059009, -5.01163487 48.44058568, -5.01157152 48.44058113, -5.01150819 48.44057645, -5.01144489 48.44057164, -5.01138161 48.4405667, -5.01131835 48.44056162, -5.01125512 48.44055641, -5.01119191 48.44055107, -5.01112872 48.4405456, -5.01106557 48.44053999, -5.01100244 48.44053426, -5.01093934 48.44052839, -5.01087626 48.44052239, -5.01081322 48.44051626, -5.0107502 48.44050999, -5.01068721 48.4405036, -5.01062426 48.44049707, -5.01056133 48.44049041, -5.01049844 48.44048362, -5.01043558 48.4404767, -5.01037275 48.44046964, -5.01030996 48.44046246, -5.0102472 48.44045514, -5.01018447 48.44044769, -5.01012178 48.44044011, -5.01005913 48.44043241, -5.00999651 48.44042456, -5.00993394 48.44041659, -5.00987139 48.44040849, -5.00980889 48.44040026, -5.00974643 48.44039189, -5.00968401 48.4403834, -5.00962162 48.44037478, -5.00955928 48.44036602, -5.00949698 48.44035714, -5.00943472 48.44034812, -5.00937251 48.44033897, -5.00931033 48.4403297, -5.00924821 48.44032029, -5.00918612 48.44031076, -5.00912409 48.44030109, -5.00906209 48.4402913, -5.00900015 48.44028137, -5.00893825 48.44027132, -5.0088764 48.44026114, -5.0088146 48.44025082, -5.00875285 48.44024038, -5.00869115 48.44022981, -5.00862949 48.44021911, -5.00856789 48.44020828, -5.00850634 48.44019732, -5.00844484 48.44018624, -5.0083834 48.44017502, -5.008322 48.44016368, -5.00826067 48.44015221, -5.00819938 48.44014061, -5.00813815 48.44012888, -5.00807698 48.44011703, -5.00801586 48.44010504, -5.0079548 48.44009293, -5.0078938 48.44008069, -5.00783286 48.44006833, -5.00777197 48.44005583, -5.00771114 48.44004321, -5.00765038 48.44003047, -5.00758967 48.44001759, -5.00752903 48.44000459, -5.00746844 48.43999146, -5.00740792 48.43997821, -5.00734747 48.43996482, -5.00728707 48.43995132, -5.00722674 48.43993768, -5.00716648 48.43992392, -5.00710628 48.43991004, -5.00704614 48.43989602, -5.00698607 48.43988189, -5.00692607 48.43986762, -5.00686614 48.43985323, -5.00680628 48.43983872, -5.00674648 48.43982408, -5.00668675 48.43980932, -5.0066271 48.43979443, -5.00656751 48.43977942, -5.006508 48.43976428, -5.00644855 48.43974902, -5.00638918 48.43973363, -5.00632989 48.43971812, -5.00627066 48.43970249, -5.00621151 48.43968673, -5.00615244 48.43967085, -5.00609344 48.43965484, -5.00603451 48.43963871, -5.00597567 48.43962246, -5.0059169 48.43960609, -5.0058582 48.43958959, -5.00579959 48.43957297, -5.00574105 48.43955623, -5.0056826 48.43953936, -5.00562422 48.43952238, -5.00556593 48.43950527, -5.00550771 48.43948804, -5.00544958 48.43947068, -5.00539153 48.43945321, -5.00533356 48.43943562, -5.00527568 48.4394179, -5.00521787 48.43940006, -5.00516016 48.43938211, -5.00510253 48.43936403, -5.00504498 48.43934583, -5.00498752 48.43932751, -5.00493015 48.43930907, -5.00487287 48.43929051, -5.00481567 48.43927183, -5.00475856 48.43925304, -5.00470154 48.43923412, -5.00464461 48.43921508, -5.00458777 48.43919593, -5.00453103 48.43917665, -5.00447437 48.43915726, -5.0044178 48.43913775, -5.00436133 48.43911812, -5.00430495 48.43909837, -5.00424866 48.43907851, -5.00419247 48.43905852, -5.00413637 48.43903842, -5.00408037 48.43901821, -5.00402447 48.43899787, -5.00396866 48.43897742, -5.00391294 48.43895685, -5.00385733 48.43893617, -5.00380181 48.43891537, -5.00374639 48.43889445, -5.00369107 48.43887342, -5.00363585 48.43885227, -5.00358073 48.43883101, -5.00352571 48.43880963, -5.00347079 48.43878814, -5.00341597 48.43876653, -5.00336126 48.43874481, -5.00330665 48.43872297, -5.00325214 48.43870102, -5.00319773 48.43867896, -5.00314343 48.43865678, -5.00308924 48.43863449, -5.00303515 48.43861209, -5.00298117 48.43858957, -5.00292729 48.43856694, -5.00287352 48.4385442, -5.00281986 48.43852134, -5.00276631 48.43849837, -5.00271286 48.43847529, -5.00265953 48.4384521, -5.0026063 48.4384288, -5.00255318 48.43840539, -5.00250018 48.43838186, -5.00244729 48.43835823, -5.00239451 48.43833448, -5.00234184 48.43831063, -5.00228928 48.43828666, -5.00223684 48.43826259, -5.00218451 48.4382384, -5.0021323 48.43821411, -5.0020802 48.4381897, -5.00202822 48.43816519, -5.00197635 48.43814057, -5.0019246 48.43811584, -5.00187296 48.438091, -5.00182145 48.43806606, -5.00177005 48.43804101, -5.00171877 48.43801585, -5.00166761 48.43799058, -5.00161657 48.43796521, -5.00156565 48.43793973, -5.00151485 48.43791414, -5.00146417 48.43788845, -5.00141361 48.43786265, -5.00136318 48.43783674, -5.00131286 48.43781073, -5.00126267 48.43778462, -5.00121261 48.4377584, -5.00116267 48.43773208, -5.00111285 48.43770565, -5.00106316 48.43767912, -5.00101359 48.43765248, -5.00096415 48.43762574, -5.00091484 48.4375989, -5.00086565 48.43757195, -5.00081659 48.4375449, -5.00076766 48.43751775, -5.00071886 48.4374905, -5.00067018 48.43746314, -5.00062164 48.43743569, -5.00057322 48.43740813, -5.00052494 48.43738047, -5.00047678 48.43735271, -5.00042876 48.43732485, -5.00038087 48.43729689, -5.00033311 48.43726883, -5.00028549 48.43724067, -5.000238 48.43721241, -5.00019064 48.43718405, -5.00014342 48.43715559, -5.00009633 48.43712703, -5.00004937 48.43709838, -5.00000255 48.43706963, -4.99995587 48.43704078, -4.99990932 48.43701183, -4.99986292 48.43698278, -4.99981664 48.43695364, -4.99977051 48.4369244, -4.99972451 48.43689507, -4.99967866 48.43686563, -4.99963294 48.43683611, -4.99958736 48.43680649, -4.99954192 48.43677677, -4.99949663 48.43674696, -4.99945147 48.43671705, -4.99940646 48.43668705, -4.99936158 48.43665695, -4.99931685 48.43662676, -4.99927226 48.43659648, -4.99922782 48.43656611, -4.99918352 48.43653564, -4.99913936 48.43650508, -4.99909535 48.43647443, -4.99905148 48.43644368, -4.99900776 48.43641284, -4.99896419 48.43638192, -4.99892076 48.4363509, -4.99887747 48.43631979, -4.99883434 48.43628859, -4.99879135 48.4362573, -4.99874851 48.43622592, -4.99870582 48.43619445, -4.99866328 48.4361629, -4.99862088 48.43613125, -4.99857864 48.43609951, -4.99853654 48.43606769, -4.9984946 48.43603578, -4.99845281 48.43600378, -4.99841117 48.4359717, -4.99836968 48.43593952, -4.99832834 48.43590726, -4.99828716 48.43587492, -4.99824612 48.43584249, -4.99820525 48.43580997, -4.99816452 48.43577737, -4.99812395 48.43574468, -4.99808353 48.43571191, -4.99804327 48.43567905, -4.99800317 48.43564611, -4.99796322 48.43561309, -4.99792343 48.43557998, -4.99788379 48.43554679, -4.99784431 48.43551352, -4.99780499 48.43548016, -4.99776582 48.43544672, -4.99772681 48.43541321, -4.99768796 48.4353796, -4.99764928 48.43534592, -4.99761075 48.43531216, -4.99757237 48.43527832, -4.99753416 48.43524439, -4.99749611 48.43521039, -4.99745822 48.43517631, -4.9974205 48.43514215, -4.99738293 48.43510791, -4.99734552 48.43507359, -4.99730828 48.43503919, -4.9972712 48.43500472, -4.99723428 48.43497017, -4.99719753 48.43493554, -4.99716094 48.43490084, -4.99712451 48.43486605, -4.99708825 48.4348312, -4.99705216 48.43479626, -4.99701622 48.43476126, -4.99698046 48.43472617, -4.99694486 48.43469101, -4.99690942 48.43465578, -4.99687416 48.43462048, -4.99683906 48.4345851, -4.99680412 48.43454964, -4.99676936 48.43451412, -4.99673476 48.43447852, -4.99670033 48.43444285, -4.99666607 48.43440711, -4.99663198 48.43437129, -4.99659805 48.43433541, -4.9965643 48.43429945, -4.99653072 48.43426343, -4.99649731 48.43422733, -4.99646406 48.43419117, -4.99643099 48.43415493, -4.99639809 48.43411863, -4.99636536 48.43408225, -4.99633281 48.43404581, -4.99630042 48.43400931, -4.99626821 48.43397273, -4.99623617 48.43393609, -4.99620431 48.43389938, -4.99617262 48.4338626, -4.9961411 48.43382576, -4.99610975 48.43378885, -4.99607858 48.43375187, -4.99604759 48.43371484, -4.99601677 48.43367773, -4.99598612 48.43364056, -4.99595566 48.43360333, -4.99592536 48.43356604, -4.99589525 48.43352868, -4.99586531 48.43349126, -4.99583554 48.43345378, -4.99580596 48.43341623, -4.99577655 48.43337862, -4.99574732 48.43334095, -4.99571826 48.43330322, -4.99568939 48.43326544, -4.99566069 48.43322758, -4.99563218 48.43318967, -4.99560384 48.43315171, -4.99557568 48.43311368, -4.9955477 48.43307559, -4.9955199 48.43303744, -4.99549228 48.43299924, -4.99546485 48.43296098, -4.99543759 48.43292266, -4.99541051 48.43288429, -4.99538362 48.43284586, -4.99535691 48.43280737, -4.99533037 48.43276883, -4.99530402 48.43273023, -4.99527786 48.43269157, -4.99525187 48.43265287, -4.99522607 48.4326141, -4.99520045 48.43257529, -4.99517502 48.43253642, -4.99514977 48.4324975, -4.9951247 48.43245852, -4.99509982 48.4324195, -4.99507512 48.43238042, -4.99505061 48.43234129, -4.99502628 48.43230211, -4.99500213 48.43226287, -4.99497817 48.43222359, -4.9949544 48.43218426, -4.99493081 48.43214488, -4.99490741 48.43210545, -4.9948842 48.43206597, -4.99486117 48.43202644, -4.99483833 48.43198687, -4.99481567 48.43194724, -4.99479321 48.43190757, -4.99477093 48.43186785, -4.99474883 48.43182809, -4.99472693 48.43178828, -4.99470521 48.43174843, -4.99468369 48.43170853, -4.99466235 48.43166858, -4.99464119 48.43162859, -4.99462023 48.43158856, -4.99459946 48.43154848, -4.99457888 48.43150836, -4.99455848 48.4314682, -4.99453828 48.43142799, -4.99451826 48.43138774, -4.99449844 48.43134745, -4.99447881 48.43130712, -4.99445936 48.43126675, -4.99444011 48.43122634, -4.99442105 48.43118589, -4.99440218 48.43114539, -4.9943835 48.43110486, -4.99436501 48.43106429, -4.99434671 48.43102368, -4.99432861 48.43098304, -4.9943107 48.43094235, -4.99429298 48.43090163, -4.99427545 48.43086087, -4.99425811 48.43082008, -4.99424097 48.43077925, -4.99422402 48.43073838, -4.99420726 48.43069748, -4.9941907 48.43065655, -4.99417433 48.43061557, -4.99415815 48.43057457, -4.99414217 48.43053353, -4.99412638 48.43049246, -4.99411079 48.43045135, -4.99409539 48.43041022, -4.99408018 48.43036905, -4.99406517 48.43032785, -4.99405035 48.43028662, -4.99403573 48.43024535, -4.9940213 48.43020406, -4.99400706 48.43016274, -4.99399303 48.43012139, -4.99397918 48.43008, -4.99396554 48.43003859, -4.99395208 48.42999716, -4.99393883 48.42995569, -4.99392577 48.4299142, -4.9939129 48.42987267, -4.99390024 48.42983113, -4.99388776 48.42978955, -4.99387549 48.42974795, -4.99386341 48.42970633, -4.99385153 48.42966468, -4.99383984 48.429623, -4.99382835 48.4295813, -4.99381706 48.42953958, -4.99380597 48.42949783, -4.99379507 48.42945606, -4.99378437 48.42941427, -4.99377386 48.42937246, -4.99376356 48.42933062, -4.99375345 48.42928876, -4.99374354 48.42924688, -4.99373383 48.42920499, -4.99372431 48.42916307, -4.99371499 48.42912113, -4.99370587 48.42907917, -4.99369695 48.42903719, -4.99368823 48.4289952, -4.99367971 48.42895318, -4.99367138 48.42891115, -4.99366325 48.42886911, -4.99365532 48.42882704, -4.99364759 48.42878496, -4.99364006 48.42874286, -4.99363273 48.42870075, -4.99362559 48.42865862, -4.99361866 48.42861648, -4.99361192 48.42857432, -4.99360539 48.42853215)))" - val polygon = wktReader.read(multipolygonString) as MultiPolygon - val firstMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - openBy = "KIM", - closedBy = "TRA", - facade = "NAMO", - observationsCacem = - "Remain vote several ok. Bring American play woman challenge. Throw low law positive seven.", - startDateTimeUtc = - ZonedDateTime.parse("2022-03-21T12:11:13Z"), - endDateTimeUtc = null, - geom = polygon, - isClosed = false, - isDeleted = false, - envActions = listOf(), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10002, - administration = "DDTM", - isArchived = false, - name = "DML 2A", - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 3, - controlUnitId = - 10002, - name = - "Semi-rigide 1", - ), - LegacyControlUnitResourceEntity( - id = 4, - controlUnitId = - 10002, - name = - "Semi-rigide 2", - ), - LegacyControlUnitResourceEntity( - id = 5, - controlUnitId = - 10002, - name = - "Voiture", - ), - ), - ), - ), - isGeometryComputedFromControls = false, + LegacyControlUnitResourceEntity( + id = 4, + controlUnitId = + 10002, + name = + "Semi-rigide 2", + ), + LegacyControlUnitResourceEntity( + id = 5, + controlUnitId = + 10002, + name = + "Voiture", ), - ) + ), + ), + ), + isGeometryComputedFromControls = false, + ), + ) val mission = jpaMissionRepository.findFullMissionById(10) assertThat(mission).isEqualTo(firstMission) @@ -716,9 +376,9 @@ class JpaMissionRepositoryITests : AbstractDBTests() { assertThat(missionDTO.mission.id).isEqualTo(34) assertThat(missionDTO.mission.envActions).hasSize(2) assertThat( - missionDTO.envActionsAttachedToReportingIds?.get(0)?.first, - ) - .isEqualTo(UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807")) + missionDTO.envActionsAttachedToReportingIds?.get(0)?.first, + ) + .isEqualTo(UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807")) assertThat(missionDTO.envActionsAttachedToReportingIds?.get(0)?.second).isEqualTo(listOf(6)) } @@ -735,89 +395,88 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save should create a new mission`() { // Given val existingMissions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(existingMissions).hasSize(21) val noteObservations = "Quelqu'un aurait vu quelque chose quelque part à un certain moment." val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - envActions = - listOf( - EnvActionControlEntity( - id = - UUID.fromString( - "33310163-4e22-4d3d-b585-dac4431eb4b5", - ), - facade = "Facade 1", - controlPlans = - listOf( - EnvActionControlPlanEntity( - subThemeIds = listOf(1), - tagIds = listOf(1, 2), - themeId = 1, - ), - ), - department = "Department 1", - geom = point, - vehicleType = VehicleTypeEnum.VEHICLE_LAND, - isAdministrativeControl = true, - isComplianceWithWaterRegulationsControl = true, - isSafetyEquipmentAndStandardsComplianceControl = - true, - isSeafarersControl = true, - ), - EnvActionSurveillanceEntity( - id = - UUID.fromString( - "a6c4bd17-eb45-4504-ab15-7a18ea714a10", - ), - facade = "Facade 2", - department = "Department 2", - geom = polygon, - ), - EnvActionNoteEntity( - id = - UUID.fromString( - "126ded89-2dc0-4c77-9bf2-49f86b9a71a1", - ), - observations = noteObservations, - ), - ), - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10121, - name = "PAM Jeanne Barret", - administration = "DIRM / DM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 8, - controlUnitId = 10121, - name = "PAM Jeanne Barret", - ), - ), - ), - ), - isGeometryComputedFromControls = false, - ) + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + envActions = + listOf( + EnvActionControlEntity( + id = + UUID.fromString( + "33310163-4e22-4d3d-b585-dac4431eb4b5", + ), + facade = "Facade 1", + controlPlans = listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(1), + tagIds = listOf(1, 2), + themeId = 1, + ), + ), + department = "Department 1", + geom = point, + vehicleType = VehicleTypeEnum.VEHICLE_LAND, + isAdministrativeControl = true, + isComplianceWithWaterRegulationsControl = true, + isSafetyEquipmentAndStandardsComplianceControl = + true, + isSeafarersControl = true, + ), + EnvActionSurveillanceEntity( + id = + UUID.fromString( + "a6c4bd17-eb45-4504-ab15-7a18ea714a10", + ), + facade = "Facade 2", + department = "Department 2", + geom = polygon, + ), + EnvActionNoteEntity( + id = + UUID.fromString( + "126ded89-2dc0-4c77-9bf2-49f86b9a71a1", + ), + observations = noteObservations, + ), + ), + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10121, + name = "PAM Jeanne Barret", + administration = "DIRM / DM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 8, + controlUnitId = 10121, + name = "PAM Jeanne Barret", + ), + ), + ), + ), + isGeometryComputedFromControls = false, + ) // When val newMissionCreated = jpaMissionRepository.save(newMission) @@ -826,39 +485,39 @@ class JpaMissionRepositoryITests : AbstractDBTests() { assertThat(newMissionCreated.mission.controlUnits).hasSize(1) assertThat(newMissionCreated.mission.controlUnits.first().id).isEqualTo(10121) assertThat(newMissionCreated.mission.controlUnits.first().name) - .isEqualTo("PAM Jeanne Barret") + .isEqualTo("PAM Jeanne Barret") assertThat(newMissionCreated.mission.controlUnits.first().administration) - .isEqualTo("DIRM / DM") + .isEqualTo("DIRM / DM") assertThat(newMissionCreated.mission.controlUnits.first().resources).hasSize(1) assertThat(newMissionCreated.mission.controlUnits.first().resources.first().id).isEqualTo(8) assertThat(newMissionCreated.mission.controlUnits.first().resources.first().controlUnitId) - .isEqualTo(10121) + .isEqualTo(10121) assertThat(newMissionCreated.mission.controlUnits.first().resources.first().name) - .isEqualTo("PAM Jeanne Barret") + .isEqualTo("PAM Jeanne Barret") assertThat(newMissionCreated.mission.envActions).hasSize(3) assertThat(newMissionCreated.mission.envActions?.first()?.facade).isEqualTo("Facade 1") assertThat(newMissionCreated.mission.envActions?.first()?.department) - .isEqualTo("Department 1") + .isEqualTo("Department 1") assertThat(newMissionCreated.mission.envActions?.get(1)?.facade).isEqualTo("Facade 2") assertThat(newMissionCreated.mission.envActions?.get(1)?.department) - .isEqualTo("Department 2") + .isEqualTo("Department 2") assertThat( - (newMissionCreated.mission.envActions?.get(2) as EnvActionNoteEntity) - .observations, - ) - .isEqualTo( - noteObservations, - ) + (newMissionCreated.mission.envActions?.get(2) as EnvActionNoteEntity) + .observations, + ) + .isEqualTo( + noteObservations, + ) val missions = - jpaMissionRepository.findAllFullMissions( - startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), - startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), - missionTypes = null, - missionStatuses = null, - seaFronts = null, - pageable = Pageable.unpaged(), - ) + jpaMissionRepository.findAllFullMissions( + startedAfter = ZonedDateTime.parse("2022-01-01T10:54:00Z").toInstant(), + startedBefore = ZonedDateTime.parse("2022-08-08T00:00:00Z").toInstant(), + missionTypes = null, + missionStatuses = null, + seaFronts = null, + pageable = Pageable.unpaged(), + ) assertThat(missions).hasSize(22) } @@ -868,84 +527,84 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save should update mission resources`() { // Given val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10004, - name = "DPM – DDTM 35", - administration = "DDTM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 8, - controlUnitId = 10004, - name = "PAM Jeanne Barret", - ), - ), - ), - ), - isGeometryComputedFromControls = false, - ) + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10004, + name = "DPM – DDTM 35", + administration = "DDTM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 8, + controlUnitId = 10004, + name = "PAM Jeanne Barret", + ), + ), + ), + ), + isGeometryComputedFromControls = false, + ) jpaMissionRepository.save(newMission) // When val newMissionUpdated = - jpaMissionRepository.save( - newMission.copy( - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 10002, - name = "DML 2A", - administration = "DIRM / DM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 3, - controlUnitId = - 10002, - name = - "Semi-rigide 1", - ), - LegacyControlUnitResourceEntity( - id = 5, - controlUnitId = - 10002, - name = "Voiture", - ), - ), - ), - ), + jpaMissionRepository.save( + newMission.copy( + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 10002, + name = "DML 2A", + administration = "DIRM / DM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 3, + controlUnitId = + 10002, + name = + "Semi-rigide 1", + ), + LegacyControlUnitResourceEntity( + id = 5, + controlUnitId = + 10002, + name = "Voiture", + ), + ), ), - ) + ), + ), + ) // Then assertThat(newMissionUpdated.mission.controlUnits).hasSize(1) assertThat(newMissionUpdated.mission.controlUnits.first().id).isEqualTo(10002) assertThat(newMissionUpdated.mission.controlUnits.first().name).isEqualTo("DML 2A") assertThat(newMissionUpdated.mission.controlUnits.first().administration) - .isEqualTo("DIRM / DM") + .isEqualTo("DIRM / DM") assertThat(newMissionUpdated.mission.controlUnits.first().resources).hasSize(2) assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().id).isEqualTo(3) assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().controlUnitId) - .isEqualTo(10002) + .isEqualTo(10002) assertThat(newMissionUpdated.mission.controlUnits.first().resources.first().name) - .isEqualTo("Semi-rigide 1") + .isEqualTo("Semi-rigide 1") assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().id).isEqualTo(5) assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().controlUnitId) - .isEqualTo(10002) + .isEqualTo(10002) assertThat(newMissionUpdated.mission.controlUnits.first().resources.last().name) - .isEqualTo("Voiture") + .isEqualTo("Voiture") } @Test @@ -955,28 +614,28 @@ class JpaMissionRepositoryITests : AbstractDBTests() { val mission = jpaMissionRepository.findById(25) val newControlUnitResource = jpaControlUnitResourceRepository.findById(10) val newControlUnit = - jpaControlUnitRepository.findById( - requireNotNull(newControlUnitResource.controlUnit.id), - ) + jpaControlUnitRepository.findById( + requireNotNull(newControlUnitResource.controlUnit.id), + ) val nextMission = - mission.copy( - controlUnits = - mission.controlUnits.plus( - LegacyControlUnitEntity( - id = requireNotNull(newControlUnit.controlUnit.id), - administration = newControlUnit.administration.name, - isArchived = newControlUnit.controlUnit.isArchived, - name = newControlUnit.controlUnit.name, - resources = - listOf( - newControlUnitResource - .toLegacyControlUnitResource(), - ), - contact = null, - ), - ), - ) + mission.copy( + controlUnits = + mission.controlUnits.plus( + LegacyControlUnitEntity( + id = requireNotNull(newControlUnit.controlUnit.id), + administration = newControlUnit.administration.name, + isArchived = newControlUnit.controlUnit.isArchived, + name = newControlUnit.controlUnit.name, + resources = + listOf( + newControlUnitResource + .toLegacyControlUnitResource(), + ), + contact = null, + ), + ), + ) val updatedMission = jpaMissionRepository.save(nextMission) @@ -985,12 +644,12 @@ class JpaMissionRepositoryITests : AbstractDBTests() { assertThat(updatedMission.mission.controlUnits.first().resources).hasSize(1) assertThat(updatedMission.mission.controlUnits.first().resources.first().id).isEqualTo(3) assertThat(updatedMission.mission.controlUnits.first().resources.first().controlUnitId) - .isEqualTo(10002) + .isEqualTo(10002) assertThat(updatedMission.mission.controlUnits.last().id).isEqualTo(10018) assertThat(updatedMission.mission.controlUnits.last().resources).hasSize(1) assertThat(updatedMission.mission.controlUnits.last().resources.first().id).isEqualTo(10) assertThat(updatedMission.mission.controlUnits.last().resources.first().controlUnitId) - .isEqualTo(10018) + .isEqualTo(10018) } @Test @@ -998,33 +657,33 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save should throw an exception When the resource id is not found`() { // Given val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 5, - name = "DPM – DDTM 35", - administration = "DDTM", - isArchived = false, - resources = - listOf( - LegacyControlUnitResourceEntity( - id = 123456, - controlUnitId = 5, - name = "PAM Jeanne Barret", - ), - ), - ), - ), - isGeometryComputedFromControls = false, - ) + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 5, + name = "DPM – DDTM 35", + administration = "DDTM", + isArchived = false, + resources = + listOf( + LegacyControlUnitResourceEntity( + id = 123456, + controlUnitId = 5, + name = "PAM Jeanne Barret", + ), + ), + ), + ), + isGeometryComputedFromControls = false, + ) // When val throwable = catchThrowable { jpaMissionRepository.save(newMission) } @@ -1038,26 +697,26 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save should throw an exception When the unit id is not found`() { // Given val newMission = - MissionEntity( - missionTypes = listOf(MissionTypeEnum.SEA), - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - isClosed = false, - isDeleted = false, - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - controlUnits = - listOf( - LegacyControlUnitEntity( - id = 123456, - name = "PAM Jeanne Barret", - administration = "", - isArchived = false, - resources = listOf(), - ), - ), - isGeometryComputedFromControls = false, - ) + MissionEntity( + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isClosed = false, + isDeleted = false, + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + controlUnits = + listOf( + LegacyControlUnitEntity( + id = 123456, + name = "PAM Jeanne Barret", + administration = "", + isArchived = false, + resources = listOf(), + ), + ), + isGeometryComputedFromControls = false, + ) // When val throwable = catchThrowable { jpaMissionRepository.save(newMission) } @@ -1071,90 +730,90 @@ class JpaMissionRepositoryITests : AbstractDBTests() { fun `save Should update mission`() { // Given val infraction = - InfractionEntity( - id = UUID.randomUUID().toString(), - natinf = listOf("53432"), - observations = "This is an infraction", - registrationNumber = "REGISTRATION NUM", - companyName = "ACME inc.", - relevantCourt = "MARITIME_COURT", - infractionType = InfractionTypeEnum.WITHOUT_REPORT, - formalNotice = FormalNoticeEnum.NO, - toProcess = false, - controlledPersonIdentity = "Dick Hoover", - vesselType = VesselTypeEnum.FISHING, - vesselSize = VesselSizeEnum.FROM_12_TO_24m, - ) + InfractionEntity( + id = UUID.randomUUID().toString(), + natinf = listOf("53432"), + observations = "This is an infraction", + registrationNumber = "REGISTRATION NUM", + companyName = "ACME inc.", + relevantCourt = "MARITIME_COURT", + infractionType = InfractionTypeEnum.WITHOUT_REPORT, + formalNotice = FormalNoticeEnum.NO, + toProcess = false, + controlledPersonIdentity = "Dick Hoover", + vesselType = VesselTypeEnum.FISHING, + vesselSize = VesselSizeEnum.FROM_12_TO_24m, + ) val controlAction = - EnvActionControlEntity( - id = UUID.randomUUID(), - observations = "RAS", - actionNumberOfControls = 12, - actionTargetType = ActionTargetTypeEnum.VEHICLE, - vehicleType = VehicleTypeEnum.VESSEL, - infractions = listOf(infraction), - ) + EnvActionControlEntity( + id = UUID.randomUUID(), + observations = "RAS", + actionNumberOfControls = 12, + actionTargetType = ActionTargetTypeEnum.VEHICLE, + vehicleType = VehicleTypeEnum.VESSEL, + infractions = listOf(infraction), + ) val surveillanceAction = - EnvActionSurveillanceEntity( - id = UUID.randomUUID(), - observations = "This is a surveillance action", - ) + EnvActionSurveillanceEntity( + id = UUID.randomUUID(), + observations = "This is a surveillance action", + ) val noteAction = - EnvActionNoteEntity( - id = UUID.randomUUID(), - observations = "This is a note", - ) + EnvActionNoteEntity( + id = UUID.randomUUID(), + observations = "This is a note", + ) val missionToUpdate = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - openBy = "John Smith", - closedBy = "Carol Tim", - facade = "MEMN", - geom = polygon, - observationsCacem = null, - observationsCnsp = null, - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isClosed = false, - isDeleted = false, - envActions = listOf(controlAction, surveillanceAction, noteAction), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ) + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + openBy = "John Smith", + closedBy = "Carol Tim", + facade = "MEMN", + geom = polygon, + observationsCacem = null, + observationsCnsp = null, + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isClosed = false, + isDeleted = false, + envActions = listOf(controlAction, surveillanceAction, noteAction), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ) val expectedUpdatedMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - openBy = "John Smith", - closedBy = "Carol Tim", - facade = "MEMN", - geom = polygon, - observationsCacem = null, - observationsCnsp = null, - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = - ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isClosed = false, - isDeleted = false, - envActions = - listOf( - controlAction, - surveillanceAction, - noteAction, - ), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ), - ) + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + openBy = "John Smith", + closedBy = "Carol Tim", + facade = "MEMN", + geom = polygon, + observationsCacem = null, + observationsCnsp = null, + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = + ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isClosed = false, + isDeleted = false, + envActions = + listOf( + controlAction, + surveillanceAction, + noteAction, + ), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ), + ) // When jpaMissionRepository.save(missionToUpdate) assertThat(jpaMissionRepository.findFullMissionById(10)).isEqualTo(expectedUpdatedMission) @@ -1166,53 +825,53 @@ class JpaMissionRepositoryITests : AbstractDBTests() { // Given val envAction = - EnvActionControlEntity( - id = UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), - actionTargetType = ActionTargetTypeEnum.VEHICLE, - vehicleType = VehicleTypeEnum.VESSEL, - actionNumberOfControls = 4, - ) + EnvActionControlEntity( + id = UUID.fromString("bf9f4062-83d3-4a85-b89b-76c0ded6473d"), + actionTargetType = ActionTargetTypeEnum.VEHICLE, + vehicleType = VehicleTypeEnum.VESSEL, + actionNumberOfControls = 4, + ) val missionToUpdate = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - facade = "NAMO", - geom = polygon, - observationsCacem = null, - observationsCnsp = null, - startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isClosed = false, - isDeleted = false, - envActions = listOf(envAction), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ) + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + facade = "NAMO", + geom = polygon, + observationsCacem = null, + observationsCnsp = null, + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isClosed = false, + isDeleted = false, + envActions = listOf(envAction), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ) val expectedUpdatedMission = - MissionDTO( - mission = - MissionEntity( - id = 10, - missionTypes = listOf(MissionTypeEnum.LAND), - facade = "NAMO", - geom = polygon, - observationsCacem = null, - observationsCnsp = null, - startDateTimeUtc = - ZonedDateTime.parse("2022-01-15T04:50:09Z"), - endDateTimeUtc = - ZonedDateTime.parse("2022-01-23T20:29:03Z"), - isClosed = false, - isDeleted = false, - envActions = listOf(envAction), - missionSource = MissionSourceEnum.MONITORENV, - hasMissionOrder = false, - isUnderJdp = false, - isGeometryComputedFromControls = false, - ), - ) + MissionDTO( + mission = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.LAND), + facade = "NAMO", + geom = polygon, + observationsCacem = null, + observationsCnsp = null, + startDateTimeUtc = + ZonedDateTime.parse("2022-01-15T04:50:09Z"), + endDateTimeUtc = + ZonedDateTime.parse("2022-01-23T20:29:03Z"), + isClosed = false, + isDeleted = false, + envActions = listOf(envAction), + missionSource = MissionSourceEnum.MONITORENV, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + ), + ) // When jpaMissionRepository.save(missionToUpdate) val updatedMission = jpaMissionRepository.findFullMissionById(10) @@ -1223,46 +882,35 @@ class JpaMissionRepositoryITests : AbstractDBTests() { @Transactional fun `save Should update subThemes of envActions`() { val mission = jpaMissionRepository.findById(34) - val envAction = - mission.envActions?.find { - it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") - } + val envAction = mission.envActions?.find { it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") } assertThat(envAction?.controlPlans?.size).isEqualTo(1) - assertThat(envAction?.controlPlans?.get(0)?.subThemeIds?.size).isEqualTo(2) - val nextControlPlans = - listOf( - EnvActionControlPlanEntity( - subThemeIds = listOf(53, 34), - themeId = 2, - ), - EnvActionControlPlanEntity( - tagIds = listOf(1, 2, 3), - themeId = 11, - ), - EnvActionControlPlanEntity( - themeId = 17, - ), - ) - val nextMission = - mission.copy( - envActions = - mission.envActions?.map { - if (it.id == - UUID.fromString( - "b8007c8a-5135-4bc3-816f-c69c7b75d807" - ) && it is EnvActionControlEntity - ) { - it.copy(controlPlans = nextControlPlans) - } else { - it - } - }, - ) + assertThat(envAction?.controlPlans?.get(0)?.subThemeIds?.size).isEqualTo(1) + val nextControlPlans = listOf( + EnvActionControlPlanEntity( + subThemeIds = listOf(53, 34), + themeId = 2, + ), + EnvActionControlPlanEntity( + tagIds = listOf(1, 2, 3), + themeId = 11, + ), + EnvActionControlPlanEntity( + themeId = 17, + ), + ) + val nextMission = mission.copy( + envActions = mission.envActions?.map { + if (it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") && it is EnvActionControlEntity) { + it.copy(controlPlans = nextControlPlans) + } else { + it + } + }, + ) val updatedMission = jpaMissionRepository.save(nextMission) - val updatedControlPlan = - updatedMission.mission.envActions - ?.find { it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") } - ?.controlPlans + val updatedControlPlan = updatedMission.mission.envActions?.find { + it.id == UUID.fromString("b8007c8a-5135-4bc3-816f-c69c7b75d807") + }?.controlPlans assertThat(updatedControlPlan?.size).isEqualTo(3) assertThat(updatedControlPlan?.get(0)?.subThemeIds?.size).isEqualTo(2) assertThat(updatedControlPlan?.get(0)?.subThemeIds?.get(0)).isEqualTo(53) From 142d4036a38e901a32f3ce0e7751aa0dbd9dbe67 Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Fri, 15 Dec 2023 09:59:43 +0100 Subject: [PATCH 37/53] [Test] re-add deleted test --- .../JpaControlPlanThemeRepositoryITests.kt | 31 +++++++++++++++++++ .../missions/MissionForm/mission.json | 0 2 files changed, 31 insertions(+) create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt delete mode 100644 frontend/src/features/missions/MissionForm/mission.json diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt new file mode 100644 index 000000000..e4154d0a0 --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt @@ -0,0 +1,31 @@ +package fr.gouv.cacem.monitorenv.infrastructure.database.repositories + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +class JpaControlPlanThemeRepositoryITests : AbstractDBTests() { + @Autowired private lateinit var jpaControlPlanThemeRepository: JpaControlPlanThemeRepository + + @Test + fun `findAll Should return all control plan themes`() { + // When + val requestedControlPlanThemes = jpaControlPlanThemeRepository.findAll() + // Then + assertThat(requestedControlPlanThemes.size).isEqualTo(23) + assertThat(requestedControlPlanThemes[5].id).isEqualTo(6) + assertThat(requestedControlPlanThemes[5].theme).isEqualTo("Divers") + } + + @Test + fun `findByYear Should return all control plan theme for a specific year`() { + // When + val requestedControlPlanThemesFor2023 = jpaControlPlanThemeRepository.findByYear(2023) + val requestedControlPlanThemesFor2024 = jpaControlPlanThemeRepository.findByYear(2024) + // Then + assertThat(requestedControlPlanThemesFor2023.size).isEqualTo(83) + assertThat(requestedControlPlanThemesFor2024.size).isEqualTo(12) + assertThat(requestedControlPlanThemesFor2024[5].id).isEqualTo(100001) + assertThat(requestedControlPlanThemesFor2024[5].theme).isEqualTo("Mouillage Individuel") + } +} diff --git a/frontend/src/features/missions/MissionForm/mission.json b/frontend/src/features/missions/MissionForm/mission.json deleted file mode 100644 index e69de29bb..000000000 From 1d1dac334cf45a387154ff5c20cbcb72acc26a34 Mon Sep 17 00:00:00 2001 From: Thomas Brosset <thomas.brosset@gmail.com> Date: Fri, 15 Dec 2023 10:48:11 +0100 Subject: [PATCH 38/53] Add control plans 2024 --- .../V0.105__add_control_plan_2024.sql | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql diff --git a/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql b/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql new file mode 100644 index 000000000..0a34bb7ee --- /dev/null +++ b/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql @@ -0,0 +1,119 @@ +INSERT INTO control_plan_themes (id, theme) VALUES +(100,'Mouillage individuel') +(101,'Zone de mouillage et d''équipement léger (ZMEL)') +(102,'Rejet') +(103,'Espèce protégée et leur habitat (faune et flore)') +(104,'Bien culturel maritime') +(105,'Épave') +(106,'Activité et manifestation soumises à évaluation d''incidence Natura 2003') +(107,'Domanialité publique (circulation et dégradation)') +(108,'Culture marine') +(109,'Travaux en milieu marin') +(110,'Arrêté à visa environnemental') +(111,'Parc national') +(112,'Réserve naturelle') +(113,'Arrêté de protection') +(114,'Autres') +(115,'Pêche à pied') +(116,'Pêche de loisir (autre que PAP)') +(117,'Surveillance générale'); + +SELECT setval('control_plans_themes_id_seq', (SELECT max(id) FROM control_plans_themes), true); + +INSERT INTO control_plan_tags (id,theme_id,tag) VALUES +(10,103,'Mammifères marins'), +(11,103,'Oiseaux'), +(12,103,'Reptiles'), +(13,103,'Poissons'), +(14,103,'Flore'), +(15,103,'Habitat'), +(16,103,'Autres espèces protégées'), +(17,115,'Bichique'), +(18,115,'Civelle'), +(19,115,'Filet fixe'), +(20,115,'Autre'); + +SELECT setval('control_plan_tags_id_seq', (SELECT max(id) FROM control_plan_tags), true); + + +INSERT INTO control_plan_sub_themes (id,theme_id,subtheme,year) VALUES +(100,100,'Mouillage réglementé par arrêté',2024), +(101,100,'Mouillage réglementé par AMP',2024), +(102,100,'Mouillage avec AOT individuelle',2024), +(103,100,'Autre mouillage individuel',2024), +(104,101,'Gestionnaire ZMEL',2024), +(105,101,'Usagers ZMEL',2024), +(106,101,'Autre (ZMEL)',2024), +(107,102,'Jet de déchet (macro déchet)',2024), +(108,102,'Carénage sauvage',2024), +(109,102,'Rejet d''eau grise / eau noire',2024), +(110,102,'Rejet d''hydrocarbure',2024), +(111,102,'Eaux de ballast',2024), +(112,102,'Pollutions associées aux opérations d''exploration, d''exploitation, d''immersion et d''incinération',2024), +(113,102,'Rejets atmosphériques ',2024), +(114,102,'Avitaillement, soutage, transbordement',2024), +(115,102,'Rejet réglementé par AMP',2024), +(116,102,'Autre rejet',2024), +(117,103,'Destruction, capture, arrachage d''espèces protégées',2024), +(118,103,'Atteinte aux habitats d''espèces protégées',2024), +(119,103,'Transport, vente, exportation, commerce d''espèces protégées',2024), +(120,103,'Détention des espèces protégées',2024), +(121,103,'Dérogations relatives aux espèces protégées et aux habitats d''espèces protégées',2024), +(122,103,'Dérangement / perturbation intentionnelle des espèces animales protégées',2024), +(123,103,'Autre (Espèce protégée et leur habitat)',2024), +(124,104,'Prospection d''un bien culturel maritime',2024), +(125,104,'Aliénation/acquisition d''un bien culturel maritime',2024), +(126,104,'Déplacement/prélèvement/atteinte d''un bien culturel maritime',2024), +(127,104,'Autre (Bien culturel maritime)',2024), +(128,105,'Découverte d''une épave maritime',2024), +(129,105,'Recel ou détournement d''une épave maritime',2024), +(130,105,'Épave / Navire abandonné',2024), +(131,105,'Autre (Épave)',2024), +(132,106,'Existence d''une évaluation d''incidence Natura 2000',2024), +(133,106,'Prescriptions environnementales des manifestations / activités dans une zone Natura 2000',2024), +(134,106,'Travaux dans une zone Natura 2000',2024), +(135,106,'Charte Natura 2000',2024), +(136,106,'Autre (EIN2000)',2024), +(137,107,'Circulation des VTM sur le DPM',2024), +(138,107,'Respect des espaces balisés',2024), +(139,107,'Dégradation du DPM',2024), +(140,107,'Autre (DPM)',2024), +(141,108,'Prescriptions réglementaires des concessions d''exploitation de culture marine',2024), +(142,108,'Remise en état après occupation du DPM',2024), +(143,108,'Implantation',2024), +(144,108,'Autre (Culture marine)',2024), +(145,109,'Dragage',2024), +(146,109,'Clapage',2024), +(147,109,'Extraction de granulats ',2024), +(148,109,'Chantier marin',2024), +(149,109,'Chantier portuaire',2024), +(150,109,'Travaux réglementés par AMP',2024), +(151,109,'Autres travaux en mer',2024), +(152,110,'Arrêtés municipaux réglementant certaines activités avec un impact sur l''environnement marin ',2024), +(153,110,'Arrêtés du préfet de département réglementant certaines activités avec un impact sur l''environnement marin',2024), +(154,110,'Arrêtés du préfet maritime réglementant certaines activités avec un impact sur l''environnement marin ',2024), +(155,110,'Autres arrêtés réglementant certaines activités avec un impact sur l''environnement marin ',2024), +(156,111,'Réglementation du parc national',2024), +(157,111,'Autre (Parc national)',2024), +(158,112,'Réglementation de la réserve naturelle',2024), +(159,112,'Autre (Réserve naturelle)',2024), +(160,113,'Réglementation de l''arrêté de protection',2024), +(161,113,'Autre (Arrêté de protection)',2024), +(162,114,'Drone',2024), +(163,114,'Introduction d''espèce dans le milieu naturel ',2024), +(164,114,'Dérogation d''introduction d''espèce',2024), +(165,114,'Campagnes scientifiques',2024), +(166,114,'Manifestation sur le DPM avec prescriptions environnementales',2024), +(167,114,'Chasse sur le DPM',2024), +(168,114,'Autre',2024), +(169,115,'Pêche à pied de loisir',2024), +(170,115,'Pêche à pied professionnelle',2024), +(171,115,'Engin non-marqué',2024), +(172,115,'Autre (Pêche à pied)',2024), +(173,116,'Pêche embarquée',2024), +(174,116,'Pêche sous-marine',2024), +(175,116,'Engin non-marqué',2024), +(176,116,'Autre (Pêche de loisir hors PAP)',2024), +(177,117,'Surveillance générale',2024); + +SELECT setval('control_plan_sub_themes_id_seq', (SELECT max(id) FROM control_plan_sub_themes), true); \ No newline at end of file From ccc00233974866fd64c7efa017b86c3d06278f5d Mon Sep 17 00:00:00 2001 From: Thomas Brosset <thomas.brosset@gmail.com> Date: Fri, 15 Dec 2023 11:27:53 +0100 Subject: [PATCH 39/53] insert new themes --- .../V0.105__add_control_plan_2024.sql | 130 ++++++++++++------ 1 file changed, 86 insertions(+), 44 deletions(-) diff --git a/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql b/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql index 0a34bb7ee..e3db75652 100644 --- a/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql +++ b/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql @@ -1,24 +1,25 @@ INSERT INTO control_plan_themes (id, theme) VALUES -(100,'Mouillage individuel') -(101,'Zone de mouillage et d''équipement léger (ZMEL)') -(102,'Rejet') -(103,'Espèce protégée et leur habitat (faune et flore)') -(104,'Bien culturel maritime') -(105,'Épave') -(106,'Activité et manifestation soumises à évaluation d''incidence Natura 2003') -(107,'Domanialité publique (circulation et dégradation)') -(108,'Culture marine') -(109,'Travaux en milieu marin') -(110,'Arrêté à visa environnemental') -(111,'Parc national') -(112,'Réserve naturelle') -(113,'Arrêté de protection') -(114,'Autres') -(115,'Pêche à pied') -(116,'Pêche de loisir (autre que PAP)') +(100,'Mouillage individuel'), +(101,'Zone de mouillage et d''équipement léger (ZMEL)'), +(102,'Rejet'), +(103,'Espèce protégée et leur habitat (faune et flore)'), +(104,'Bien culturel maritime'), +(105,'Épave'), +(107,'Domanialité publique (circulation et dégradation)'), +(108,'Culture marine'), +(111,'Parc national'), +(112,'Réserve naturelle'), +(113,'Arrêté de protection'), +(114,'Autres'), +(116,'Pêche de loisir (autre que PAP)'), (117,'Surveillance générale'); -SELECT setval('control_plans_themes_id_seq', (SELECT max(id) FROM control_plans_themes), true); +-- (106,'Activité et manifestation soumises à évaluation d’incidence Natura 2000'), +-- (109,'Travaux en milieu marin'), +-- (110,'Arrêté à visa environnemental'), +-- (115,'Pêche à pied'), + +SELECT setval('control_plans_themes_id_seq', (SELECT max(id) FROM control_plan_themes), true); INSERT INTO control_plan_tags (id,theme_id,tag) VALUES (10,103,'Mammifères marins'), @@ -27,11 +28,17 @@ INSERT INTO control_plan_tags (id,theme_id,tag) VALUES (13,103,'Poissons'), (14,103,'Flore'), (15,103,'Habitat'), -(16,103,'Autres espèces protégées'), -(17,115,'Bichique'), -(18,115,'Civelle'), -(19,115,'Filet fixe'), -(20,115,'Autre'); +(16,103,'Autres espèces protégées'); + +INSERT INTO control_plan_tags (id,tag,theme_id) + SELECT new_tags.*, existing_theme.id FROM (VALUES + (17,'Bichique'), + (18,'Civelle'), + (19,'Filet fixe'), + (20,'Autre')) as new_tags, + ( + SELECT id FROM control_plan_themes + WHERE theme = 'Pêche à pied') existing_theme; SELECT setval('control_plan_tags_id_seq', (SELECT max(id) FROM control_plan_tags), true); @@ -69,11 +76,6 @@ INSERT INTO control_plan_sub_themes (id,theme_id,subtheme,year) VALUES (129,105,'Recel ou détournement d''une épave maritime',2024), (130,105,'Épave / Navire abandonné',2024), (131,105,'Autre (Épave)',2024), -(132,106,'Existence d''une évaluation d''incidence Natura 2000',2024), -(133,106,'Prescriptions environnementales des manifestations / activités dans une zone Natura 2000',2024), -(134,106,'Travaux dans une zone Natura 2000',2024), -(135,106,'Charte Natura 2000',2024), -(136,106,'Autre (EIN2000)',2024), (137,107,'Circulation des VTM sur le DPM',2024), (138,107,'Respect des espaces balisés',2024), (139,107,'Dégradation du DPM',2024), @@ -82,17 +84,6 @@ INSERT INTO control_plan_sub_themes (id,theme_id,subtheme,year) VALUES (142,108,'Remise en état après occupation du DPM',2024), (143,108,'Implantation',2024), (144,108,'Autre (Culture marine)',2024), -(145,109,'Dragage',2024), -(146,109,'Clapage',2024), -(147,109,'Extraction de granulats ',2024), -(148,109,'Chantier marin',2024), -(149,109,'Chantier portuaire',2024), -(150,109,'Travaux réglementés par AMP',2024), -(151,109,'Autres travaux en mer',2024), -(152,110,'Arrêtés municipaux réglementant certaines activités avec un impact sur l''environnement marin ',2024), -(153,110,'Arrêtés du préfet de département réglementant certaines activités avec un impact sur l''environnement marin',2024), -(154,110,'Arrêtés du préfet maritime réglementant certaines activités avec un impact sur l''environnement marin ',2024), -(155,110,'Autres arrêtés réglementant certaines activités avec un impact sur l''environnement marin ',2024), (156,111,'Réglementation du parc national',2024), (157,111,'Autre (Parc national)',2024), (158,112,'Réglementation de la réserve naturelle',2024), @@ -106,14 +97,65 @@ INSERT INTO control_plan_sub_themes (id,theme_id,subtheme,year) VALUES (166,114,'Manifestation sur le DPM avec prescriptions environnementales',2024), (167,114,'Chasse sur le DPM',2024), (168,114,'Autre',2024), -(169,115,'Pêche à pied de loisir',2024), -(170,115,'Pêche à pied professionnelle',2024), -(171,115,'Engin non-marqué',2024), -(172,115,'Autre (Pêche à pied)',2024), (173,116,'Pêche embarquée',2024), (174,116,'Pêche sous-marine',2024), (175,116,'Engin non-marqué',2024), (176,116,'Autre (Pêche de loisir hors PAP)',2024), -(177,117,'Surveillance générale',2024); +(177,117,'Surveillance générale',2024) +; + + +INSERT INTO control_plan_sub_themes (id,subtheme,year,theme_id) + SELECT new_sub_themes.*, existing_theme.id FROM (VALUES + (132,'Existence d''une évaluation d''incidence Natura 2000',2024), + (133,'Prescriptions environnementales des manifestations / activités dans une zone Natura 2000',2024), + (134,'Travaux dans une zone Natura 2000',2024), + (135,'Charte Natura 2000',2024), + (136,'Autre (EIN2000)',2024)) as new_sub_themes, + ( + SELECT id FROM control_plan_themes + WHERE theme = 'Activités et manifestations soumises à évaluation d’incidence Natura 2000') existing_theme +; + + +INSERT INTO control_plan_sub_themes (id,subtheme,year,theme_id) + SELECT new_sub_themes.*, existing_theme.id FROM (VALUES + (145,'Dragage',2024), + (146,'Clapage',2024), + (147,'Extraction de granulats ',2024), + (148,'Chantier marin',2024), + (149,'Chantier portuaire',2024), + (150,'Travaux réglementés par AMP',2024), + (151,'Autres travaux en mer',2024)) as new_sub_themes, + ( + SELECT id FROM control_plan_themes + WHERE theme = 'Travaux en milieu marin') existing_theme +; + + +INSERT INTO control_plan_sub_themes (id,subtheme,year,theme_id) + SELECT new_sub_themes.*, existing_theme.id FROM (VALUES + (152,'Arrêtés municipaux réglementant certaines activités avec un impact sur l''environnement marin ',2024), + (153,'Arrêtés du préfet de département réglementant certaines activités avec un impact sur l''environnement marin',2024), + (154,'Arrêtés du préfet maritime réglementant certaines activités avec un impact sur l''environnement marin ',2024), + (155,'Autres arrêtés réglementant certaines activités avec un impact sur l''environnement marin ',2024) +) as new_sub_themes, + ( + SELECT id FROM control_plan_themes + WHERE theme = 'Arrêté à visa environnemental') existing_theme +; + +INSERT INTO control_plan_sub_themes (id,subtheme,year,theme_id) + SELECT new_sub_themes.*, existing_theme.id FROM (VALUES + (169,'Pêche à pied de loisir',2024), + (170,'Pêche à pied professionnelle',2024), + (171,'Engin non-marqué',2024), + (172,'Autre (Pêche à pied)',2024) +) as new_sub_themes, + ( + SELECT id FROM control_plan_themes + WHERE theme = 'Pêche à pied') existing_theme +; + SELECT setval('control_plan_sub_themes_id_seq', (SELECT max(id) FROM control_plan_sub_themes), true); \ No newline at end of file From f413ba2e38e95866d3d161c3fd72e1b433bd5081 Mon Sep 17 00:00:00 2001 From: Thomas Brosset <thomas.brosset@gmail.com> Date: Fri, 15 Dec 2023 11:43:44 +0100 Subject: [PATCH 40/53] fix data, renumber ids --- .../V0.105__add_control_plan_2024.sql | 83 ++++++++++--------- ...6.08__insert_dummy_control_plan_themes.sql | 24 ------ .../V666.10__insert_dummy_env_actions.sql | 52 ++++++------ 3 files changed, 68 insertions(+), 91 deletions(-) delete mode 100644 backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql diff --git a/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql b/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql index e3db75652..a7161037f 100644 --- a/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql +++ b/backend/src/main/resources/db/migration/internal/V0.105__add_control_plan_2024.sql @@ -5,21 +5,22 @@ INSERT INTO control_plan_themes (id, theme) VALUES (103,'Espèce protégée et leur habitat (faune et flore)'), (104,'Bien culturel maritime'), (105,'Épave'), -(107,'Domanialité publique (circulation et dégradation)'), -(108,'Culture marine'), -(111,'Parc national'), -(112,'Réserve naturelle'), -(113,'Arrêté de protection'), -(114,'Autres'), -(116,'Pêche de loisir (autre que PAP)'), -(117,'Surveillance générale'); - --- (106,'Activité et manifestation soumises à évaluation d’incidence Natura 2000'), --- (109,'Travaux en milieu marin'), --- (110,'Arrêté à visa environnemental'), --- (115,'Pêche à pied'), - -SELECT setval('control_plans_themes_id_seq', (SELECT max(id) FROM control_plan_themes), true); +(106,'Domanialité publique (circulation et dégradation)'), +(107,'Culture marine'), +(108,'Parc national'), +(109,'Réserve naturelle'), +(110,'Arrêté de protection'), +(111,'Autres'), +(112,'Pêche de loisir (autre que PAP)'), +(113,'Surveillance générale'); + +-- Thématiques existantes pour lesquels une recherche doit être faite pour récupérer l'identifiant +-- Activité et manifestation soumises à évaluation d’incidence Natura 2000 +-- Travaux en milieu marin +-- Arrêté à visa environnemental +-- Pêche à pied + +SELECT setval('control_plan_themes_id_seq', (SELECT max(id) FROM control_plan_themes), true); INSERT INTO control_plan_tags (id,theme_id,tag) VALUES (10,103,'Mammifères marins'), @@ -76,32 +77,32 @@ INSERT INTO control_plan_sub_themes (id,theme_id,subtheme,year) VALUES (129,105,'Recel ou détournement d''une épave maritime',2024), (130,105,'Épave / Navire abandonné',2024), (131,105,'Autre (Épave)',2024), -(137,107,'Circulation des VTM sur le DPM',2024), -(138,107,'Respect des espaces balisés',2024), -(139,107,'Dégradation du DPM',2024), -(140,107,'Autre (DPM)',2024), -(141,108,'Prescriptions réglementaires des concessions d''exploitation de culture marine',2024), -(142,108,'Remise en état après occupation du DPM',2024), -(143,108,'Implantation',2024), -(144,108,'Autre (Culture marine)',2024), -(156,111,'Réglementation du parc national',2024), -(157,111,'Autre (Parc national)',2024), -(158,112,'Réglementation de la réserve naturelle',2024), -(159,112,'Autre (Réserve naturelle)',2024), -(160,113,'Réglementation de l''arrêté de protection',2024), -(161,113,'Autre (Arrêté de protection)',2024), -(162,114,'Drone',2024), -(163,114,'Introduction d''espèce dans le milieu naturel ',2024), -(164,114,'Dérogation d''introduction d''espèce',2024), -(165,114,'Campagnes scientifiques',2024), -(166,114,'Manifestation sur le DPM avec prescriptions environnementales',2024), -(167,114,'Chasse sur le DPM',2024), -(168,114,'Autre',2024), -(173,116,'Pêche embarquée',2024), -(174,116,'Pêche sous-marine',2024), -(175,116,'Engin non-marqué',2024), -(176,116,'Autre (Pêche de loisir hors PAP)',2024), -(177,117,'Surveillance générale',2024) +(137,106,'Circulation des VTM sur le DPM',2024), +(138,106,'Respect des espaces balisés',2024), +(139,106,'Dégradation du DPM',2024), +(140,106,'Autre (DPM)',2024), +(141,107,'Prescriptions réglementaires des concessions d''exploitation de culture marine',2024), +(142,107,'Remise en état après occupation du DPM',2024), +(143,107,'Implantation',2024), +(144,107,'Autre (Culture marine)',2024), +(156,108,'Réglementation du parc national',2024), +(157,108,'Autre (Parc national)',2024), +(158,109,'Réglementation de la réserve naturelle',2024), +(159,109,'Autre (Réserve naturelle)',2024), +(160,110,'Réglementation de l''arrêté de protection',2024), +(161,110,'Autre (Arrêté de protection)',2024), +(162,111,'Drone',2024), +(163,111,'Introduction d''espèce dans le milieu naturel ',2024), +(164,111,'Dérogation d''introduction d''espèce',2024), +(165,111,'Campagnes scientifiques',2024), +(166,111,'Manifestation sur le DPM avec prescriptions environnementales',2024), +(167,111,'Chasse sur le DPM',2024), +(168,111,'Autre',2024), +(173,112,'Pêche embarquée',2024), +(174,112,'Pêche sous-marine',2024), +(175,112,'Engin non-marqué',2024), +(176,112,'Autre (Pêche de loisir hors PAP)',2024), +(177,113,'Surveillance générale',2024) ; diff --git a/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql b/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql deleted file mode 100644 index 7483afe97..000000000 --- a/backend/src/main/resources/db/testdata/V666.08__insert_dummy_control_plan_themes.sql +++ /dev/null @@ -1,24 +0,0 @@ - -INSERT INTO control_plan_themes (id, theme) VALUES (100001, 'Mouillage Individuel'); -INSERT INTO control_plan_themes (id, theme) VALUES (100002, 'Rejet'); -INSERT INTO control_plan_themes (id, theme) VALUES (100003, 'Épave'); - -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Mouillage réglementé par arrêté', 100001, 2024); -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Mouillage réglementé par AMP', 100001, 2024); -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Mouillage avec AOT individuelle', 100001, 2024); -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Autre mouillage', 100001, 2024); -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Rejet d’hydrocarbure', 100002, 2024); -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Découverte d’une épave maritime', 100003, 2024); -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Recel ou détournement d’une épave maritime', 100003, 2024); -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Épave / Navire abandonné', 100003, 2024); -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Autre (Épave)', 100003, 2024); - - -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) - SELECT 'Destruction, capture, arrachage', id, 2024 - FROM control_plan_themes - WHERE theme = 'Police des espèces protégées et de leurs habitats (faune et flore)'; - -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Dérogations relatives aux espèces protégées et aux habitats d’espèces protégées', 11, 2024); -INSERT INTO control_plan_sub_themes (subtheme, theme_id, year) VALUES ('Détention des espèces protégées', 11, 2024); - diff --git a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql index 1dbcb299f..f7f6736b3 100644 --- a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql +++ b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql @@ -27,31 +27,31 @@ UPDATE public.env_actions SET WHERE mission_id > 20; ; -INSERT INTO public.env_actions_control_plan_themes (env_action_id, theme_id) VALUES -('b8007c8a-5135-4bc3-816f-c69c7b75d807', 100001), -('475d2887-5344-46cd-903b-8cb5e42f9a9c', 16), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 11), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 100001), -('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 15), -('e2257638-ddef-4611-960c-7675a3254c38', 9), -('4d9a3139-6c60-49a5-b443-0e6238a6a120', 12), -('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 1) -; +-- INSERT INTO public.env_actions_control_plan_themes (env_action_id, theme_id) VALUES +-- ('b8007c8a-5135-4bc3-816f-c69c7b75d807', 100), +-- ('475d2887-5344-46cd-903b-8cb5e42f9a9c', 16), +-- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 11), +-- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 100), +-- ('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 15), +-- ('e2257638-ddef-4611-960c-7675a3254c38', 9), +-- ('4d9a3139-6c60-49a5-b443-0e6238a6a120', 12), +-- ('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 1) +-- ; -INSERT INTO public.env_actions_control_plan_sub_themes(env_action_id, subtheme_id) VALUES -('e2257638-ddef-4611-960c-7675a3254c38', 51), -('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 83), -('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 43), -('475d2887-5344-46cd-903b-8cb5e42f9a9c', 79), -('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 48), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 84), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 85), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 93), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 95), -('b8007c8a-5135-4bc3-816f-c69c7b75d807', 86), -('4d9a3139-6c60-49a5-b443-0e6238a6a120', 42) -; +-- INSERT INTO public.env_actions_control_plan_sub_themes(env_action_id, subtheme_id) VALUES +-- ('e2257638-ddef-4611-960c-7675a3254c38', 51), +-- ('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 83), +-- ('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 43), +-- ('475d2887-5344-46cd-903b-8cb5e42f9a9c', 79), +-- ('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 48), +-- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 84), +-- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 85), +-- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 93), +-- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 95), +-- ('b8007c8a-5135-4bc3-816f-c69c7b75d807', 86), +-- ('4d9a3139-6c60-49a5-b443-0e6238a6a120', 42) +-- ; -INSERT INTO public.env_actions_control_plan_tags(env_action_id, tag_id) VALUES -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 1), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 2); +-- INSERT INTO public.env_actions_control_plan_tags(env_action_id, tag_id) VALUES +-- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 1), +-- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 2); From d0076b28b186c200a63c45dc804f64d64b1df1ac Mon Sep 17 00:00:00 2001 From: Thomas Brosset <thomas.brosset@gmail.com> Date: Fri, 15 Dec 2023 14:21:00 +0100 Subject: [PATCH 41/53] maj test front --- .../side_window/mission_form/mission_actions.spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts b/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts index 9d4cc9e68..c56d5876f 100644 --- a/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts @@ -48,7 +48,7 @@ context('Mission actions', () => { cy.get('*[data-cy="edit-mission-34"]').click({ force: true }) cy.get('*[data-cy="action-card"]').eq(1).click() cy.get('*[data-cy="envaction-theme-element"]').should('have.length', 1) - cy.get('*[data-cy="envaction-theme-selector"]').contains('Mouillage Individuel') // id 100001 + cy.get('*[data-cy="envaction-theme-selector"]').contains('Mouillage Individuel') // id 100 cy.get('*[data-cy="envaction-theme-element"]').contains('Mouillage avec AOT individuelle') // id 86 cy.get('*[data-cy="envaction-tags-selector"]').should('not.exist') // When @@ -130,11 +130,11 @@ context('Mission actions', () => { // When cy.get('*[data-cy="envaction-theme-selector"]').eq(0).click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').eq(0).contains('Épave').click() // id 100003 + cy.get('*[data-cy="envaction-theme-element"]').eq(0).contains('Épave').click() // id 105 cy.get('*[data-cy="envaction-add-theme"]').click({ force: true }) cy.get('*[data-cy="envaction-theme-selector"]').eq(2).click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').eq(2).contains('Rejet').click() // id 100002 + cy.get('*[data-cy="envaction-theme-element"]').eq(2).contains('Rejet').click() // id 102 cy.get('*[data-cy="envaction-subtheme-selector"]').eq(2).click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').eq(2).contains('Rejet d’hydrocarbure').click({ force: true }) // id 88 @@ -151,17 +151,17 @@ context('Mission actions', () => { const { controlPlans } = response && response.body.envActions.find(a => a.id === 'c52c6f20-e495-4b29-b3df-d7edfb67fdd7') expect(controlPlans.length).equal(3) - expect(controlPlans[0].themeId).equal(100001) + expect(controlPlans[0].themeId).equal(100) expect(controlPlans[0].subThemeIds.length).equal(2) expect(controlPlans[0].subThemeIds[0]).equal(84) expect(controlPlans[0].subThemeIds[1]).equal(85) expect(controlPlans[0].tagIds.length).equal(0) - expect(controlPlans[1].themeId).equal(100003) + expect(controlPlans[1].themeId).equal(105) expect(controlPlans[1].subThemeIds.length).equal(0) expect(controlPlans[1].tagIds.length).equal(0) - expect(controlPlans[2].themeId).equal(100002) + expect(controlPlans[2].themeId).equal(102) expect(controlPlans[2].subThemeIds.length).equal(1) expect(controlPlans[2].subThemeIds[0]).equal(88) expect(controlPlans[2].tagIds.length).equal(0) From 9a1ff3b4af1e763d7612b965790c15048b89e19f Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Fri, 15 Dec 2023 14:53:00 +0100 Subject: [PATCH 42/53] [Tests] clean tests back --- .../V666.10__insert_dummy_env_actions.sql | 52 +++++++++---------- .../JpaControlPlanSubThemeRepositoryITests.kt | 11 ++-- .../JpaControlPlanTagRepositoryITests.kt | 12 ++--- .../JpaControlPlanThemeRepositoryITests.kt | 9 ++-- .../mission_form/mission_actions.spec.ts | 10 ++-- 5 files changed, 48 insertions(+), 46 deletions(-) diff --git a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql index f7f6736b3..809b0212d 100644 --- a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql +++ b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql @@ -27,31 +27,31 @@ UPDATE public.env_actions SET WHERE mission_id > 20; ; --- INSERT INTO public.env_actions_control_plan_themes (env_action_id, theme_id) VALUES --- ('b8007c8a-5135-4bc3-816f-c69c7b75d807', 100), --- ('475d2887-5344-46cd-903b-8cb5e42f9a9c', 16), --- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 11), --- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 100), --- ('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 15), --- ('e2257638-ddef-4611-960c-7675a3254c38', 9), --- ('4d9a3139-6c60-49a5-b443-0e6238a6a120', 12), --- ('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 1) --- ; +INSERT INTO public.env_actions_control_plan_themes (env_action_id, theme_id) VALUES +('b8007c8a-5135-4bc3-816f-c69c7b75d807', 100), +('475d2887-5344-46cd-903b-8cb5e42f9a9c', 16), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 103), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 100), +('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 15), +('e2257638-ddef-4611-960c-7675a3254c38', 9), +('4d9a3139-6c60-49a5-b443-0e6238a6a120', 12), +('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 1) +; --- INSERT INTO public.env_actions_control_plan_sub_themes(env_action_id, subtheme_id) VALUES --- ('e2257638-ddef-4611-960c-7675a3254c38', 51), --- ('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 83), --- ('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 43), --- ('475d2887-5344-46cd-903b-8cb5e42f9a9c', 79), --- ('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 48), --- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 84), --- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 85), --- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 93), --- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 95), --- ('b8007c8a-5135-4bc3-816f-c69c7b75d807', 86), --- ('4d9a3139-6c60-49a5-b443-0e6238a6a120', 42) --- ; +INSERT INTO public.env_actions_control_plan_sub_themes(env_action_id, subtheme_id) VALUES +('e2257638-ddef-4611-960c-7675a3254c38', 51), +('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 83), +('f3e90d3a-6ba4-4bb3-805e-d391508aa46d', 43), +('475d2887-5344-46cd-903b-8cb5e42f9a9c', 79), +('6d4b7d0a-79ce-47cf-ac26-2024d2b27f28', 48), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 100), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 102), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 117), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 118), +('b8007c8a-5135-4bc3-816f-c69c7b75d807', 102), +('4d9a3139-6c60-49a5-b443-0e6238a6a120', 42) +; --- INSERT INTO public.env_actions_control_plan_tags(env_action_id, tag_id) VALUES --- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 1), --- ('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 2); +INSERT INTO public.env_actions_control_plan_tags(env_action_id, tag_id) VALUES +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 1), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 2); diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt index 508abe92b..b355a573a 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanSubThemeRepositoryITests.kt @@ -13,7 +13,7 @@ class JpaControlPlanSubThemeRepositoryITests : AbstractDBTests() { // When val requestedControlPlanSubThemes = jpaControlPlanSubThemeRepository.findAll() // Then - assertThat(requestedControlPlanSubThemes.size).isEqualTo(95) + assertThat(requestedControlPlanSubThemes.size).isEqualTo(161) assertThat(requestedControlPlanSubThemes[5].id).isEqualTo(6) assertThat(requestedControlPlanSubThemes[5].themeId).isEqualTo(4) assertThat(requestedControlPlanSubThemes[5].subTheme) @@ -24,18 +24,19 @@ class JpaControlPlanSubThemeRepositoryITests : AbstractDBTests() { assertThat(requestedControlPlanSubThemes[5].year).isEqualTo(2023) } + @Test fun `findByYear Should return all control plan theme for a specific year`() { // When val requestedControlPlanSubThemesFor2023 = jpaControlPlanSubThemeRepository.findByYear(2023) val requestedControlPlanSubThemesFor2024 = jpaControlPlanSubThemeRepository.findByYear(2024) // Then assertThat(requestedControlPlanSubThemesFor2023.size).isEqualTo(83) - assertThat(requestedControlPlanSubThemesFor2024.size).isEqualTo(6) - assertThat(requestedControlPlanSubThemesFor2024[5].id).isEqualTo(6) - assertThat(requestedControlPlanSubThemesFor2024[5].themeId).isEqualTo(11) + assertThat(requestedControlPlanSubThemesFor2024.size).isEqualTo(78) + assertThat(requestedControlPlanSubThemesFor2024[5].id).isEqualTo(105) + assertThat(requestedControlPlanSubThemesFor2024[5].themeId).isEqualTo(101) assertThat(requestedControlPlanSubThemesFor2024[5].subTheme) .isEqualTo( - "Destruction, capture, arrachage", + "Usagers ZMEL", ) assertThat(requestedControlPlanSubThemesFor2024[5].year).isEqualTo(2024) diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt index 1ddd04a4d..6f96a6f95 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanTagRepositoryITests.kt @@ -12,7 +12,7 @@ class JpaControlPlanTagRepositoryITests : AbstractDBTests() { // When val requestedControlPlanTags = jpaControlPlanTagRepository.findAll() // Then - assertThat(requestedControlPlanTags.size).isEqualTo(6) + assertThat(requestedControlPlanTags.size).isEqualTo(17) assertThat(requestedControlPlanTags[5].id).isEqualTo(6) assertThat(requestedControlPlanTags[5].themeId).isEqualTo(11) assertThat(requestedControlPlanTags[5].tag) @@ -27,13 +27,13 @@ class JpaControlPlanTagRepositoryITests : AbstractDBTests() { val requestedControlPlanTagsFor2023 = jpaControlPlanTagRepository.findByYear(2023) val requestedControlPlanTagsFor2024 = jpaControlPlanTagRepository.findByYear(2024) // Then - assertThat(requestedControlPlanTagsFor2023.size).isEqualTo(48) - assertThat(requestedControlPlanTagsFor2024.size).isEqualTo(18) - assertThat(requestedControlPlanTagsFor2024[5].id).isEqualTo(2) - assertThat(requestedControlPlanTagsFor2024[5].themeId).isEqualTo(11) + assertThat(requestedControlPlanTagsFor2023.size).isEqualTo(68) + assertThat(requestedControlPlanTagsFor2024.size).isEqualTo(65) + assertThat(requestedControlPlanTagsFor2024[5].id).isEqualTo(10) + assertThat(requestedControlPlanTagsFor2024[5].themeId).isEqualTo(103) assertThat(requestedControlPlanTagsFor2024[5].tag) .isEqualTo( - "Habitat", + "Mammifères marins", ) } } diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt index e4154d0a0..b93afd52c 100644 --- a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/repositories/JpaControlPlanThemeRepositoryITests.kt @@ -12,7 +12,7 @@ class JpaControlPlanThemeRepositoryITests : AbstractDBTests() { // When val requestedControlPlanThemes = jpaControlPlanThemeRepository.findAll() // Then - assertThat(requestedControlPlanThemes.size).isEqualTo(23) + assertThat(requestedControlPlanThemes.size).isEqualTo(34) assertThat(requestedControlPlanThemes[5].id).isEqualTo(6) assertThat(requestedControlPlanThemes[5].theme).isEqualTo("Divers") } @@ -24,8 +24,9 @@ class JpaControlPlanThemeRepositoryITests : AbstractDBTests() { val requestedControlPlanThemesFor2024 = jpaControlPlanThemeRepository.findByYear(2024) // Then assertThat(requestedControlPlanThemesFor2023.size).isEqualTo(83) - assertThat(requestedControlPlanThemesFor2024.size).isEqualTo(12) - assertThat(requestedControlPlanThemesFor2024[5].id).isEqualTo(100001) - assertThat(requestedControlPlanThemesFor2024[5].theme).isEqualTo("Mouillage Individuel") + assertThat(requestedControlPlanThemesFor2024.size).isEqualTo(78) + assertThat(requestedControlPlanThemesFor2024[5].id).isEqualTo(3) + assertThat(requestedControlPlanThemesFor2024[5].theme) + .isEqualTo("Arrêté à visa environnemental") } } diff --git a/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts b/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts index c56d5876f..1d137b83c 100644 --- a/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts @@ -49,15 +49,15 @@ context('Mission actions', () => { cy.get('*[data-cy="action-card"]').eq(1).click() cy.get('*[data-cy="envaction-theme-element"]').should('have.length', 1) cy.get('*[data-cy="envaction-theme-selector"]').contains('Mouillage Individuel') // id 100 - cy.get('*[data-cy="envaction-theme-element"]').contains('Mouillage avec AOT individuelle') // id 86 + cy.get('*[data-cy="envaction-theme-element"]').contains('Mouillage avec AOT individuelle') // id 102 cy.get('*[data-cy="envaction-tags-selector"]').should('not.exist') // When cy.get('*[data-cy="envaction-theme-selector"]').click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').contains('Police des espèces protégées').click() // id 11 cy.get('*[data-cy="envaction-subtheme-selector"]').click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').contains('Destruction, capture, arrachage').click({ force: true }) // id 89 - cy.get('*[data-cy="envaction-theme-element"]').contains('Détention des espèces protégées').click({ force: true }) // id 91 + cy.get('*[data-cy="envaction-theme-element"]').contains('Destruction, capture, arrachage').click({ force: true }) // id 117 + cy.get('*[data-cy="envaction-theme-element"]').contains('Détention des espèces protégées').click({ force: true }) // id 120 cy.get('*[data-cy="envaction-subtheme-selector"]').click({ force: true }) cy.get('*[data-cy="envaction-tags-selector"]').should('exist') @@ -123,7 +123,7 @@ context('Mission actions', () => { cy.get('*[data-cy="envaction-theme-selector"]') .eq(0) .contains('Police des espèces protégées et de leurs habitats (faune et flore)') // id 11 - cy.get('*[data-cy="envaction-theme-element"]').contains('Destruction, capture, arrachage') // id 93 + cy.get('*[data-cy="envaction-theme-element"]').contains('Destruction, capture, arrachage') // id 117 cy.get('*[data-cy="envaction-tags-selector"]').should('exist') cy.get('*[data-cy="envaction-theme-element"]').contains('Habitat') // id 2 cy.get('*[data-cy="envaction-theme-element"]').contains('Oiseaux') // id 1 @@ -137,7 +137,7 @@ context('Mission actions', () => { cy.get('*[data-cy="envaction-theme-element"]').eq(2).contains('Rejet').click() // id 102 cy.get('*[data-cy="envaction-subtheme-selector"]').eq(2).click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').eq(2).contains('Rejet d’hydrocarbure').click({ force: true }) // id 88 + cy.get('*[data-cy="envaction-theme-element"]').eq(2).contains('Rejet d’hydrocarbure').click({ force: true }) // id 74 cy.get('*[data-cy="envaction-tags-selector"]').should('have.length', 0) From 604657d8b87c890245808a5bcd8a9b810386084a Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Fri, 15 Dec 2023 16:10:39 +0100 Subject: [PATCH 43/53] [Tests] fix tests e2e --- .../envAction/EnvActionControlPlanEntity.kt | 2 +- .../MissionEnvActionControlPlanDataInput.kt | 2 +- .../MissionEnvActionControlPlanDataOutput.kt | 2 +- .../database/model/EnvActionModel.kt | 1 + .../V666.10__insert_dummy_env_actions.sql | 4 +- .../mission_form/mission_actions.spec.ts | 39 +++++++++---------- .../mission_dates_validation.spec.ts | 4 +- .../domain/use_cases/missions/saveMission.ts | 2 +- .../MissionForm/Schemas/Surveillance.ts | 1 - 9 files changed, 28 insertions(+), 29 deletions(-) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanEntity.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanEntity.kt index f95890ad9..3dc60074c 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/entities/mission/envAction/EnvActionControlPlanEntity.kt @@ -1,7 +1,7 @@ package fr.gouv.cacem.monitorenv.domain.entities.mission.envAction data class EnvActionControlPlanEntity( - val themeId: Int, + val themeId: Int? = null, val subThemeIds: List<Int>? = emptyList(), val tagIds: List<Int>? = emptyList(), ) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionControlPlanDataInput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionControlPlanDataInput.kt index 69b8280e2..0eeaab81f 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionControlPlanDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/inputs/missions/MissionEnvActionControlPlanDataInput.kt @@ -5,7 +5,7 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionContr data class MissionEnvActionControlPlanDataInput( val subThemeIds: List<Int>? = emptyList(), val tagIds: List<Int>? = emptyList(), - val themeId: Int, + val themeId: Int? = null, ) { fun toEnvActionControlPlanEntity(): EnvActionControlPlanEntity { return EnvActionControlPlanEntity( diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlPlanDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlPlanDataOutput.kt index 96f577960..1b98751b5 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlPlanDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/adapters/bff/outputs/missions/MissionEnvActionControlPlanDataOutput.kt @@ -3,7 +3,7 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.mission import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.EnvActionControlPlanEntity data class MissionEnvActionControlPlanDataOutput( - val themeId: Int, + val themeId: Int? = null, val subThemeIds: List<Int>? = emptyList(), val tagIds: List<Int>? = emptyList(), ) { diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt index 061b14b46..14a355153 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/database/model/EnvActionModel.kt @@ -168,6 +168,7 @@ class EnvActionModel( value = EnvActionMapper.envActionEntityToJSON(mapper, action), ) action.controlPlans?.forEach { + if (it.themeId == null) return@forEach envActionModel.controlPlanThemes?.add( EnvActionsControlPlanThemeModel.fromEnvActionControlPlanThemeEntity( envAction = envActionModel, diff --git a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql index 809b0212d..1b5c27eb5 100644 --- a/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql +++ b/backend/src/main/resources/db/testdata/V666.10__insert_dummy_env_actions.sql @@ -53,5 +53,5 @@ INSERT INTO public.env_actions_control_plan_sub_themes(env_action_id, subtheme_i ; INSERT INTO public.env_actions_control_plan_tags(env_action_id, tag_id) VALUES -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 1), -('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 2); +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 11), +('c52c6f20-e495-4b29-b3df-d7edfb67fdd7', 15); diff --git a/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts b/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts index 1d137b83c..ee8b1c44a 100644 --- a/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/mission_actions.spec.ts @@ -48,12 +48,12 @@ context('Mission actions', () => { cy.get('*[data-cy="edit-mission-34"]').click({ force: true }) cy.get('*[data-cy="action-card"]').eq(1).click() cy.get('*[data-cy="envaction-theme-element"]').should('have.length', 1) - cy.get('*[data-cy="envaction-theme-selector"]').contains('Mouillage Individuel') // id 100 + cy.get('*[data-cy="envaction-theme-selector"]').contains('Mouillage individuel') // id 100 cy.get('*[data-cy="envaction-theme-element"]').contains('Mouillage avec AOT individuelle') // id 102 cy.get('*[data-cy="envaction-tags-selector"]').should('not.exist') // When cy.get('*[data-cy="envaction-theme-selector"]').click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').contains('Police des espèces protégées').click() // id 11 + cy.get('*[data-cy="envaction-theme-element"]').contains('Espèce protégée').click() // id 103 cy.get('*[data-cy="envaction-subtheme-selector"]').click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').contains('Destruction, capture, arrachage').click({ force: true }) // id 117 @@ -62,8 +62,8 @@ context('Mission actions', () => { cy.get('*[data-cy="envaction-tags-selector"]').should('exist') cy.get('*[data-cy="envaction-tags-selector"]').click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').contains('Habitat').click({ force: true }) // id 2 - cy.get('*[data-cy="envaction-theme-element"]').contains('Oiseaux').click({ force: true }) // id 1 + cy.get('*[data-cy="envaction-theme-element"]').contains('Habitat').click({ force: true }) // id 15 + cy.get('*[data-cy="envaction-theme-element"]').contains('Oiseaux').click({ force: true }) // id 11 cy.get('*[data-cy="envaction-tags-selector"]').click({ force: true }) cy.get('*[data-cy="envaction-add-theme"]').should('not.exist') @@ -78,14 +78,14 @@ context('Mission actions', () => { const { controlPlans } = request.body.envActions.find(a => a.id === 'b8007c8a-5135-4bc3-816f-c69c7b75d807') expect(controlPlans.length).equal(1) - expect(controlPlans[0].themeId).equal(11) + expect(controlPlans[0].themeId).equal(103) expect(controlPlans[0].subThemeIds.length).equal(2) - expect(controlPlans[0].subThemeIds[0]).equal(89) - expect(controlPlans[0].subThemeIds[1]).equal(91) + expect(controlPlans[0].subThemeIds[0]).equal(117) + expect(controlPlans[0].subThemeIds[1]).equal(120) expect(controlPlans[0].tagIds.length).equal(2) - expect(controlPlans[0].tagIds[0]).equal(1) - expect(controlPlans[0].tagIds[1]).equal(2) + expect(controlPlans[0].tagIds[0]).equal(11) + expect(controlPlans[0].tagIds[1]).equal(15) }) }) @@ -120,24 +120,22 @@ context('Mission actions', () => { cy.get('*[data-cy="edit-mission-34"]').click({ force: true }) cy.get('*[data-cy="action-card"]').eq(0).click() cy.get('*[data-cy="envaction-theme-element"]').should('have.length', 2) - cy.get('*[data-cy="envaction-theme-selector"]') - .eq(0) - .contains('Police des espèces protégées et de leurs habitats (faune et flore)') // id 11 + cy.get('*[data-cy="envaction-theme-selector"]').eq(0).contains('Espèce protégée et leur habitat (faune et flore)') // id 103 cy.get('*[data-cy="envaction-theme-element"]').contains('Destruction, capture, arrachage') // id 117 cy.get('*[data-cy="envaction-tags-selector"]').should('exist') - cy.get('*[data-cy="envaction-theme-element"]').contains('Habitat') // id 2 - cy.get('*[data-cy="envaction-theme-element"]').contains('Oiseaux') // id 1 + cy.get('*[data-cy="envaction-theme-element"]').contains('Habitat') // id 15 + cy.get('*[data-cy="envaction-theme-element"]').contains('Oiseaux') // id 11 // When cy.get('*[data-cy="envaction-theme-selector"]').eq(0).click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').eq(0).contains('Épave').click() // id 105 + cy.get('*[data-cy="envaction-theme-element"]').eq(0).contains('Épave').click({ force: true }) // id 105 cy.get('*[data-cy="envaction-add-theme"]').click({ force: true }) cy.get('*[data-cy="envaction-theme-selector"]').eq(2).click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').eq(2).contains('Rejet').click() // id 102 cy.get('*[data-cy="envaction-subtheme-selector"]').eq(2).click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').eq(2).contains('Rejet d’hydrocarbure').click({ force: true }) // id 74 + cy.get('*[data-cy="envaction-theme-element"]').eq(2).contains("Rejet d'hydrocarbure").click({ force: true }) // id 74 cy.get('*[data-cy="envaction-tags-selector"]').should('have.length', 0) @@ -151,19 +149,20 @@ context('Mission actions', () => { const { controlPlans } = response && response.body.envActions.find(a => a.id === 'c52c6f20-e495-4b29-b3df-d7edfb67fdd7') expect(controlPlans.length).equal(3) + expect(controlPlans[0].themeId).equal(100) expect(controlPlans[0].subThemeIds.length).equal(2) - expect(controlPlans[0].subThemeIds[0]).equal(84) - expect(controlPlans[0].subThemeIds[1]).equal(85) + expect(controlPlans[0].subThemeIds[0]).equal(100) + expect(controlPlans[0].subThemeIds[1]).equal(102) expect(controlPlans[0].tagIds.length).equal(0) - + 0 expect(controlPlans[1].themeId).equal(105) expect(controlPlans[1].subThemeIds.length).equal(0) expect(controlPlans[1].tagIds.length).equal(0) expect(controlPlans[2].themeId).equal(102) expect(controlPlans[2].subThemeIds.length).equal(1) - expect(controlPlans[2].subThemeIds[0]).equal(88) + expect(controlPlans[2].subThemeIds[0]).equal(110) expect(controlPlans[2].tagIds.length).equal(0) }) }) diff --git a/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts b/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts index 73066de7d..5d1339eb4 100644 --- a/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts @@ -37,7 +37,7 @@ context('Mission dates', () => { cy.clickButton('Ajouter une surveillance') cy.get('*[data-cy="envaction-theme-selector"]').click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').contains('Police des espèces protégées').click() + cy.get('*[data-cy="envaction-theme-element"]').contains('Espèce protégée').click() cy.get('*[data-cy="envaction-subtheme-selector"]').click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').contains('Destruction').click({ force: true }) cy.get('*[data-cy="envaction-subtheme-selector"]').click('topLeft', { force: true }) @@ -169,7 +169,7 @@ context('Mission dates', () => { cy.clickButton('Ajouter des contrôles') cy.get('*[data-cy="envaction-theme-selector"]').click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').contains('Police des espèces protégées').click() + cy.get('*[data-cy="envaction-theme-element"]').contains('Espèce protégée').click() cy.get('*[data-cy="envaction-subtheme-selector"]').click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').contains('Détention').click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').click('topLeft') diff --git a/frontend/src/domain/use_cases/missions/saveMission.ts b/frontend/src/domain/use_cases/missions/saveMission.ts index 91143cf59..a1f67301b 100644 --- a/frontend/src/domain/use_cases/missions/saveMission.ts +++ b/frontend/src/domain/use_cases/missions/saveMission.ts @@ -54,7 +54,7 @@ export const saveMission = reportings }) } else { - if (response.error.data.type === ApiErrorCode.CHILD_ALREADY_ATTACHED) { + if (response.error?.data?.type === ApiErrorCode.CHILD_ALREADY_ATTACHED) { throw Error('Le signalement est déjà rattaché à une mission') } throw Error('Erreur à la création ou à la modification de la mission') diff --git a/frontend/src/features/missions/MissionForm/Schemas/Surveillance.ts b/frontend/src/features/missions/MissionForm/Schemas/Surveillance.ts index 67c1e9120..78ab6c738 100644 --- a/frontend/src/features/missions/MissionForm/Schemas/Surveillance.ts +++ b/frontend/src/features/missions/MissionForm/Schemas/Surveillance.ts @@ -95,7 +95,6 @@ export const getClosedEnvActionSurveillanceSchema = (ctx: any): Yup.SchemaOf<Env }), actionType: Yup.mixed().oneOf([ActionTypeEnum.SURVEILLANCE]), controlPlans: Yup.array().of(ControlPlansSchema).ensure().required(), - geom: Yup.object().when('coverMissionZone', { is: true, otherwise: () => From dc0c30f5e6ceb176450fd078db9136ab519ca507 Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Fri, 15 Dec 2023 16:33:28 +0100 Subject: [PATCH 44/53] [Tests] fix test e2e --- .../side_window/mission_form/mission_dates_validation.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts b/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts index 5d1339eb4..dc82fa4ef 100644 --- a/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/mission_dates_validation.spec.ts @@ -94,7 +94,7 @@ context('Mission dates', () => { cy.clickButton('Ajouter une surveillance') cy.get('*[data-cy="envaction-theme-selector"]').click({ force: true }) - cy.get('*[data-cy="envaction-theme-element"]').contains('Mouillage Individuel').click() + cy.get('*[data-cy="envaction-theme-element"]').contains('Mouillage individuel').click() cy.get('*[data-cy="envaction-subtheme-selector"]').click({ force: true }) cy.get('*[data-cy="envaction-theme-element"]').contains('Autre').click({ force: true }) cy.get('*[data-cy="envaction-subtheme-selector"]').click('topLeft', { force: true }) From fa9d3e5b95c0dd100826abfb8b67c947a04a0822 Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Mon, 18 Dec 2023 08:57:19 +0100 Subject: [PATCH 45/53] [Reportings] fix tests e2e for reportings --- .../V666.12__insert_dummy_reportings.sql | 16 ++++++++-------- .../e2e/side_window/reporting/filters.spec.ts | 3 ++- .../features/Reportings/Filters/Table/index.tsx | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql b/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql index f3970017c..26a577b7b 100644 --- a/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql +++ b/backend/src/main/resources/db/testdata/V666.12__insert_dummy_reportings.sql @@ -1,13 +1,13 @@ DELETE FROM reportings; -INSERT INTO public.reportings VALUES (1, 2300001, 'SEMAPHORE', 21, NULL, NULL, 'VEHICLE', 'VESSEL', '[{"mmsi": "012314231343", "vesselName": "Vessel 1"}]', '0104000020E610000001000000010100000045035E406AC113C00CF3FE4C1D354840', 'NAMO', 'Description 1', 'INFRACTION_SUSPICION', 'Rejets illicites', '{"Jet de déchet","Carénage sauvage"}', 'ACTION TAKEN', true, true, '2023-12-05 18:27:58.191835', 24, false, false, NULL, NULL, NULL, NULL, NULL, 19); -INSERT INTO public.reportings VALUES (2, 2300002, 'SEMAPHORE', 23, NULL, NULL, 'VEHICLE', 'VESSEL', '[{"mmsi": "012314231344", "vesselName": "Vessel 2"}]', '0104000020E610000001000000010100000062C9C715311E13C050CB31D53D4F4840', 'NAMO', 'Description 2', 'INFRACTION_SUSPICION', 'Police des mouillages', '{ZMEL}', 'ACTION TAKEN', true, true, '2023-12-06 18:27:58.191835', 2, false, false, NULL, NULL, NULL, NULL, NULL, 12); -INSERT INTO public.reportings VALUES (3, 2300003, 'CONTROL_UNIT', NULL, 10000, NULL, 'VEHICLE', 'VESSEL', '[{"mmsi": "012314231345", "vesselName": "Vessel 3"}]', '0106000020E610000001000000010300000001000000040000006E15B8857C090CC02C07754424784840552A202082FC09C0C0FD120D667A484025BF296025E00BC0805DC2889C7F48406E15B8857C090CC02C07754424784840', 'NAMO', 'Description 3', 'INFRACTION_SUSPICION', 'Police des mouillages', '{ZMEL}', 'ACTION TAKEN', true, true, '2023-12-08 17:27:58.191835', 1, false, false, NULL, NULL, NULL, NULL, NULL, 12); -INSERT INTO public.reportings VALUES (4, 2300004, 'OTHER', NULL, NULL, 'MA SUPER SOCIETE', 'INDIVIDUAL', NULL, '[{"operatorName": "Mr le dirigeant"}]', '0106000020E6100000010000000103000000010000000500000012F330DDB98206C0CD5EF048C0BF4840FE7303CB321005C092CE3C90A7CC4840820740BBC76A06C07E8D665D8AD94840310109D4AC5507C002C775BEE5C2484012F330DDB98206C0CD5EF048C0BF4840', 'MED', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ultrices risus ac arcu pellentesque, et tempor justo tempor. Pellentesque sem nisl, tempor id augue non, interdum sollicitudin felis.', 'OBSERVATION', 'Pêche à pied', '{Braconnage}', NULL, true, true, '2023-12-08 15:27:58.191835', 4, false, false, NULL, NULL, NULL, NULL, NULL, 18); -INSERT INTO public.reportings VALUES (5, 2300005, 'SEMAPHORE', 36, NULL, NULL, 'COMPANY', NULL, '[{"vesselName": "Mr le gérant", "operatorName": "Ma société"}]', '0104000020E6100000010000000101000000417927B8BBBBD73F06D9D38A46E24840', 'Guadeloupe', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, '2023-12-08 17:27:58.191835', 6, false, false, NULL, NULL, NULL, NULL, NULL, NULL); -INSERT INTO public.reportings VALUES (6, 2300006, 'SEMAPHORE', 36, NULL, NULL, 'COMPANY', NULL, '[{"vesselName": "Héron", "operatorName": "La sociéter"}]', '0104000020E6100000010000000101000000A22CD736208DF9BF242A543717D44540', 'Guadeloupe', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', 'Police des mouillages', '{ZMEL}', NULL, true, true, '2023-12-08 17:12:58.191835', 6, false, false, 'ABC', 34, '2023-12-08 18:12:58.191835', NULL, 'b8007c8a-5135-4bc3-816f-c69c7b75d807', 12); -INSERT INTO public.reportings VALUES (7, 2300007, 'CONTROL_UNIT', NULL, 10001, NULL, 'COMPANY', NULL, '[{"vesselName": "Mr le gérant", "operatorName": "Good Company"}]', '0104000020E6100000010000000101000000BDAE0F9A19C010C068D780A5708E4740', 'NAMO', 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, '2023-12-08 16:57:58.191835', 6, false, false, 'DEF', 34, '2023-12-08 18:02:58.191835', NULL, NULL, NULL); -INSERT INTO public.reportings VALUES (8, 2300008, 'CONTROL_UNIT', NULL, 10001, NULL, 'COMPANY', NULL, '[{"vesselName": "Mr le gérant", "operatorName": "Good Company"}]', '0104000020E61000000100000001010000005BE1449141C0F5BF89869C29BA034740', 'NAMO', 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, '2023-12-08 16:57:58.191835', 6, false, false, 'GHI', 38, '2023-12-08 18:02:58.191835', NULL, NULL, NULL); +INSERT INTO public.reportings VALUES (1, 2300001, 'SEMAPHORE', 21, NULL, NULL, 'VEHICLE', 'VESSEL', '[{"mmsi": "012314231343", "vesselName": "Vessel 1"}]', '0104000020E610000001000000010100000045035E406AC113C00CF3FE4C1D354840', 'NAMO', 'Description 1', 'INFRACTION_SUSPICION', 'Rejets illicites', '{"Jet de déchet","Carénage sauvage"}', 'ACTION TAKEN', true, true, now() - INTERVAL '3 days', 24, false, false, NULL, NULL, NULL, NULL, NULL, 19); +INSERT INTO public.reportings VALUES (2, 2300002, 'SEMAPHORE', 23, NULL, NULL, 'VEHICLE', 'VESSEL', '[{"mmsi": "012314231344", "vesselName": "Vessel 2"}]', '0104000020E610000001000000010100000062C9C715311E13C050CB31D53D4F4840', 'NAMO', 'Description 2', 'INFRACTION_SUSPICION', 'Police des mouillages', '{ZMEL}', 'ACTION TAKEN', true, true, now() - INTERVAL '2 days', 2, false, false, NULL, NULL, NULL, NULL, NULL, 12); +INSERT INTO public.reportings VALUES (3, 2300003, 'CONTROL_UNIT', NULL, 10000, NULL, 'VEHICLE', 'VESSEL', '[{"mmsi": "012314231345", "vesselName": "Vessel 3"}]', '0106000020E610000001000000010300000001000000040000006E15B8857C090CC02C07754424784840552A202082FC09C0C0FD120D667A484025BF296025E00BC0805DC2889C7F48406E15B8857C090CC02C07754424784840', 'NAMO', 'Description 3', 'INFRACTION_SUSPICION', 'Police des mouillages', '{ZMEL}', 'ACTION TAKEN', true, true, now() - INTERVAL '1 hour', 1, false, false, NULL, NULL, NULL, NULL, NULL, 12); +INSERT INTO public.reportings VALUES (4, 2300004, 'OTHER', NULL, NULL, 'MA SUPER SOCIETE', 'INDIVIDUAL', NULL, '[{"operatorName": "Mr le dirigeant"}]', '0106000020E6100000010000000103000000010000000500000012F330DDB98206C0CD5EF048C0BF4840FE7303CB321005C092CE3C90A7CC4840820740BBC76A06C07E8D665D8AD94840310109D4AC5507C002C775BEE5C2484012F330DDB98206C0CD5EF048C0BF4840', 'MED', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ultrices risus ac arcu pellentesque, et tempor justo tempor. Pellentesque sem nisl, tempor id augue non, interdum sollicitudin felis.', 'OBSERVATION', 'Pêche à pied', '{Braconnage}', NULL, true, true, now() - INTERVAL '3 hour', 4, false, false, NULL, NULL, NULL, NULL, NULL, 18); +INSERT INTO public.reportings VALUES (5, 2300005, 'SEMAPHORE', 36, NULL, NULL, 'COMPANY', NULL, '[{"vesselName": "Mr le gérant", "operatorName": "Ma société"}]', '0104000020E6100000010000000101000000417927B8BBBBD73F06D9D38A46E24840', 'Guadeloupe', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, now() - INTERVAL '1 hour', 6, false, false, NULL, NULL, NULL, NULL, NULL, NULL); +INSERT INTO public.reportings VALUES (6, 2300006, 'SEMAPHORE', 36, NULL, NULL, 'COMPANY', NULL, '[{"vesselName": "Héron", "operatorName": "La sociéter"}]', '0104000020E6100000010000000101000000A22CD736208DF9BF242A543717D44540', 'Guadeloupe', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', 'Police des mouillages', '{ZMEL}', NULL, true, true, now() - INTERVAL '75 minutes', 6, false, false, 'ABC', 34, now() - INTERVAL '15 minutes', NULL, 'b8007c8a-5135-4bc3-816f-c69c7b75d807', 12); +INSERT INTO public.reportings VALUES (7, 2300007, 'CONTROL_UNIT', NULL, 10001, NULL, 'COMPANY', NULL, '[{"vesselName": "Mr le gérant", "operatorName": "Good Company"}]', '0104000020E6100000010000000101000000BDAE0F9A19C010C068D780A5708E4740', 'NAMO', 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, now() - INTERVAL '90 minutes', 6, false, false, 'DEF', 34, now() - INTERVAL '25 minutes', NULL, NULL, NULL); +INSERT INTO public.reportings VALUES (8, 2300008, 'CONTROL_UNIT', NULL, 10001, NULL, 'COMPANY', NULL, '[{"vesselName": "Mr le gérant", "operatorName": "Good Company"}]', '0104000020E61000000100000001010000005BE1449141C0F5BF89869C29BA034740', 'NAMO', 'Lorem LoremLorem ipsum dolor sit amet, consectetur adipiscing elit.', 'OBSERVATION', NULL, NULL, NULL, true, true, now() - INTERVAL '90 minutes', 6, false, false, 'GHI', 38, now() - INTERVAL '25 minutes', NULL, NULL, NULL); /* reporting linked to a surveillance */ diff --git a/frontend/cypress/e2e/side_window/reporting/filters.spec.ts b/frontend/cypress/e2e/side_window/reporting/filters.spec.ts index dfddaa5ae..5da9d185e 100644 --- a/frontend/cypress/e2e/side_window/reporting/filters.spec.ts +++ b/frontend/cypress/e2e/side_window/reporting/filters.spec.ts @@ -41,7 +41,7 @@ context('Reportings', () => { it('Should filter reportings by source', () => { cy.fill('Source', ['Sémaphore de Fécamp']) - + cy.wait(500) cy.getDataCy('reportings-filter-tags').find('.Component-SingleTag > span').contains('Source Sémaphore de Fécamp') cy.get('.Table-SimpleTable tr').should('have.length.to.be.greaterThan', 0) @@ -59,6 +59,7 @@ context('Reportings', () => { it('Should filter reportings by type', () => { cy.fill('Type de signalement', 'Observation') + cy.wait(500) cy.wait('@getReportings') cy.get('.Table-SimpleTable tr').should('have.length.to.be.greaterThan', 0) diff --git a/frontend/src/features/Reportings/Filters/Table/index.tsx b/frontend/src/features/Reportings/Filters/Table/index.tsx index a81133da9..cb236d1ff 100644 --- a/frontend/src/features/Reportings/Filters/Table/index.tsx +++ b/frontend/src/features/Reportings/Filters/Table/index.tsx @@ -72,11 +72,11 @@ export function TableReportingsFiltersWithRef( ) const themeCustomSearch = useMemo( () => - new CustomSearch(subThemesOptions as Array<Option<number>>, ['label'], { + new CustomSearch(themesOptions as Array<Option<number>>, ['label'], { cacheKey: 'REPORTINGS_LIST', withCacheInvalidation: true }), - [subThemesOptions] + [themesOptions] ) const subThemeCustomSearch = useMemo( From 110354849c651fdfdce3d1a670e2614abaf43d0c Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Mon, 18 Dec 2023 09:24:46 +0100 Subject: [PATCH 46/53] [Tests] fix reportings filters tests --- frontend/cypress/e2e/side_window/reporting/filters.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/cypress/e2e/side_window/reporting/filters.spec.ts b/frontend/cypress/e2e/side_window/reporting/filters.spec.ts index 5da9d185e..e8a5d8c2b 100644 --- a/frontend/cypress/e2e/side_window/reporting/filters.spec.ts +++ b/frontend/cypress/e2e/side_window/reporting/filters.spec.ts @@ -40,6 +40,7 @@ context('Reportings', () => { }) it('Should filter reportings by source', () => { + cy.wait(1000) cy.fill('Source', ['Sémaphore de Fécamp']) cy.wait(500) cy.getDataCy('reportings-filter-tags').find('.Component-SingleTag > span').contains('Source Sémaphore de Fécamp') From c09822ac11775af486190b5e581374c5fa7a1092 Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Mon, 18 Dec 2023 10:28:59 +0100 Subject: [PATCH 47/53] [Tech] changes due to code review --- .../filters/isMissionPartOfSelectedControlPlans.ts | 3 +-- .../ReportingsList/Cells/CellActionThemes.tsx | 14 +++++++------- .../Themes/ThemeSelector/SubThemesSelector.tsx | 2 +- .../ActionForm/Themes/ThemeSelector/index.tsx | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/frontend/src/domain/use_cases/missions/filters/isMissionPartOfSelectedControlPlans.ts b/frontend/src/domain/use_cases/missions/filters/isMissionPartOfSelectedControlPlans.ts index 25a8291b1..a3a2f5f0c 100644 --- a/frontend/src/domain/use_cases/missions/filters/isMissionPartOfSelectedControlPlans.ts +++ b/frontend/src/domain/use_cases/missions/filters/isMissionPartOfSelectedControlPlans.ts @@ -11,7 +11,6 @@ export function isMissionPartOfSelectedControlPlans(mission: Mission, selectedTh const missionControlPlans = mission.envActions.flatMap((action: any) => action.controlPlans?.flatMap(controlPlan => controlPlan.themeId) ) - const controlPlansFiltered = missionControlPlans.filter(controlPlan => selectedThemes.includes(controlPlan)) - return controlPlansFiltered.length > 0 + return missionControlPlans.some(controlPlan => selectedThemes.includes(controlPlan)) } diff --git a/frontend/src/features/Reportings/ReportingsList/Cells/CellActionThemes.tsx b/frontend/src/features/Reportings/ReportingsList/Cells/CellActionThemes.tsx index 65dd32e96..1874fd3dc 100644 --- a/frontend/src/features/Reportings/ReportingsList/Cells/CellActionThemes.tsx +++ b/frontend/src/features/Reportings/ReportingsList/Cells/CellActionThemes.tsx @@ -5,18 +5,18 @@ import { useGetControlPlans } from '../../../../hooks/useGetControlPlans' export function CellActionThemes({ subThemeIds, themeId }: { subThemeIds: number[]; themeId: number }) { const { subThemes, themes } = useGetControlPlans() const cellContent = useMemo(() => { - if (themeId) { - const themeAsString = themes[themeId]?.theme ?? '' - if (subThemeIds.length > 0) { - const subThemesAsString = subThemeIds.map(subThemeId => subThemes[subThemeId]?.subTheme) + if (!themeId) { + return '' + } - return `${themeAsString}: ${subThemesAsString.join(', ')}` - } + const themeAsString = themes[themeId]?.theme ?? '' + if (subThemeIds.length === 0) { return themeAsString } + const subThemesAsString = subThemeIds.map(subThemeId => subThemes[subThemeId]?.subTheme) - return '' + return `${themeAsString}: ${subThemesAsString.join(', ')}` }, [themeId, subThemeIds, subThemes, themes]) return cellContent !== '' ? ( diff --git a/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/SubThemesSelector.tsx b/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/SubThemesSelector.tsx index 0db8537e9..8fde239ba 100644 --- a/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/SubThemesSelector.tsx +++ b/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/SubThemesSelector.tsx @@ -41,7 +41,7 @@ export function SubThemesSelector({ {!isError && !isLoading && ( <MultiSelect // force update when name or theme changes - key={`${themeId}-${subThemes.length}`} + key={`${actionIndex}-${themeId}-${subThemes.length}`} baseContainer={newWindowContainerRef.current} data-cy="envaction-subtheme-selector" disabled={!themeId} diff --git a/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/index.tsx b/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/index.tsx index 2e824caf3..87ef2779b 100644 --- a/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/index.tsx +++ b/frontend/src/features/missions/MissionForm/ActionForm/Themes/ThemeSelector/index.tsx @@ -31,7 +31,7 @@ export function ThemeSelector({ actionIndex, isError, isLoading, label, themeInd {isLoading && <Msg>Chargement</Msg>} {!isError && !isLoading && ( <Select - key={themes.length} + key={`${actionIndex}-${themes.length}`} baseContainer={newWindowContainerRef.current} data-cy="envaction-theme-selector" error={currentThemeProps.error} From 71588c053e6f101395798db37d966c12036ec3c2 Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Mon, 18 Dec 2023 17:53:45 +0100 Subject: [PATCH 48/53] [Tech] add distinct in migration --- .../db/migration/internal/V0.103__create_action_theme.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index c87f2c776..56ae3eb79 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -87,7 +87,7 @@ WITH themes AS ( jsonb_array_elements(value->'themes')->>'theme' as theme FROM env_actions ) -SELECT themes.env_action_id, th.id +SELECT DISTINCT themes.env_action_id, th.id FROM themes, control_plan_themes th WHERE th.theme = themes.theme @@ -101,7 +101,7 @@ INSERT INTO env_actions_control_plan_sub_themes (env_action_id, subtheme_id) jsonb_array_elements_text(jsonb_array_elements(value->'themes')->'subThemes') as subtheme FROM env_actions ) - SELECT themes.env_action_id, sbt.id + SELECT DISTINCT themes.env_action_id, sbt.id FROM themes, control_plan_sub_themes sbt, control_plan_themes th From 7e683e985b5429a16ad9cd7bf88761e7e89a9669 Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Mon, 18 Dec 2023 18:28:41 +0100 Subject: [PATCH 49/53] [Migration] fix migration for control_plan_tags --- .../db/migration/internal/V0.103__create_action_theme.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index 56ae3eb79..508435088 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -118,6 +118,7 @@ WITH themes AS ( jsonb_array_elements(value->'themes')->>'theme' as theme, jsonb_array_elements(value->'themes')->'protectedSpecies' as protectedspecies FROM env_actions + WHERE jsonb_typeof(value->'themes') = 'array' ) SELECT themes.env_action_id, control_plan_tags.id FROM themes, From 8f4ce54bab9e691826c4c88ced0d82e43bdd4de7 Mon Sep 17 00:00:00 2001 From: Thomas Brosset <thomas.brosset@gmail.com> Date: Tue, 19 Dec 2023 10:27:40 +0100 Subject: [PATCH 50/53] fix distinct tags --- .../internal/V0.103__create_action_theme.sql | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index 508435088..515308312 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -81,16 +81,16 @@ INSERT INTO control_plan_tags (theme_id, tag) -- EnvActions: Insertion des données depuis les env actions dans la table env_actions_control_plan_themes INSERT INTO env_actions_control_plan_themes (env_action_id, theme_id) -WITH themes AS ( - SELECT - id as env_action_id, - jsonb_array_elements(value->'themes')->>'theme' as theme -FROM env_actions - ) -SELECT DISTINCT themes.env_action_id, th.id -FROM themes, - control_plan_themes th -WHERE th.theme = themes.theme + WITH themes AS ( + SELECT + id as env_action_id, + jsonb_array_elements(value->'themes')->>'theme' as theme + FROM env_actions + ) + SELECT DISTINCT themes.env_action_id, th.id + FROM themes, + control_plan_themes th + WHERE th.theme = themes.theme ; -- EnvActions: Insertion des données depuis les env actions dans la table env_actions_control_plan_sub_themes INSERT INTO env_actions_control_plan_sub_themes (env_action_id, subtheme_id) @@ -113,14 +113,14 @@ INSERT INTO env_actions_control_plan_sub_themes (env_action_id, subtheme_id) -- EnvActions: Insertion des données depuis les env actions dans la table env_actions_control_plan_tags INSERT INTO env_actions_control_plan_tags (env_action_id, tag_id) WITH themes AS ( - SELECT + SELECT id as env_action_id, jsonb_array_elements(value->'themes')->>'theme' as theme, + jsonb_array_elements(value->'themes')->>'protectedSpecies' as protectedspeciestext, jsonb_array_elements(value->'themes')->'protectedSpecies' as protectedspecies FROM env_actions - WHERE jsonb_typeof(value->'themes') = 'array' ) - SELECT themes.env_action_id, control_plan_tags.id + SELECT DISTINCT themes.env_action_id, control_plan_tags.id FROM themes, LATERAL ( SELECT @@ -136,7 +136,9 @@ WITH themes AS ( FROM (SELECT jsonb_array_elements_text(protectedspecies) species) t ) d(tags), control_plan_tags - WHERE control_plan_tags.tag = d.tags; + WHERE control_plan_tags.tag = d.tags + AND protectedspeciestext IS NOT NULL + AND protectedspeciestext !='[]'; --- Signalements From 323ddeb3b17654627c19f65d320e23ceb46316cd Mon Sep 17 00:00:00 2001 From: Claire Dagan <clairedagan@gmail.com> Date: Tue, 19 Dec 2023 11:28:03 +0100 Subject: [PATCH 51/53] [Tests] fix tests e2e --- frontend/cypress/e2e/side_window/mission_form/main_form.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/cypress/e2e/side_window/mission_form/main_form.spec.ts b/frontend/cypress/e2e/side_window/mission_form/main_form.spec.ts index becce470c..c7d6b9c19 100644 --- a/frontend/cypress/e2e/side_window/mission_form/main_form.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/main_form.spec.ts @@ -296,7 +296,7 @@ context('Side Window > Mission Form > Main Form', () => { const month = new Date().getMonth() cy.fill('Période spécifique', [ [2023, month - 4, 1], - [2023, month - 4, 31] + [2023, month - 3, 31] ]) cy.wait('@getMissions') From 782e4f61576a6edaa6ffe2d231021cfe9dae8ce2 Mon Sep 17 00:00:00 2001 From: Thomas Brosset <thomas.brosset@gmail.com> Date: Tue, 19 Dec 2023 12:20:30 +0100 Subject: [PATCH 52/53] update analytic view with themes from controlplan --- ...0.104__update_materialized_view_themes.sql | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 backend/src/main/resources/db/migration/internal/V0.104__update_materialized_view_themes.sql diff --git a/backend/src/main/resources/db/migration/internal/V0.104__update_materialized_view_themes.sql b/backend/src/main/resources/db/migration/internal/V0.104__update_materialized_view_themes.sql new file mode 100644 index 000000000..f60c24285 --- /dev/null +++ b/backend/src/main/resources/db/migration/internal/V0.104__update_materialized_view_themes.sql @@ -0,0 +1,66 @@ +DROP MATERIALIZED VIEW analytics_actions; + +CREATE MATERIALIZED VIEW public.analytics_actions AS + +SELECT + a.id, + a.mission_id, + action_start_datetime_utc, + action_end_datetime_utc, + EXTRACT(year FROM action_start_datetime_utc) AS year, + m.start_datetime_utc AS mission_start_datetime_utc, + m.end_datetime_utc AS mission_end_datetime_utc, + mission_type, + action_type, + COALESCE(m.facade, 'Hors façade') AS mission_facade, + cu.name AS control_unit, + adm.name AS administration, + cu.name ILIKE 'ulam%' OR ( + adm.name = 'DIRM / DM' AND + cu.name ILIKE 'PAM%' + ) AS is_aff_mar, + ( + cu.name ILIKE 'ulam%' OR ( + adm.name = 'DIRM / DM' AND + cu.name ILIKE 'PAM%' + ) + ) OR adm.name IN ('Gendarmerie Nationale', 'Gendarmerie Maritime', 'Douane', 'Marine Nationale') AS is_aem, + CASE + WHEN cu.name ILIKE 'ulam%' OR (adm.name = 'DIRM / DM' AND cu.name ILIKE 'PAM%') THEN 'Affaires Maritimes' + WHEN adm.name IN ('Gendarmerie Nationale', 'Gendarmerie Maritime', 'Douane', 'Marine Nationale') THEN adm.name + ELSE 'Administrations hors AEM' + END AS administration_aem, + COALESCE(a.facade, 'Hors façade') AS action_facade, + COALESCE(a.department, 'Hors département') AS action_department, + COALESCE(t3.theme, 'Aucun thème') AS theme_level_1, + COALESCE(t2.subtheme, 'Aucun sous-thème') AS theme_level_2, + CASE WHEN action_type = 'CONTROL' THEN ST_X(geom_element.geom) END AS longitude, + CASE WHEN action_type = 'CONTROL' THEN ST_Y(geom_element.geom) END AS latitude, + CASE WHEN action_type = 'CONTROL' THEN CASE WHEN jsonb_array_length(a.value->'infractions') > 0 THEN true ELSE false END END AS infraction, + (a.value->>'actionNumberOfControls')::DOUBLE PRECISION AS number_of_controls, + CASE WHEN action_type = 'SURVEILLANCE' THEN EXTRACT(epoch FROM a.action_end_datetime_utc - a.action_start_datetime_utc) / 3600.0 END AS surveillance_duration, + m.observations_cacem +FROM env_actions a +LEFT JOIN ST_Dump(a.geom) AS geom_element +ON true +LEFT JOIN env_actions_control_plan_sub_themes t1 on t1.env_action_id = a.id +LEFT JOIN control_plan_sub_themes t2 on t2.id = t1.subtheme_id +LEFT JOIN control_plan_themes t3 on t3.id = t2.theme_id +JOIN missions m +ON a.mission_id = m.id +LEFT JOIN LATERAL unnest(mission_types) mission_type ON true +LEFT JOIN missions_control_units mcu +ON mcu.mission_id = m.id +LEFT JOIN control_units cu +ON cu.id = mcu.control_unit_id +LEFT JOIN administrations adm +ON adm.id = cu.administration_id +WHERE + NOT m.deleted AND + m.closed AND + action_type IN ('CONTROL', 'SURVEILLANCE') +ORDER BY action_start_datetime_utc DESC; + +CREATE INDEX ON analytics_actions USING BRIN(action_start_datetime_utc); + +REFRESH MATERIALIZED VIEW public.analytics_actions; \ No newline at end of file From cf6345aca6cd63fd6fe95fd69a3c634de12f1deb Mon Sep 17 00:00:00 2001 From: Thomas Brosset <thomas.brosset@gmail.com> Date: Tue, 19 Dec 2023 17:11:48 +0100 Subject: [PATCH 53/53] fix safe select for inserts --- .../db/migration/internal/V0.103__create_action_theme.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql index 515308312..52c97e821 100644 --- a/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql +++ b/backend/src/main/resources/db/migration/internal/V0.103__create_action_theme.sql @@ -86,6 +86,7 @@ INSERT INTO env_actions_control_plan_themes (env_action_id, theme_id) id as env_action_id, jsonb_array_elements(value->'themes')->>'theme' as theme FROM env_actions + WHERE value->>'themes' is not null ) SELECT DISTINCT themes.env_action_id, th.id FROM themes, @@ -100,6 +101,7 @@ INSERT INTO env_actions_control_plan_sub_themes (env_action_id, subtheme_id) jsonb_array_elements(value->'themes')->>'theme' as theme, jsonb_array_elements_text(jsonb_array_elements(value->'themes')->'subThemes') as subtheme FROM env_actions + WHERE value->>'themes' is not null ) SELECT DISTINCT themes.env_action_id, sbt.id FROM themes, @@ -119,6 +121,7 @@ WITH themes AS ( jsonb_array_elements(value->'themes')->>'protectedSpecies' as protectedspeciestext, jsonb_array_elements(value->'themes')->'protectedSpecies' as protectedspecies FROM env_actions + WHERE value->>'themes' is not null ) SELECT DISTINCT themes.env_action_id, control_plan_tags.id FROM themes,