diff --git a/packages/api/src/api/_format/etapes-types.ts b/packages/api/src/api/_format/etapes-types.ts index 4757e45cdf7b55f828d82b9bbf89f8803d26b101..3b960bc51947f4ff10dbb820d743f3b5a2f1fba2 100644 --- a/packages/api/src/api/_format/etapes-types.ts +++ b/packages/api/src/api/_format/etapes-types.ts @@ -1,9 +1,9 @@ -import { demarcheEnregistrementDemandeDateFind } from 'camino-common/src/demarche' import { ITitreEtape } from '../../types' import { DocumentType } from 'camino-common/src/static/documentsTypes' import { EtapesTypes, EtapeTypeId } from 'camino-common/src/static/etapesTypes' import { isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools' +import { demarcheEnregistrementDemandeDateFind } from '../../business/rules-demarches/machines' export const documentsTypesFormat = (documentsTypes: DocumentType[] | undefined | null, documentsTypesSpecifiques: DocumentType[] | undefined | null): DocumentType[] => { let result: DocumentType[] = [] diff --git a/packages/api/src/api/_format/titres-etapes.ts b/packages/api/src/api/_format/titres-etapes.ts index 3be4551241699d4d4d11907c29af24ddd88af75b..384b3f8dfe9a608b2e04a188b8932960b11da611 100644 --- a/packages/api/src/api/_format/titres-etapes.ts +++ b/packages/api/src/api/_format/titres-etapes.ts @@ -11,6 +11,7 @@ import { z } from 'zod' import { Effect } from 'effect' import { CaminoError } from 'camino-common/src/zod-tools' import { zodParseEffect, ZodUnparseable } from '../../tools/fp-tools' +import { MachineInfo } from 'camino-common/src/machines' const getPerimetreFromITitreEtape = ( titreEtape: Pick< @@ -31,27 +32,11 @@ const getPerimetreFromITitreEtape = ( const apiFlattenEtapeValidator = flattenEtapeValidator.and(titreEtapeForMachineValidator.pick({ concurrence: true, hasTitreFrom: true, demarcheIdsConsentement: true })) export type ApiFlattenEtape = z.infer<typeof apiFlattenEtapeValidator> -const pasDeDemarcheOuDeTitreCharge = 'pas de démarche ou de titre chargé' as const -const pasDeDemarcheChargee = 'pas de démarche chargée' as const const pasDHeritageCharge = "pas d'héritage chargé" as const const pasDeSlug = 'pas de slug' as const -export type TitreEtapeToFlattenEtapeErrors = typeof pasDeDemarcheOuDeTitreCharge | typeof pasDeDemarcheChargee | typeof pasDHeritageCharge | typeof pasDeSlug | ZodUnparseable -export const iTitreEtapeToFlattenEtape = (titreEtape: ITitreEtape): Effect.Effect<ApiFlattenEtape, CaminoError<TitreEtapeToFlattenEtapeErrors>> => { +export type TitreEtapeToFlattenEtapeErrors = typeof pasDHeritageCharge | typeof pasDeSlug | ZodUnparseable +export const iTitreEtapeToFlattenEtape = (machineInfo: MachineInfo, titreEtape: ITitreEtape): Effect.Effect<ApiFlattenEtape, CaminoError<TitreEtapeToFlattenEtapeErrors>> => { return Effect.Do.pipe( - Effect.bind('titreTypeId', () => { - const titreTypeId = titreEtape.demarche?.titre?.typeId - if (isNotNullNorUndefined(titreTypeId)) { - return Effect.succeed(titreTypeId) - } - return Effect.fail({ message: pasDeDemarcheOuDeTitreCharge }) - }), - Effect.bind('demarcheTypeId', () => { - const demarcheTypeId = titreEtape.demarche?.typeId - if (isNullOrUndefined(demarcheTypeId)) { - return Effect.fail({ message: pasDeDemarcheChargee }) - } - return Effect.succeed(demarcheTypeId) - }), Effect.bind('heritageProps', () => { const heritageProps = EtapesTypes[titreEtape.typeId].fondamentale ? titreEtape.heritageProps : defaultHeritageProps if (isNullOrUndefined(heritageProps)) { @@ -67,9 +52,7 @@ export const iTitreEtapeToFlattenEtape = (titreEtape: ITitreEtape): Effect.Effec return Effect.succeed(slug) }), Effect.bind('heritageContenu', () => zodParseEffect(heritageContenuValidator, titreEtape.heritageContenu)), - Effect.bind('contenu', ({ titreTypeId, demarcheTypeId, heritageContenu }) => - Effect.succeed(simpleContenuToFlattenedContenu(titreTypeId, demarcheTypeId, titreEtape.typeId, titreEtape.contenu ?? {}, heritageContenu)) - ), + Effect.bind('contenu', ({ heritageContenu }) => Effect.succeed(simpleContenuToFlattenedContenu(machineInfo, titreEtape.typeId, titreEtape.contenu ?? {}, heritageContenu))), Effect.map(({ heritageProps, slug, contenu }) => { const flattenEtape: FlattenEtape = { ...titreEtape, diff --git a/packages/api/src/api/graphql/resolvers/_titre-etape.ts b/packages/api/src/api/graphql/resolvers/_titre-etape.ts index 11a505b94dd24ffd4ad898dbf52f1f29ce073246..aa08885c7f396b0203339b12892995cb3c8df9f6 100644 --- a/packages/api/src/api/graphql/resolvers/_titre-etape.ts +++ b/packages/api/src/api/graphql/resolvers/_titre-etape.ts @@ -3,14 +3,13 @@ import { IHeritageContenu, IHeritageElement, IHeritageProps, ITitreDemarche, ITi import { titreEtapeHeritagePropsFind } from '../../../business/utils/titre-etape-heritage-props-find' import { titreEtapeHeritageContenuFind } from '../../../business/utils/titre-etape-heritage-contenu-find' import { titreEtapesSortAscByOrdre, titreEtapesSortDescByOrdre } from '../../../business/utils/titre-etapes-sort' -import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' import { getKeys, isNotNullNorUndefined, RecordPartial } from 'camino-common/src/typescript-tools' import { getSections, Section } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/sections' import { ETAPE_HERITAGE_PROPS, isHeritageProps } from 'camino-common/src/heritage' import { EtapeTypeId, EtapesTypes } from 'camino-common/src/static/etapesTypes' import { CaminoDate } from 'camino-common/src/date' import { EtapeId } from 'camino-common/src/etape' +import { MachineInfo } from 'camino-common/src/machines' const titreEtapeHeritagePropsBuild = (date: CaminoDate, titreEtapes: ITitreEtape[] | null, etapeId: EtapeId | null) => { const titreEtapesFiltered = titreEtapesSortAscByOrdre( @@ -59,19 +58,12 @@ const titreEtapeHeritagePropsBuild = (date: CaminoDate, titreEtapes: ITitreEtape return newTitreEtape } -const titreEtapeHeritageContenuBuild = ( - date: CaminoDate, - etapeTypeId: EtapeTypeId, - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - titreEtapes: ITitreEtape[] | null, - etapeId: EtapeId | null -) => { +const titreEtapeHeritageContenuBuild = (date: CaminoDate, etapeTypeId: EtapeTypeId, machineInfo: MachineInfo, titreEtapes: ITitreEtape[] | null, etapeId: EtapeId | null) => { if (!titreEtapes) { titreEtapes = [] } - const sections = getSections(titreTypeId, demarcheTypeId, etapeTypeId) + const sections = getSections(machineInfo, etapeTypeId) const titreEtape = { id: 'new-titre-etape', date, @@ -83,7 +75,7 @@ const titreEtapeHeritageContenuBuild = ( titreEtapesFiltered.splice(0, 0, titreEtape) const etapeSectionsDictionary = titreEtapesFiltered.reduce<RecordPartial<string, Section[]>>((acc, e) => { - acc[e.id] = getSections(titreTypeId, demarcheTypeId, e.typeId) + acc[e.id] = getSections(machineInfo, e.typeId) return acc }, {}) @@ -127,14 +119,7 @@ const titreEtapeHeritageContenuBuild = ( return { contenu, heritageContenu } } -export const titreEtapeHeritageBuild = ( - date: CaminoDate, - etapeTypeId: EtapeTypeId, - titreDemarche: ITitreDemarche, - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - etapeId: EtapeId | null -): ITitreEtape => { +export const titreEtapeHeritageBuild = (date: CaminoDate, machineInfo: MachineInfo, etapeTypeId: EtapeTypeId, titreDemarche: ITitreDemarche, etapeId: EtapeId | null): ITitreEtape => { let titreEtape = {} as ITitreEtape const etapeType = EtapesTypes[etapeTypeId] @@ -143,9 +128,9 @@ export const titreEtapeHeritageBuild = ( titreEtape = titreEtapeHeritagePropsBuild(date, titreDemarche.etapes ?? [], etapeId) } - const sections = getSections(titreTypeId, demarcheTypeId, etapeType.id) + const sections = getSections(machineInfo, etapeType.id) if (sections.length) { - const { contenu, heritageContenu } = titreEtapeHeritageContenuBuild(date, etapeTypeId, titreTypeId, demarcheTypeId, titreDemarche.etapes ?? [], etapeId) + const { contenu, heritageContenu } = titreEtapeHeritageContenuBuild(date, etapeTypeId, machineInfo, titreDemarche.etapes ?? [], etapeId) titreEtape.contenu = contenu titreEtape.heritageContenu = heritageContenu diff --git a/packages/api/src/api/graphql/resolvers/titres-etapes.ts b/packages/api/src/api/graphql/resolvers/titres-etapes.ts index 2d43165d776e856405e35d669e5a5702ae221c00..cb5e06ebe250e0cfc9d2231e4eeccfe8ef07f531 100644 --- a/packages/api/src/api/graphql/resolvers/titres-etapes.ts +++ b/packages/api/src/api/graphql/resolvers/titres-etapes.ts @@ -11,6 +11,8 @@ import { CaminoDate } from 'camino-common/src/date' import { titreEtapeFormatFields } from '../../_format/_fields' import { EtapeId } from 'camino-common/src/etape' import { DemarcheId } from 'camino-common/src/demarche' +import { MachineInfo } from 'camino-common/src/machines' +import { isNullOrUndefined } from 'camino-common/src/typescript-tools' export const etapeHeritage = async ( { date, titreDemarcheId, typeId, etapeId }: { date: CaminoDate; titreDemarcheId: DemarcheId; typeId: EtapeTypeId; etapeId: EtapeId | null }, @@ -19,7 +21,9 @@ export const etapeHeritage = async ( try { let titreDemarche = await titreDemarcheGet(titreDemarcheId, { fields: {} }, user) - if (!titreDemarche) throw new Error("la démarche n'existe pas") + if (isNullOrUndefined(titreDemarche)) { + throw new Error("la démarche n'existe pas") + } titreDemarche = await titreDemarcheGet( titreDemarcheId, @@ -32,8 +36,17 @@ export const etapeHeritage = async ( userSuper ) - const titreEtape = titreEtapeHeritageBuild(date, typeId, titreDemarche!, titreDemarche!.titre!.typeId, titreDemarche!.typeId, etapeId) - const titreTypeId = titreDemarche?.titre?.typeId + if (isNullOrUndefined(titreDemarche)) { + throw new Error("la démarche n'existe pas") + } + + const machineInfo = MachineInfo.withMachineId(titreDemarche.titre!.typeId, titreDemarche.typeId, titreDemarche.id, titreDemarche.machineId) + if (!machineInfo.valid) { + throw new Error(machineInfo.error) + } + + const titreEtape = titreEtapeHeritageBuild(date, machineInfo.value, typeId, titreDemarche!, etapeId) + const titreTypeId = titreDemarche.titre?.typeId if (!titreTypeId) { throw new Error(`le type du titre de l'étape ${titreEtape.id} n'est pas chargé`) } diff --git a/packages/api/src/api/graphql/titres-demarches.test.integration.ts b/packages/api/src/api/graphql/titres-demarches.test.integration.ts index acc9f34b38e7c71e292a620b864237c71417c753..01b18e4534abfc0cf42811e6638344a9c6ef4698 100644 --- a/packages/api/src/api/graphql/titres-demarches.test.integration.ts +++ b/packages/api/src/api/graphql/titres-demarches.test.integration.ts @@ -152,6 +152,7 @@ const demarcheCreate = async () => { id: demarcheId, titreId, typeId: 'oct', + machineId: null, }, ], }) diff --git a/packages/api/src/api/graphql/titres.test.integration.ts b/packages/api/src/api/graphql/titres.test.integration.ts index 28fbe42819f8d5f8972cd2c47bfb7ca908a1b154..2a242cc566a2aba4a2b8ac2fcf50dc494a675065 100644 --- a/packages/api/src/api/graphql/titres.test.integration.ts +++ b/packages/api/src/api/graphql/titres.test.integration.ts @@ -53,12 +53,14 @@ const titreDemarchesPubliques: ITitreInsert = { titreId: newTitreId('titre-id'), typeId: 'oct', publicLecture: true, + machineId: null, }, { id: newDemarcheId('titre-id-demarche-pro'), titreId: newTitreId('titre-id'), typeId: 'pro', publicLecture: false, + machineId: null, }, ], } @@ -76,6 +78,7 @@ const titreEtapesPubliques: ITitreInsert = { typeId: 'oct', statutId: 'acc', publicLecture: true, + machineId: 'AncienLogigrammeOctroiARM', etapes: [ { id: newEtapeId('titre-id-demarche-id-asc'), @@ -268,6 +271,7 @@ describe('titres', () => { typeId: 'oct', statutId: 'acc', publicLecture: true, + machineId: 'AncienLogigrammeOctroiARM', etapes: [ { id: newEtapeId('titre-id-demarche-id-dpu'), diff --git a/packages/api/src/api/rest/__snapshots__/demarches.test.integration.ts.snap b/packages/api/src/api/rest/__snapshots__/demarches.test.integration.ts.snap index 077fa7f1814e2ed81d9a8607dce818e642a9e46a..723e1bd69e027d6060c46326d02272380216dc3f 100644 --- a/packages/api/src/api/rest/__snapshots__/demarches.test.integration.ts.snap +++ b/packages/api/src/api/rest/__snapshots__/demarches.test.integration.ts.snap @@ -4,7 +4,7 @@ exports[`getResultatEnConcurrence > Avec un seul satellite 1`] = ` { "demarcheId": "demarcheIdPivotResultat", "demarcheTypeId": "oct", - "firstEtapeDate": "2400-01-03", + "machineId": "ProcedureSpecifique", "perimetreSansSatellite": { "geojson4326_perimetre": { "geometry": { diff --git a/packages/api/src/api/rest/__snapshots__/etapes.test.integration.ts.snap b/packages/api/src/api/rest/__snapshots__/etapes.test.integration.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..1e4101031bbcfcc4b725a1b475778019e47240d1 --- /dev/null +++ b/packages/api/src/api/rest/__snapshots__/etapes.test.integration.ts.snap @@ -0,0 +1,463 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`getEtapesTypesEtapesStatusWithMainStep > nouvelle étapes possibles change de machine en fonction de la date 2`] = ` +{ + "abd": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "adc": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "and": { + "etapeStatutIds": [ + "fai", + "acc", + "rej", + ], + "mainStep": false, + }, + "anf": { + "etapeStatutIds": [ + "pro", + "enc", + "ter", + ], + "mainStep": false, + }, + "apd": { + "etapeStatutIds": [ + "fav", + "def", + "fre", + "dre", + ], + "mainStep": false, + }, + "apo": { + "etapeStatutIds": [ + "fai", + "ajo", + "fav", + "def", + "fre", + "dre", + ], + "mainStep": false, + }, + "app": { + "etapeStatutIds": [ + "fav", + "def", + "fre", + "dre", + ], + "mainStep": false, + }, + "asc": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "css": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "des": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "dex": { + "etapeStatutIds": [ + "aci", + "acc", + "rej", + "rei", + ], + "mainStep": false, + }, + "dpu": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "exp": { + "etapeStatutIds": [ + "fav", + "def", + ], + "mainStep": false, + }, + "ipc": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mca": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mco": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mcr": { + "etapeStatutIds": [ + "fav", + "def", + ], + "mainStep": false, + }, + "mec": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "men": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mfr": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mif": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mno": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mod": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "ncl": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "ppu": { + "etapeStatutIds": [ + "pro", + "enc", + "ter", + ], + "mainStep": false, + }, + "pqr": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "rca": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "rco": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "rif": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "rpu": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "sas": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "scg": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "spo": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "spp": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, +} +`; + +exports[`getEtapesTypesEtapesStatusWithMainStep > nouvelle étapes possibles change de machine quand on déplace une étape déjà existante 1`] = ` +{ + "abd": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "adc": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "and": { + "etapeStatutIds": [ + "fai", + "acc", + "rej", + ], + "mainStep": false, + }, + "anf": { + "etapeStatutIds": [ + "pro", + "enc", + "ter", + ], + "mainStep": false, + }, + "apd": { + "etapeStatutIds": [ + "fav", + "def", + "fre", + "dre", + ], + "mainStep": false, + }, + "apo": { + "etapeStatutIds": [ + "fai", + "ajo", + "fav", + "def", + "fre", + "dre", + ], + "mainStep": false, + }, + "app": { + "etapeStatutIds": [ + "fav", + "def", + "fre", + "dre", + ], + "mainStep": false, + }, + "asc": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "css": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "des": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "dex": { + "etapeStatutIds": [ + "aci", + "acc", + "rej", + "rei", + ], + "mainStep": false, + }, + "dpu": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "exp": { + "etapeStatutIds": [ + "fav", + "def", + ], + "mainStep": false, + }, + "ipc": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mca": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mco": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mcr": { + "etapeStatutIds": [ + "fav", + "def", + ], + "mainStep": false, + }, + "mec": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "men": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mfr": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mif": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mno": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "mod": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "ncl": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "ppu": { + "etapeStatutIds": [ + "pro", + "enc", + "ter", + ], + "mainStep": false, + }, + "pqr": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "rca": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "rco": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "rif": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "rpu": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "sas": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "scg": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "spo": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, + "spp": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": false, + }, +} +`; diff --git a/packages/api/src/api/rest/activites.test.integration.ts b/packages/api/src/api/rest/activites.test.integration.ts index cdd8a4c92132bda50d394789eebbbab008bd4089..94ec45f38ec0b2ab1bdb2c43f5d2258d4adf153b 100644 --- a/packages/api/src/api/rest/activites.test.integration.ts +++ b/packages/api/src/api/rest/activites.test.integration.ts @@ -56,6 +56,7 @@ describe('updateActivite', () => { typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: DemarchesStatutsIds.Accepte, publicLecture: true, + machineId: null, etapes: [ { id: newEtapeId('titre-id-demarche-id-dpu'), diff --git a/packages/api/src/api/rest/demarches.queries.ts b/packages/api/src/api/rest/demarches.queries.ts index 9623f992d59e4ec64e5be64c8b9f001e661b52dc..346a99fd0a8419bf6408c531c41ee701d73f425c 100644 --- a/packages/api/src/api/rest/demarches.queries.ts +++ b/packages/api/src/api/rest/demarches.queries.ts @@ -50,6 +50,7 @@ import { isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefined import { demarcheTypeIdValidator } from 'camino-common/src/static/demarchesTypes' import { titreTypeIdValidator } from 'camino-common/src/static/titresTypes' import { titreIdValidator, titreSlugValidator } from 'camino-common/src/validators/titres' +import { machineIdValidator } from 'camino-common/src/validators/machine' const getEtapesByDemarcheIdDbValidator = z.object({ id: etapeIdValidator, @@ -138,6 +139,7 @@ const getDemarcheByIdOrSlugValidator = z.object({ demarche_slug: demarcheSlugValidator, demarche_type_id: demarcheTypeIdValidator, demarche_description: z.string().nullable(), + machine_id: machineIdValidator.nullable(), titre_id: titreIdValidator, titre_slug: titreSlugValidator, titre_type_id: titreTypeIdValidator, @@ -163,6 +165,7 @@ const getDemarcheByIdOrSlugDb = sql<Redefine<IGetDemarcheByIdOrSlugDbQuery, { id select td.id as demarche_id, td.slug as demarche_slug, + td.machine_id, td.type_id as demarche_type_id, td.description as demarche_description, td.entreprises_lecture, @@ -264,6 +267,7 @@ const multipolygontoFeatureMultipolygon = (multipolygon: MultiPolygon): FeatureM const getDemarchePivotEnConcurrenceDbValidator = commonTitreEnConcurrenceValidator .pick({ demarcheId: true, + machineId: true, demarcheTypeId: true, titreNom: true, titreSlug: true, @@ -356,6 +360,7 @@ select t.slug AS "titreSlug", td.type_id AS "demarcheTypeId", td.id as "demarcheId", + td.machine_id as "machineId", t.type_id AS "titreTypeId", ST_AsGeoJSON(ST_Multi(te.geojson4326_perimetre))::json as "perimetreTotalGeojson4326", te.surface as "perimetreTotalSurface", diff --git a/packages/api/src/api/rest/demarches.queries.types.ts b/packages/api/src/api/rest/demarches.queries.types.ts index 9254f5bb445911803272e115314c66c039d62f84..04f9b96256d32e310ac603628bb7f55e6f467bed 100644 --- a/packages/api/src/api/rest/demarches.queries.types.ts +++ b/packages/api/src/api/rest/demarches.queries.types.ts @@ -60,6 +60,7 @@ export interface IGetDemarcheByIdOrSlugDbResult { demarche_slug: string | null; demarche_type_id: string; entreprises_lecture: boolean; + machine_id: string | null; public_lecture: boolean; titre_id: string; titre_nom: string; @@ -118,6 +119,7 @@ export interface IGetDemarchePivotEnConcurrenceDbParams { export interface IGetDemarchePivotEnConcurrenceDbResult { demarcheId: string; demarcheTypeId: string; + machineId: string | null; perimetreTotalGeojson4326: Json | null; perimetreTotalSurface: number | null; titreNom: string; diff --git a/packages/api/src/api/rest/demarches.test.integration.ts b/packages/api/src/api/rest/demarches.test.integration.ts index c339def221731529ab8870795dc65e983dde3fc3..e982f06cd86f1b63abfa49eb7627cd9779d48151 100644 --- a/packages/api/src/api/rest/demarches.test.integration.ts +++ b/packages/api/src/api/rest/demarches.test.integration.ts @@ -259,8 +259,12 @@ describe('demarcheCreer', () => { { titreId, typeId: DEMARCHES_TYPES_IDS.Octroi, description: '' } ) - expect(res.status).toBe(HTTP_STATUS.INTERNAL_SERVER_ERROR) - expect(res.body.message).toBe('droits insuffisants') + expect(res.body).toMatchInlineSnapshot(` + { + "message": "Droits insuffisants pour créer la démarche", + "status": 400, + } + `) }) test('peut créer une démarche (utilisateur super)', async () => { @@ -284,8 +288,12 @@ describe('demarcheCreer', () => { }, { titreId: newTitreId('unknown'), typeId: DEMARCHES_TYPES_IDS.Octroi, description: '' } ) - expect(res.status).toBe(HTTP_STATUS.INTERNAL_SERVER_ERROR) - expect(res.body.message).toBe("le titre n'existe pas") + expect(res.body).toMatchInlineSnapshot(` + { + "message": "le titre n'existe pas", + "status": 404, + } + `) }) test('peut créer une démarche (utilisateur admin)', async () => { @@ -327,8 +335,12 @@ describe('demarcheCreer', () => { { titreId, typeId: DEMARCHES_TYPES_IDS.Octroi, description: '' } ) - expect(res.status).toBe(HTTP_STATUS.INTERNAL_SERVER_ERROR) - expect(res.body.message).toBe("le titre n'existe pas") + expect(res.body).toMatchInlineSnapshot(` + { + "message": "le titre n'existe pas", + "status": 404, + } + `) }) }) @@ -353,6 +365,7 @@ describe('getDemarchesEnConcurrence', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: 'ProcedureSpecifique', id: demarcheIdPivot, titreId: titreIdPivot, typeId: DEMARCHES_TYPES_IDS.Octroi, @@ -375,6 +388,7 @@ describe('getDemarchesEnConcurrence', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: 'ProcedureSpecifique', id: demarcheIdSatellite1, titreId: titreIdSatellite1, typeId: DEMARCHES_TYPES_IDS.Octroi, @@ -403,6 +417,7 @@ describe('getDemarchesEnConcurrence', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: 'ProcedureSpecifique', id: demarcheIdSatellite2, titreId: titreIdSatellite2, typeId: DEMARCHES_TYPES_IDS.Octroi, @@ -503,6 +518,7 @@ describe('getDemarcheByIdOrSlug', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: 'ProcedureSpecifique', id: demarcheId, titreId: titreId, slug: demarcheSlug, @@ -549,6 +565,7 @@ describe('getDemarcheByIdOrSlug', () => { "demarche_slug": "demarche-slug", "demarche_type_id": "oct", "first_etape_date": "2400-01-03", + "machine_id": "ProcedureSpecifique", "titre_id": "titreIdGetDemarche", "titre_nom": "titre", "titre_slug": "slug-titre", @@ -616,6 +633,7 @@ describe('getResultatEnConcurrence', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: 'ProcedureSpecifique', id: demarcheIdPivot, titreId: titreIdPivot, typeId: DEMARCHES_TYPES_IDS.Octroi, @@ -664,6 +682,7 @@ describe('getResultatEnConcurrence', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: 'ProcedureSpecifique', id: demarcheIdSatellite1, titreId: titreIdSatellite1, typeId: DEMARCHES_TYPES_IDS.Octroi, diff --git a/packages/api/src/api/rest/demarches.ts b/packages/api/src/api/rest/demarches.ts index 1ba20b73e6fef22ccbb4910b2a68242b7dd1fcb7..e33bb52677037fe8778823b8d9dfb72fdde255eb 100644 --- a/packages/api/src/api/rest/demarches.ts +++ b/packages/api/src/api/rest/demarches.ts @@ -1,7 +1,7 @@ import { Pool } from 'pg' import { HTTP_STATUS } from 'camino-common/src/http' import { CaminoRequest, CustomResponse } from './express-type' -import { DemarcheCreationOutput, demarcheIdOrSlugValidator, GetDemarcheMiseEnConcurrence, GetResultatMiseEnConcurrence } from 'camino-common/src/demarche' +import { DemarcheCreationOutput, demarcheIdOrSlugValidator, DemarcheSlug, GetDemarcheMiseEnConcurrence, GetResultatMiseEnConcurrence } from 'camino-common/src/demarche' import { getDemarcheByIdOrSlug, GetDemarcheByIdOrSlugErrors, @@ -13,19 +13,22 @@ import { } from './demarches.queries' import { GetDemarcheByIdOrSlug } from 'camino-common/src/titres' import { getAdministrationsLocalesByTitreId, getDemarchesByTitreId, getTitreByIdOrSlug, GetTitreByIdOrSlugErrors, getTitulairesAmodiatairesByTitreId } from './titres.queries' -import { isNullOrUndefined, memoize } from 'camino-common/src/typescript-tools' +import { isNotNullNorUndefined, isNullOrUndefined, memoize } from 'camino-common/src/typescript-tools' import { canReadDemarche } from './permissions/demarches' -import { titreDemarcheArchive, titreDemarcheCreate, titreDemarcheGet } from '../../database/queries/titres-demarches' +import { titreDemarcheArchive, titreDemarcheGet } from '../../database/queries/titres-demarches' import { titreDemarcheUpdateTask } from '../../business/titre-demarche-update' import { canCreateDemarche, canCreateTravaux, canDeleteDemarche, canPublishResultatMiseEnConcurrence } from 'camino-common/src/permissions/titres-demarches' import { userSuper } from '../../database/user-super' import { RestNewGetCall, RestNewPostCall } from '../../server/rest' import { Effect, Match } from 'effect' -import { isDemarcheTypeId, isTravaux } from 'camino-common/src/static/demarchesTypes' +import { isTravaux } from 'camino-common/src/static/demarchesTypes' import { titreGet } from '../../database/queries/titres' -import { CaminoApiError } from '../../types' +import { CaminoApiError, ITitreDemarche } from '../../types' import { EffectDbQueryAndValidateErrors } from '../../pg-database' -import { callAndExit, filterOrFailFromValidWithError } from '../../tools/fp-tools' +import { filterOrFailFromValidWithError } from '../../tools/fp-tools' +import { DBTitre } from '../../database/models/titres' +import { MachineInfo } from 'camino-common/src/machines' +import { createDemarche, CreateDemarcheErrors } from './titre-demande.queries' const canReadDemarcheError = 'impossible de savoir si on peut lire la démarche' as const @@ -119,52 +122,83 @@ export const demarcheSupprimer = } } -export const demarcheCreer: RestNewPostCall<'/rest/demarches'> = (rootPipe): Effect.Effect<DemarcheCreationOutput, CaminoApiError<string>> => { - return rootPipe.pipe( - Effect.flatMap(({ user, body: demarche, pool }) => - Effect.tryPromise({ - try: async () => { - const titre = await titreGet(demarche.titreId, { fields: { pointsEtape: { id: {} } } }, user) - - if (!titre) throw new Error("le titre n'existe pas") - - if (!isDemarcheTypeId(demarche.typeId)) { - throw new Error('droits insuffisants') - } - if (titre.administrationsLocales === undefined) { - throw new Error('les administrations locales doivent être chargées') - } - - const demarches = await callAndExit(getDemarchesByTitreId(pool, demarche.titreId)) - - if (isTravaux(demarche.typeId) && !canCreateTravaux(user, titre.typeId, titre.administrationsLocales ?? [], demarches)) { - throw new Error('droits insuffisants') - } - if (!isTravaux(demarche.typeId) && !canCreateDemarche(user, titre.typeId, titre.titreStatutId, titre.administrationsLocales ?? [], demarches)) { - throw new Error('droits insuffisants') - } - - const demarcheCreated = await titreDemarcheCreate(demarche) - - await titreDemarcheUpdateTask(pool, demarcheCreated.id, demarcheCreated.titreId) - - const demarcheUpdate = await titreDemarcheGet(demarcheCreated.id, { fields: { id: {} } }, user) - - if (isNullOrUndefined(demarcheUpdate?.slug)) { - throw new Error("Problème lors de l'enregistrement de la démarche") - } +const impossibleDeRecupererLeTitre = 'impossible de récupérer le titre' as const +const titreInexistant = "le titre n'existe pas" as const - return { slug: demarcheUpdate.slug } - }, - catch: unknown => { - // TODO 2024-08-08 il faut utiliser effect au dessus pour pouvoir mettre le bon code http - if (unknown instanceof Error) { - return { message: unknown.message, status: HTTP_STATUS.INTERNAL_SERVER_ERROR } - } +const administrationsNonChargees = 'Les administrations ne sont pas chargées' as const +const droitsInsuffisantsPourCreerLaDemarche = 'Droits insuffisants pour créer la démarche' as const +const impossibleDeCreerLaDemarche = 'Impossible de créer la démarche' as const +const erreurLorsDeLaMiseAJourDesTaches = 'Une erreur est survenue lors de la mise à jour des taches de la démarche' as const +const impossibleDeRecupererLaDemarcheCree = 'Impossible de récupérer la démarche crée' as const +type DemarcheCreerErrors = + | typeof impossibleDeRecupererLeTitre + | typeof titreInexistant + | typeof administrationsNonChargees + | typeof droitsInsuffisantsPourCreerLaDemarche + | typeof impossibleDeCreerLaDemarche + | typeof erreurLorsDeLaMiseAJourDesTaches + | typeof impossibleDeRecupererLaDemarcheCree + | EffectDbQueryAndValidateErrors + | CreateDemarcheErrors - return { message: "Problème lors de l'enregistrement de la démarche" as const, extra: unknown, status: HTTP_STATUS.INTERNAL_SERVER_ERROR } - }, +export const demarcheCreer: RestNewPostCall<'/rest/demarches'> = (rootPipe): Effect.Effect<DemarcheCreationOutput, CaminoApiError<DemarcheCreerErrors>> => { + return rootPipe.pipe( + Effect.bind('titre', ({ user, body: demarche }) => + Effect.tryPromise({ + try: () => titreGet(demarche.titreId, { fields: { pointsEtape: { id: {} } } }, user), + catch: error => ({ message: impossibleDeRecupererLeTitre, extra: error }), + }).pipe( + Effect.filterOrFail( + (titre): titre is NonNullable<DBTitre> => isNotNullNorUndefined(titre), + () => ({ message: titreInexistant }) + ), + Effect.filterOrFail( + titre => isNotNullNorUndefined(titre.administrationsLocales), + () => ({ message: administrationsNonChargees }) + ) + ) + ), + Effect.bind('demarches', ({ pool, body: demarche }) => getDemarchesByTitreId(pool, demarche.titreId)), + Effect.filterOrFail( + ({ body: demarche, user, titre, demarches }) => + (isTravaux(demarche.typeId) && canCreateTravaux(user, titre.typeId, titre.administrationsLocales ?? [], demarches)) || + (!isTravaux(demarche.typeId) && canCreateDemarche(user, titre.typeId, titre.titreStatutId, titre.administrationsLocales ?? [], demarches)), + () => ({ message: droitsInsuffisantsPourCreerLaDemarche }) + ), + Effect.bind('demarcheId', ({ body, pool, titre }) => createDemarche(pool, titre.id, titre.typeId, body.typeId, body.description)), + Effect.tap(({ pool, demarcheId, titre }) => + Effect.tryPromise({ + try: () => titreDemarcheUpdateTask(pool, demarcheId, titre.id), + catch: error => ({ message: erreurLorsDeLaMiseAJourDesTaches, extra: error }), }) + ), + Effect.bind('demarcheUpdate', ({ demarcheId, user }) => + Effect.tryPromise({ + try: () => titreDemarcheGet(demarcheId, { fields: { id: {} } }, user), + catch: error => ({ message: impossibleDeRecupererLaDemarcheCree, extra: error }), + }).pipe( + Effect.filterOrFail( + (demarcheUpdate): demarcheUpdate is NonNullable<ITitreDemarche & { slug: DemarcheSlug }> => isNotNullNorUndefined(demarcheUpdate?.slug), + () => ({ message: impossibleDeRecupererLaDemarcheCree }) + ) + ) + ), + Effect.map(({ demarcheUpdate }) => ({ slug: demarcheUpdate.slug })), + Effect.mapError(caminoError => + Match.value(caminoError.message).pipe( + Match.whenOr( + 'impossible de récupérer le titre', + "Impossible d'exécuter la requête dans la base de données", + 'Impossible de récupérer la démarche crée', + 'Les administrations ne sont pas chargées', + 'Les données en base ne correspondent pas à ce qui est attendu', + 'Une erreur est survenue lors de la mise à jour des taches de la démarche', + () => ({ ...caminoError, status: HTTP_STATUS.INTERNAL_SERVER_ERROR }) + ), + Match.whenOr('Droits insuffisants pour créer la démarche', () => ({ ...caminoError, status: HTTP_STATUS.BAD_REQUEST })), + Match.whenOr("le titre n'existe pas", () => ({ ...caminoError, status: HTTP_STATUS.NOT_FOUND })), + Match.exhaustive + ) ) ) } @@ -186,20 +220,34 @@ export const getDemarchesEnConcurrence: RestNewGetCall<'/rest/demarches/:demarch ) } +const incoherentMachineInfo = 'Machine associée à la démarche incohérente' as const +const insufficientPermission = 'droits insuffisants' as const +type GetResultatEnConcurrenceErrors = + | EffectDbQueryAndValidateErrors + | GetDemarcheByIdOrSlugErrors + | typeof insufficientPermission + | typeof incoherentMachineInfo + | GetFirstEtapeDateByDemarcheIdOrSlugErrors export const getResultatEnConcurrence: RestNewGetCall<'/rest/demarches/:demarcheId/resultatMiseEnConcurrence'> = ( rootPipe -): Effect.Effect<GetResultatMiseEnConcurrence, CaminoApiError<EffectDbQueryAndValidateErrors | GetDemarcheByIdOrSlugErrors | 'droits insuffisants' | GetFirstEtapeDateByDemarcheIdOrSlugErrors>> => { +): Effect.Effect<GetResultatMiseEnConcurrence, CaminoApiError<GetResultatEnConcurrenceErrors>> => { return rootPipe.pipe( Effect.bind('etapes', ({ pool, params }) => getEtapesByDemarcheId(pool, params.demarcheId)), Effect.bind('demarche', ({ pool, params }) => getDemarcheByIdOrSlug(pool, params.demarcheId)), - Effect.tap(({ etapes, demarche, user }) => - filterOrFailFromValidWithError(canPublishResultatMiseEnConcurrence(user, demarche.titre_type_id, demarche.demarche_type_id, etapes, demarche.demarche_id), 'droits insuffisants' as const) - ), + Effect.bind('machineInfo', ({ demarche }) => { + const machineInfo = MachineInfo.withMachineId(demarche.titre_type_id, demarche.demarche_type_id, demarche.demarche_id, demarche.machine_id) + if (machineInfo.valid) { + return Effect.succeed(machineInfo.value) + } + + return Effect.fail({ message: incoherentMachineInfo, extra: machineInfo.error }) + }), + Effect.tap(({ etapes, machineInfo, user }) => filterOrFailFromValidWithError(canPublishResultatMiseEnConcurrence(user, machineInfo, etapes), 'droits insuffisants' as const)), Effect.flatMap(({ pool, params, user }) => getDemarchePivotEnConcurrence(pool, params.demarcheId, user)), Effect.mapError(caminoError => Match.value(caminoError.message).pipe( Match.whenOr("La démarche n'existe pas", 'Impossible de trouver la date de la première étape', () => ({ ...caminoError, status: HTTP_STATUS.BAD_REQUEST })), - Match.whenOr("Impossible d'exécuter la requête dans la base de données", 'Les données en base ne correspondent pas à ce qui est attendu', () => ({ + Match.whenOr("Impossible d'exécuter la requête dans la base de données", 'Machine associée à la démarche incohérente', 'Les données en base ne correspondent pas à ce qui est attendu', () => ({ ...caminoError, status: HTTP_STATUS.INTERNAL_SERVER_ERROR, })), diff --git a/packages/api/src/api/rest/entreprises.test.integration.ts b/packages/api/src/api/rest/entreprises.test.integration.ts index 86b13b4155c685b32ab246c50e18b753e2d38e37..1bdff3998f671939168d357efb0ec839b7d07786 100644 --- a/packages/api/src/api/rest/entreprises.test.integration.ts +++ b/packages/api/src/api/rest/entreprises.test.integration.ts @@ -10,7 +10,6 @@ import { tempDocumentNameValidator } from 'camino-common/src/document' import { entreprisesEtablissementsFetch, entreprisesFetch, tokenInitialize } from '../../tools/api-insee/fetch' import { entreprise, entrepriseAndEtablissements } from '../../../tests/__mocks__/fetch-insee-api' import type { Pool } from 'pg' -import { titreDemarcheCreate } from '../../database/queries/titres-demarches' import { titreEtapeCreate } from '../../database/queries/titres-etapes' import { toCaminoAnnee, toCaminoDate } from 'camino-common/src/date' import { HTTP_STATUS } from 'camino-common/src/http' @@ -24,6 +23,9 @@ import { etapeCreate } from './rest-test-utils' import { insertTitreGraph } from '../../../tests/integration-test-helper' import { callAndExit } from '../../tools/fp-tools' import { z } from 'zod' +import { createDemarche } from './titre-demande.queries' +import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' +import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' console.info = vi.fn() console.warn = vi.fn() console.error = vi.fn() @@ -316,24 +318,23 @@ describe('getEntrepriseDocument', () => { await entrepriseUpsert({ id: entrepriseId, nom: entrepriseId }) const titreId = newTitreId() + const titreTypeId = TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX await insertTitreGraph({ id: titreId, nom: '', - typeId: 'arm', + typeId: titreTypeId, titreStatutId: 'ind', slug: titreSlugValidator.parse('arm-slug'), propsTitreEtapesIds: {}, }) - const titreDemarche = await titreDemarcheCreate({ - titreId, - typeId: 'oct', - }) + const titreDemarcheId = await callAndExit(createDemarche(dbPool, titreId, titreTypeId, DEMARCHES_TYPES_IDS.Octroi)) + const titreEtape = await titreEtapeCreate( { typeId: 'mfr', statutId: 'fai', - titreDemarcheId: titreDemarche.id, + titreDemarcheId: titreDemarcheId, date: toCaminoDate('2022-01-01'), ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, diff --git a/packages/api/src/api/rest/etape-creer.test.integration.ts b/packages/api/src/api/rest/etape-creer.test.integration.ts index 0fbb6a09707d7c77085cf5f1b42b4e2374171fef..5d3236154d38923538e0c933ac6b0561b0164b26 100644 --- a/packages/api/src/api/rest/etape-creer.test.integration.ts +++ b/packages/api/src/api/rest/etape-creer.test.integration.ts @@ -53,6 +53,7 @@ const demarcheCreate = async (titreTypeId: TitreTypeId = 'arm') => { propsTitreEtapesIds: {}, demarches: [ { + machineId: null, id: titreDemarcheId, titreId: titreId, typeId: 'oct', @@ -125,6 +126,7 @@ describe('etapeCreer', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: 'ProcedureSpecifique', id: demarcheId, titreId: titreId, typeId: DEMARCHES_TYPES_IDS.Octroi, diff --git a/packages/api/src/api/rest/etape-deposer.test.integration.ts b/packages/api/src/api/rest/etape-deposer.test.integration.ts index 55034704a8649e74bf65ceabb528d43275b1bf01..696d8bba64ec4c22706e3eec6410155c0d9b6038 100644 --- a/packages/api/src/api/rest/etape-deposer.test.integration.ts +++ b/packages/api/src/api/rest/etape-deposer.test.integration.ts @@ -133,6 +133,7 @@ describe('etapeDeposer', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: 'ProcedureSimplifiee', id: demarcheId, titreId: titreId, typeId: DEMARCHES_TYPES_IDS.Octroi, diff --git a/packages/api/src/api/rest/etape-modifier.test.integration.ts b/packages/api/src/api/rest/etape-modifier.test.integration.ts index fa59f834871841dd5f07ac3206bd8471842a1dbe..9318f03452fd612012ec3d0b142f61f3238ccd8e 100644 --- a/packages/api/src/api/rest/etape-modifier.test.integration.ts +++ b/packages/api/src/api/rest/etape-modifier.test.integration.ts @@ -95,6 +95,7 @@ describe('etapeModifier', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: null, id: demarcheId, titreId: newTitreId('titre-id'), typeId: 'oct', @@ -380,6 +381,7 @@ describe('etapeModifier', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: null, id: demarcheId, titreId: titreId, typeId: 'oct', diff --git a/packages/api/src/api/rest/etapes.test.integration.ts b/packages/api/src/api/rest/etapes.test.integration.ts index 2ada5d99e31c27e788730f40501a5c288c4b5fd7..38c190f8b793415d1f51b61ec61fa7b2409f3e05 100644 --- a/packages/api/src/api/rest/etapes.test.integration.ts +++ b/packages/api/src/api/rest/etapes.test.integration.ts @@ -1,7 +1,7 @@ import { dbManager } from '../../../tests/db-manager' import { userSuper } from '../../database/user-super' import { restCall, restNewCall, restNewDeleteCall, restNewPostCall } from '../../../tests/_utils/index' -import { caminoDateValidator, dateAddDays, toCaminoDate } from 'camino-common/src/date' +import { caminoDateValidator, dateAddDays, firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { afterAll, beforeAll, test, expect, describe, vi } from 'vitest' import type { Pool } from 'pg' import { HTTP_STATUS } from 'camino-common/src/http' @@ -19,11 +19,13 @@ import { tempDocumentNameValidator } from 'camino-common/src/document' import { idGenerate, newDemarcheId, newEtapeId, newTitreId } from '../../database/models/_format/id-create' import { insertTitreGraph } from '../../../tests/integration-test-helper' import { callAndExit } from '../../tools/fp-tools' -import { DATE_DEBUT_PROCEDURE_SPECIFIQUE_AXM_ARM } from 'camino-common/src/machines' +import { DATE_DEBUT_PRM_OCT, DATE_DEBUT_PROCEDURE_SPECIFIQUE_AXM_ARM, MachineInfo } from 'camino-common/src/machines' import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' import { copyFileSync, mkdirSync } from 'node:fs' import { z } from 'zod' +import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' +import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' console.info = vi.fn() console.error = vi.fn() @@ -46,6 +48,7 @@ describe('getEtapeEntrepriseDocuments', () => { const titreId = newTitreId() const demarcheId = newDemarcheId() const etapeId = newEtapeId() + const dateDemande = toCaminoDate('2025-01-31') await insertTitreGraph({ id: titreId, nom: 'nomTitre', @@ -54,6 +57,7 @@ describe('getEtapeEntrepriseDocuments', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse(dateDemande)).machineId ?? null, id: demarcheId, titreId, typeId: 'oct', @@ -61,7 +65,7 @@ describe('getEtapeEntrepriseDocuments', () => { { id: etapeId, typeId: ETAPES_TYPES.demande, - date: toCaminoDate('2025-01-31'), + date: dateDemande, isBrouillon: ETAPE_IS_NOT_BROUILLON, statutId: ETAPES_STATUTS.FAIT, titreDemarcheId: demarcheId, @@ -121,6 +125,7 @@ describe('getEtapesTypesEtapesStatusWithMainStep', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: 'AncienLogigrammeOctroiARM', id: demarcheId, titreId, typeId: 'oct', @@ -173,6 +178,7 @@ describe('getEtapesTypesEtapesStatusWithMainStep', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: 'ProcedureSpecifique', id: demarcheId, titreId, typeId: 'oct', @@ -194,10 +200,98 @@ describe('getEtapesTypesEtapesStatusWithMainStep', () => { } `) }) + + test('nouvelle étapes possibles change de machine en fonction de la date', async () => { + const titreId = newTitreId() + const demarcheId = newDemarcheId() + await insertTitreGraph({ + id: titreId, + nom: 'nomTitre', + typeId: TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, + titreStatutId: 'val', + propsTitreEtapesIds: {}, + demarches: [ + { + machineId: null, + id: demarcheId, + titreId, + typeId: DEMARCHES_TYPES_IDS.Octroi, + }, + ], + }) + + const tested = await restNewCall(dbPool, '/rest/etapesTypes/:demarcheId/:date', { demarcheId: demarcheId, date: dateAddDays(DATE_DEBUT_PRM_OCT, 20) }, userSuper) + + expect(tested.body).toMatchInlineSnapshot(` + { + "mfr": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": true, + }, + } + `) + + const testedTde = await restNewCall(dbPool, '/rest/etapesTypes/:demarcheId/:date', { demarcheId: demarcheId, date: dateAddDays(DATE_DEBUT_PRM_OCT, -20) }, userSuper) + expect(testedTde.body).toMatchSnapshot() + expect(tested.body).not.toStrictEqual(testedTde.body) + }) + + test('nouvelle étapes possibles change de machine quand on déplace une étape déjà existante', async () => { + const titreId = newTitreId() + const demarcheId = newDemarcheId() + const etapeId = newEtapeId() + const dateDemande = dateAddDays(DATE_DEBUT_PRM_OCT, -20) + await insertTitreGraph({ + id: titreId, + nom: 'nomTitre', + typeId: TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, + titreStatutId: 'val', + propsTitreEtapesIds: {}, + demarches: [ + { + machineId: null, + id: demarcheId, + titreId, + typeId: DEMARCHES_TYPES_IDS.Octroi, + etapes: [ + { + id: etapeId, + typeId: ETAPES_TYPES.demande, + date: dateDemande, + statutId: ETAPES_STATUTS.FAIT, + isBrouillon: ETAPE_IS_NOT_BROUILLON, + titreDemarcheId: demarcheId, + }, + ], + }, + ], + }) + + const testedTde = await restNewCall(dbPool, '/rest/etapesTypes/:demarcheId/:date', { demarcheId: demarcheId, date: dateDemande }, userSuper, { etapeId }) + expect(testedTde.body).toMatchSnapshot() + + const tested = await restNewCall(dbPool, '/rest/etapesTypes/:demarcheId/:date', { demarcheId, date: dateAddDays(dateDemande, 50) }, userSuper, { etapeId }) + + expect(tested.body).toMatchInlineSnapshot(` + { + "mfr": { + "etapeStatutIds": [ + "fai", + ], + "mainStep": true, + }, + } + `) + expect(tested.body).not.toStrictEqual(testedTde.body) + }) + test('nouvelle étapes possibles prends en compte les brouillons', async () => { const titreId = newTitreId() const demarcheId = newDemarcheId() const etapeId = newEtapeId() + const dateDemande = toCaminoDate('2024-06-27') await insertTitreGraph({ id: titreId, nom: 'nomTitre', @@ -206,6 +300,7 @@ describe('getEtapesTypesEtapesStatusWithMainStep', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse(dateDemande)).machineId ?? null, id: demarcheId, titreId, typeId: 'oct', @@ -213,7 +308,7 @@ describe('getEtapesTypesEtapesStatusWithMainStep', () => { { id: etapeId, typeId: 'mfr', - date: toCaminoDate('2024-06-27'), + date: dateDemande, titreDemarcheId: demarcheId, statutId: 'fai', isBrouillon: ETAPE_IS_BROUILLON, @@ -258,6 +353,7 @@ describe('etapeSupprimer', () => { const titreId = newTitreId() const demarcheId = newDemarcheId() const etapeId = newEtapeId() + const dateDemande = toCaminoDate('2018-01-01') await insertTitreGraph({ id: titreId, nom: 'nomTitre', @@ -266,6 +362,7 @@ describe('etapeSupprimer', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse(dateDemande)).machineId ?? null, id: demarcheId, titreId, typeId: 'oct', @@ -277,7 +374,7 @@ describe('etapeSupprimer', () => { isBrouillon: ETAPE_IS_BROUILLON, ordre: 1, titreDemarcheId: demarcheId, - date: toCaminoDate('2018-01-01'), + date: dateDemande, }, ], }, @@ -298,6 +395,7 @@ describe('etapeSupprimer', () => { const titreId = newTitreId() const demarcheId = newDemarcheId() const etapeId = newEtapeId() + const dateDemande = toCaminoDate('2018-01-01') await insertTitreGraph({ id: titreId, nom: 'nomTitre', @@ -306,6 +404,7 @@ describe('etapeSupprimer', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse(dateDemande)).machineId ?? null, id: demarcheId, titreId, typeId: 'oct', @@ -317,7 +416,7 @@ describe('etapeSupprimer', () => { isBrouillon: ETAPE_IS_BROUILLON, ordre: 1, titreDemarcheId: demarcheId, - date: toCaminoDate('2018-01-01'), + date: dateDemande, }, ], }, @@ -338,6 +437,7 @@ describe('etapeSupprimer', () => { const titreId = newTitreId() const demarcheId = newDemarcheId() const etapeId = newEtapeId() + const dateDemande = toCaminoDate('2018-01-01') await insertTitreGraph({ id: titreId, nom: 'nomTitre', @@ -347,6 +447,7 @@ describe('etapeSupprimer', () => { publicLecture: false, demarches: [ { + machineId: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse(dateDemande)).machineId ?? null, id: demarcheId, titreId, typeId: 'oct', @@ -360,7 +461,7 @@ describe('etapeSupprimer', () => { isBrouillon: ETAPE_IS_BROUILLON, ordre: 1, titreDemarcheId: demarcheId, - date: toCaminoDate('2018-01-01'), + date: dateDemande, titulaireIds: [titulaireId1], }, ], @@ -391,6 +492,7 @@ describe('getEtapeAvis', () => { const titreId = newTitreId() const demarcheId = newDemarcheId() const etapeId = newEtapeId() + const dateDemande = toCaminoDate('2018-01-01') await insertTitreGraph({ id: titreId, nom: 'nomTitre', @@ -399,6 +501,7 @@ describe('getEtapeAvis', () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse(dateDemande)).machineId ?? null, id: demarcheId, titreId, typeId: 'oct', @@ -410,7 +513,7 @@ describe('getEtapeAvis', () => { isBrouillon: ETAPE_IS_BROUILLON, ordre: 1, titreDemarcheId: demarcheId, - date: toCaminoDate('2018-01-01'), + date: dateDemande, }, ], }, diff --git a/packages/api/src/api/rest/etapes.ts b/packages/api/src/api/rest/etapes.ts index 56b44029e768a8cce74821cbb62f3d1276de3352..0743d590dfe923d9a9114c10c1f985d86d7686b6 100644 --- a/packages/api/src/api/rest/etapes.ts +++ b/packages/api/src/api/rest/etapes.ts @@ -10,7 +10,7 @@ import { ETAPE_IS_BROUILLON, getStatutId, } from 'camino-common/src/etape' -import { demarcheEnregistrementDemandeDateFind, DemarcheId } from 'camino-common/src/demarche' +import { DemarcheId } from 'camino-common/src/demarche' import { HTTP_STATUS } from 'camino-common/src/http' import { CaminoDate, firstEtapeDateValidator, getCurrent } from 'camino-common/src/date' import { titreDemarcheGet } from '../../database/queries/titres-demarches' @@ -20,7 +20,7 @@ import { User, isBureauDEtudes, isEntreprise } from 'camino-common/src/roles' import { canCreateEtape, canDeposeEtape, canDeleteEtape, canEditEtape } from 'camino-common/src/permissions/titres-etapes' import { canBeBrouillon, ETAPES_TYPES, isEtapeTypeId } from 'camino-common/src/static/etapesTypes' -import { NotNullableKeys, getKeys, isNonEmptyArray, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefined, memoize, onlyUnique } from 'camino-common/src/typescript-tools' +import { getKeys, isNonEmptyArray, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefined, isNullOrUndefinedOrEmpty, memoize, onlyUnique } from 'camino-common/src/typescript-tools' import { Pool } from 'pg' import { EntrepriseDocument, EntrepriseDocumentId, EtapeEntrepriseDocument } from 'camino-common/src/entreprise' import { @@ -66,8 +66,9 @@ import { RestNewDeleteCall, RestNewGetCall, RestNewPostCall, RestNewPutCall } fr import { Effect, Match, Option } from 'effect' import { EffectDbQueryAndValidateErrors } from '../../pg-database' import { CaminoError } from 'camino-common/src/zod-tools' -import { machineFind } from '../../business/rules-demarches/machines' import { TitreEtapeForMachine } from '../../business/rules-demarches/machine-common' +import { MachineInfo } from 'camino-common/src/machines' +import { ApiMachineInfo, demarcheEnregistrementDemandeDateFind } from '../../business/rules-demarches/machines' import { newEtapeId } from '../../database/models/_format/id-create' type GetEtapeEntrepriseDocumentsErrors = EffectDbQueryAndValidateErrors @@ -199,6 +200,7 @@ type DeleteEtapeErrors = | typeof demarcheIntrouvableError | typeof titreIntrouvableError | typeof demarcheInvalideError + | typeof incoherentMachineInfo export const deleteEtape: RestNewDeleteCall<'/rest/etapes/:etapeIdOrSlug'> = (rootPipe): Effect.Effect<Option.Option<never>, CaminoApiError<DeleteEtapeErrors>> => rootPipe.pipe( Effect.bind('etape', ({ params, user }) => @@ -283,8 +285,16 @@ export const deleteEtape: RestNewDeleteCall<'/rest/etapes/:etapeIdOrSlug'> = (ro ) ) ), - Effect.tap(({ fullDemarche, fullTitre, etape }) => { - const { valid, errors: rulesErrors } = titreDemarcheUpdatedEtatValidate(fullDemarche.typeId, fullTitre, etape, fullDemarche.id, fullDemarche.etapes!, true) + Effect.bind('machineInfo', ({ fullDemarche, titre }) => { + const machineInfo = MachineInfo.withMachineId(titre.typeId, fullDemarche.typeId, fullDemarche.id, fullDemarche.machineId) + if (!machineInfo.valid) { + return Effect.fail({ message: incoherentMachineInfo, extra: machineInfo.error }) + } + + return Effect.succeed(machineInfo.value) + }), + Effect.tap(({ fullDemarche, fullTitre, etape, machineInfo }) => { + const { valid, errors: rulesErrors } = titreDemarcheUpdatedEtatValidate(machineInfo, fullTitre.demarches!, etape, fullDemarche.etapes!, true) if (!valid) { return Effect.fail({ message: demarcheInvalideError, detail: rulesErrors.join(', ') }) } @@ -326,6 +336,7 @@ export const deleteEtape: RestNewDeleteCall<'/rest/etapes/:etapeIdOrSlug'> = (ro "Les tâches après mise à jour de l'étape ont échoué", "Une erreur s'est produite lors de la récupération de l'étape", "Une erreur s'est produite lors de la récupération de la démarche", + 'La machine associée à la démarche est incohérente', () => ({ ...caminoError, status: HTTP_STATUS.INTERNAL_SERVER_ERROR, @@ -336,7 +347,14 @@ export const deleteEtape: RestNewDeleteCall<'/rest/etapes/:etapeIdOrSlug'> = (ro ) ) -type GetEtapeErrors = EffectDbQueryAndValidateErrors | TitreEtapeToFlattenEtapeErrors | typeof etapeFetchError | typeof etapeIntrouvableError | typeof etapeIncompletError | typeof droitsManquantsError +type GetEtapeErrors = + | EffectDbQueryAndValidateErrors + | TitreEtapeToFlattenEtapeErrors + | typeof etapeFetchError + | typeof etapeIntrouvableError + | typeof etapeIncompletError + | typeof droitsManquantsError + | typeof incoherentMachineInfo export const getEtape: RestNewGetCall<'/rest/etapes/:etapeIdOrSlug'> = (rootPipe): Effect.Effect<FlattenEtape, CaminoApiError<GetEtapeErrors>> => rootPipe.pipe( Effect.bind('etape', ({ user, params }) => @@ -382,7 +400,15 @@ export const getEtape: RestNewGetCall<'/rest/etapes/:etapeIdOrSlug'> = (rootPipe }), () => ({ message: droitsManquantsError }) ), - Effect.flatMap(({ etape }) => iTitreEtapeToFlattenEtape(etape)), + Effect.bind('machineInfo', ({ demarche, titre }) => { + const machineInfo = MachineInfo.withMachineId(titre.typeId, demarche.typeId, demarche.id, demarche.machineId) + if (!machineInfo.valid) { + return Effect.fail({ message: incoherentMachineInfo, extra: machineInfo.error }) + } + + return Effect.succeed(machineInfo.value) + }), + Effect.flatMap(({ etape, machineInfo }) => iTitreEtapeToFlattenEtape(machineInfo, etape)), Effect.mapError(caminoError => Match.value(caminoError.message).pipe( Match.when("L'étape n'existe pas", () => ({ @@ -398,9 +424,8 @@ export const getEtape: RestNewGetCall<'/rest/etapes/:etapeIdOrSlug'> = (rootPipe 'Problème de validation de données', "Une erreur s'est produite lors de la récupération de l'étape", "pas d'héritage chargé", - 'pas de démarche chargée', - 'pas de démarche ou de titre chargé', 'pas de slug', + 'La machine associée à la démarche est incohérente', () => ({ ...caminoError, status: HTTP_STATUS.INTERNAL_SERVER_ERROR, @@ -449,14 +474,14 @@ export const arePointsOnPerimeter = (perimetre: FeatureMultiPolygon, points: Fea }) } const getForagesProperties = ( - titreTypeId: TitreTypeId, + machineInfo: MachineInfo, geojsonOrigineGeoSystemeId: GraphqlEtape['geojsonOrigineGeoSystemeId'], geojsonOrigineForages: GraphqlEtape['geojsonOrigineForages'], pool: Pool ): Effect.Effect<Pick<GraphqlEtape, 'geojson4326Forages' | 'geojsonOrigineForages'>, CaminoError<ConvertPointsErrors>> => Effect.Do.pipe( Effect.flatMap(() => { - if (canHaveForages(titreTypeId) && isNotNullNorUndefined(geojsonOrigineForages) && isNotNullNorUndefined(geojsonOrigineGeoSystemeId)) { + if (canHaveForages(machineInfo) && isNotNullNorUndefined(geojsonOrigineForages) && isNotNullNorUndefined(geojsonOrigineGeoSystemeId)) { return convertPoints(pool, geojsonOrigineGeoSystemeId, geojsonOrigineForages) } return Effect.succeed(null) @@ -477,7 +502,7 @@ const getPerimetreInfosInternal = ( geojson4326Perimetre: GraphqlEtape['geojson4326Perimetre'], geojsonOriginePerimetre: GraphqlEtape['geojsonOriginePerimetre'], geojsonOriginePoints: GraphqlEtape['geojsonOriginePoints'], - titreTypeId: TitreTypeId, + machineInfo: MachineInfo, geojsonOrigineGeoSystemeId: GraphqlEtape['geojsonOrigineGeoSystemeId'], geojsonOrigineForages: GraphqlEtape['geojsonOrigineForages'] ): Effect.Effect<PerimetreInfos, CaminoError<PerimetreInfosError>> => { @@ -492,7 +517,7 @@ const getPerimetreInfosInternal = ( () => ({ message: lespointsdoiventetresurleperimetreerror }) ), Effect.bind('geojsonInformation', value => getGeojsonInformation(pool, value.geometry)), - Effect.bind('forage', () => getForagesProperties(titreTypeId, geojsonOrigineGeoSystemeId, geojsonOrigineForages, pool)), + Effect.bind('forage', () => getForagesProperties(machineInfo, geojsonOrigineGeoSystemeId, geojsonOrigineForages, pool)), Effect.let('secteursMaritime', ({ geojsonInformation: { secteurs } }) => secteurs.map(s => getSecteurMaritime(s))), Effect.map(({ secteursMaritime, geojsonInformation: { departements, surface, communes, forets, sdom }, forage: { geojson4326Forages } }) => ({ surface, @@ -518,7 +543,8 @@ const getPerimetreInfosInternal = ( ) ) } -type GetFlattenEtapeErrors = PerimetreInfosError | TitreEtapeToFlattenEtapeErrors +const incoherentMachineInfo = 'La machine associée à la démarche est incohérente' as const +type GetFlattenEtapeErrors = PerimetreInfosError | TitreEtapeToFlattenEtapeErrors | typeof incoherentMachineInfo const getFlattenEtape = ( etape: RestEtapeCreation | RestEtapeModification, demarche: ITitreDemarche, @@ -530,13 +556,22 @@ const getFlattenEtape = ( etapeOldDemarcheIdsConsentement: TitreEtapeForMachine['demarcheIdsConsentement'], pool: Pool ): Effect.Effect<{ flattenEtape: Partial<Pick<ApiFlattenEtape, 'id'>> & Omit<ApiFlattenEtape, 'id'>; perimetreInfos: PerimetreInfos }, CaminoError<GetFlattenEtapeErrors>> => { - const titreEtapeHeritage = titreEtapeHeritageBuild(etape.date, etape.typeId, demarche, titreTypeId, demarche.typeId, 'id' in etape ? etape.id : null) return Effect.Do.pipe( - Effect.bind('perimetreInfos', () => - getPerimetreInfosInternal(pool, etape.geojson4326Perimetre, etape.geojsonOriginePerimetre, etape.geojsonOriginePoints, titreTypeId, etape.geojsonOrigineGeoSystemeId, etape.geojsonOrigineForages) + Effect.bind('machineInfo', () => { + const machineInfo = MachineInfo.withMachineId(titreTypeId, demarche.typeId, demarche.id, demarche.machineId) + if (!machineInfo.valid) { + return Effect.fail({ message: incoherentMachineInfo, extra: machineInfo.error }) + } + + return Effect.succeed(machineInfo.value) + }), + Effect.let('titreEtapeHeritage', ({ machineInfo }) => titreEtapeHeritageBuild(etape.date, machineInfo, etape.typeId, demarche, 'id' in etape ? etape.id : null)), + + Effect.bind('perimetreInfos', ({ machineInfo }) => + getPerimetreInfosInternal(pool, etape.geojson4326Perimetre, etape.geojsonOriginePerimetre, etape.geojsonOriginePoints, machineInfo, etape.geojsonOrigineGeoSystemeId, etape.geojsonOrigineForages) ), - Effect.bind('heritageProps', () => + Effect.bind('heritageProps', ({ titreEtapeHeritage }) => Effect.succeed( ETAPE_HERITAGE_PROPS.reduce<IHeritageProps>((acc, propId) => { acc[propId] = { @@ -548,8 +583,8 @@ const getFlattenEtape = ( }, {} as IHeritageProps) ) ), - Effect.bind('heritageContenu', () => { - const sections = getSections(titreTypeId, demarche.typeId, etape.typeId) + Effect.bind('heritageContenu', ({ machineInfo, titreEtapeHeritage }) => { + const sections = getSections(machineInfo, etape.typeId) const heritageContenu = sections.reduce<IHeritageContenu>((accSections, section) => { accSections[section.id] = section.elements.reduce<NonNullable<IHeritageContenu[string]>>((accElements, element) => { @@ -566,8 +601,8 @@ const getFlattenEtape = ( return Effect.succeed(heritageContenu) }), Effect.let('fakeEtapeId', () => newEtapeId('newId')), - Effect.bind('flattenEtape', ({ perimetreInfos, heritageProps, heritageContenu, fakeEtapeId }) => - iTitreEtapeToFlattenEtape({ + Effect.bind('flattenEtape', ({ perimetreInfos, heritageProps, heritageContenu, fakeEtapeId, machineInfo }) => + iTitreEtapeToFlattenEtape(machineInfo, { ...etape, demarche, ...perimetreInfos, @@ -600,6 +635,8 @@ const droitsInsuffisants = 'droits insuffisants pour créer cette étape' as con const erreurLorsDeLaCreationDeLEtape = "Une erreur est survenue lors de la création de l'étape" as const const tachesAnnexes = 'une erreur est survenue lors des tâches annexes' as const const envoieMails = 'une erreur est survenue lors des envois de mail' as const +const etapesNonChargees = "la liste des étapes n'est pas chargée" as const +const demarchesNonChargees = "la liste des démarches n'est pas chargée" as const type CreateEtapeError = | GetFlattenEtapeErrors | EffectDbQueryAndValidateErrors @@ -614,6 +651,8 @@ type CreateEtapeError = | typeof erreurLorsDeLaCreationDeLEtape | typeof tachesAnnexes | typeof envoieMails + | typeof etapesNonChargees + | typeof demarchesNonChargees export const createEtape: RestNewPostCall<'/rest/etapes'> = (rootPipe): Effect.Effect<{ id: EtapeId }, CaminoApiError<CreateEtapeError>> => { return rootPipe.pipe( Effect.tap(({ body: etape, user }) => @@ -649,28 +688,45 @@ export const createEtape: RestNewPostCall<'/rest/etapes'> = (rootPipe): Effect.E userSuper ), catch: e => ({ message: demarcheExistePas, extra: e }), - }) + }).pipe( + Effect.filterOrFail( + (demarche): demarche is ITitreDemarche => isNotNullNorUndefined(demarche), + () => ({ message: demarcheExistePas }) + ), + Effect.filterOrFail( + (demarche): demarche is ITitreDemarche & { etapes: ITitreEtape[] } => isNotNullNorUndefined(demarche.etapes), + () => ({ message: etapesNonChargees }) + ) + ) ), - Effect.filterOrFail( - (value): value is typeof value & { titreDemarche: Omit<ITitreDemarche, 'titre'> & { titre: ITitre } } => - isNotNullNorUndefined(value.titreDemarche) && isNotNullNorUndefined(value.titreDemarche.titre), - () => ({ message: titreExistePas }) + Effect.bind('titre', ({ titreDemarche }) => + Effect.Do.pipe( + Effect.map(() => titreDemarche.titre), + Effect.filterOrFail( + (value): value is ITitre => isNotNullNorUndefined(value), + () => ({ message: titreExistePas }) + ), + Effect.filterOrFail( + (value): value is ITitre & { demarches: ITitreDemarche[] } => isNotNullNorUndefined(value.demarches), + () => ({ message: demarchesNonChargees }) + ) + ) ), Effect.let('isBrouillon', ({ body: etape }) => canBeBrouillon(etape.typeId)), Effect.filterOrFail( - ({ isBrouillon, titreDemarche, user, body: etape }) => - canCreateEtape(user, etape.typeId, isBrouillon, titreDemarche.titre.titulaireIds ?? [], titreDemarche.titre.administrationsLocales ?? [], titreDemarche.typeId, { - typeId: titreDemarche.titre.typeId, - titreStatutId: titreDemarche.titre.titreStatutId, + ({ isBrouillon, titreDemarche, titre, user, body: etape }) => + canCreateEtape(user, etape.typeId, isBrouillon, titre.titulaireIds ?? [], titre.administrationsLocales ?? [], titreDemarche.typeId, { + typeId: titre.typeId, + titreStatutId: titre.titreStatutId, }), () => ({ message: droitsInsuffisants }) ), - Effect.bind('hasTitreFrom', ({ titreDemarche, pool }) => hasTitreFrom(pool, titreDemarche.titre.id)), - Effect.bind('flattenEtapeAndPerimetreInfo', ({ titreDemarche, isBrouillon, body: etape, pool, hasTitreFrom }) => + Effect.bind('hasTitreFrom', ({ titre, pool }) => hasTitreFrom(pool, titre.id)), + Effect.bind('flattenEtapeAndPerimetreInfo', ({ titreDemarche, isBrouillon, titre, body: etape, pool, hasTitreFrom }) => getFlattenEtape( etape as RestEtapeCreation, // TODO 2024-11-14 comment on fait là, si on met le deepReadonly ça transpire partout et c'est violent :( titreDemarche, - titreDemarche.titre.typeId, + titre.typeId, isBrouillon, etapeSlugValidator.parse('unknown'), etape.typeId === ETAPES_TYPES.demande ? { amIFirst: true } : 'non-applicable', @@ -682,19 +738,23 @@ export const createEtape: RestNewPostCall<'/rest/etapes'> = (rootPipe): Effect.E Effect.bind('entrepriseDocuments', ({ flattenEtapeAndPerimetreInfo, body: etape, user, pool }) => validateAndGetEntrepriseDocuments(pool, flattenEtapeAndPerimetreInfo.flattenEtape, etape.entrepriseDocumentIds, user) ), - Effect.tap(({ flattenEtapeAndPerimetreInfo, titreDemarche, entrepriseDocuments, body: etape, user }) => { + Effect.let('machineInfo', ({ body: etape, titre, titreDemarche }) => { const firstEtapeDate = demarcheEnregistrementDemandeDateFind(titreDemarche.etapes) + const value = isNotNullNorUndefined(firstEtapeDate) ? firstEtapeDate : firstEtapeDateValidator.parse(etape.date) + return MachineInfo.withDate(titre.typeId, titreDemarche.typeId, titreDemarche.id, value) + }), + Effect.tap(({ flattenEtapeAndPerimetreInfo, titreDemarche, titre, entrepriseDocuments, body: etape, user, machineInfo }) => { const rulesErrors = titreEtapeUpdationValidate( flattenEtapeAndPerimetreInfo.flattenEtape, - titreDemarche, - titreDemarche.titre, + titreDemarche.etapes, + titre.demarches, etape.etapeDocuments, etape.etapeAvis, entrepriseDocuments, flattenEtapeAndPerimetreInfo.perimetreInfos.sdomZones, flattenEtapeAndPerimetreInfo.perimetreInfos.communes.map(({ id }) => id), user, - isNotNullNorUndefined(firstEtapeDate) ? firstEtapeDate : firstEtapeDateValidator.parse(etape.date) + machineInfo ) if (isNotNullNorUndefinedNorEmpty(rulesErrors)) { return Effect.fail({ message: etapeNonValide, detail: rulesErrors.join(', ') }) @@ -728,10 +788,10 @@ export const createEtape: RestNewPostCall<'/rest/etapes'> = (rootPipe): Effect.E }) ), - Effect.tap(({ etapeUpdated, titreDemarche, user, pool }) => + Effect.tap(({ etapeUpdated, titreDemarche, titre, user, pool }) => Effect.tryPromise({ try: async () => { - await titreEtapeAdministrationsEmailsSend(etapeUpdated, titreDemarche.typeId, titreDemarche.titreId, titreDemarche.titre.typeId, user) + await titreEtapeAdministrationsEmailsSend(etapeUpdated, titreDemarche.typeId, titreDemarche.titreId, titre.typeId, user) await titreEtapeUtilisateursEmailsSend(etapeUpdated, titreDemarche.titreId, pool) }, catch: e => ({ message: envoieMails, extra: e }), @@ -765,11 +825,12 @@ export const createEtape: RestNewPostCall<'/rest/etapes'> = (rootPipe): Effect.E "impossible d'insérer un fichier en base", 'Une erreur inattendue est survenue lors de la récupération des informations geojson en base', 'Impossible de transformer la feature collection', - 'pas de démarche chargée', - 'pas de démarche ou de titre chargé', "pas d'héritage chargé", 'pas de slug', 'Les données en base ne correspondent pas à ce qui est attendu', + 'La machine associée à la démarche est incohérente', + "la liste des étapes n'est pas chargée", + "la liste des démarches n'est pas chargée", () => ({ ...caminoError, status: HTTP_STATUS.INTERNAL_SERVER_ERROR }) ), Match.exhaustive @@ -802,6 +863,9 @@ type UpdateEtapeErrors = | InsertEtapeDocumentsErrors | UpdateEtapeDocumentsErrors | UpdateEtapeAvisErrors + | typeof etapesNonChargees + | typeof demarchesNonChargees + | typeof titreExistePas export const updateEtape: RestNewPutCall<'/rest/etapes'> = (rootPipe): Effect.Effect<{ id: EtapeId }, CaminoApiError<UpdateEtapeErrors>> => { return rootPipe.pipe( Effect.let('etape', ({ body }) => body), @@ -828,22 +892,6 @@ export const updateEtape: RestNewPutCall<'/rest/etapes'> = (rootPipe): Effect.Ef isNotNullNorUndefined(value.demarche) && isNotNullNorUndefined(value.demarche.titre) && value.demarche.titre.administrationsLocales !== undefined, () => ({ message: demarcheNonChargee }) ), - Effect.filterOrFail( - titreEtapeOld => - canEditEtape( - user, - titreEtapeOld.typeId, - titreEtapeOld.isBrouillon, - titreEtapeOld.titulaireIds ?? [], - titreEtapeOld.demarche.titre.administrationsLocales ?? [], - titreEtapeOld.demarche.typeId, - { - typeId: titreEtapeOld.demarche.titre.typeId, - titreStatutId: titreEtapeOld.demarche.titre.titreStatutId, - } - ), - () => ({ message: droitsInsuffisantsUpdate }) - ), Effect.filterOrFail( titreEtapeOld => titreEtapeOld.typeId === etape.typeId, () => ({ message: interditTypeEtapeEdition }) @@ -875,24 +923,42 @@ export const updateEtape: RestNewPutCall<'/rest/etapes'> = (rootPipe): Effect.Ef catch: e => ({ message: demarcheExistePas, extra: e }), }).pipe( Effect.filterOrFail( - (value): value is ITitreDemarche & { titre: ITitre } => isNotNullNorUndefined(value) && isNotNullNorUndefined(value.titre), + (demarche): demarche is ITitreDemarche => isNotNullNorUndefined(demarche), () => ({ message: demarcheExistePas }) ), Effect.filterOrFail( - value => isNotNullNorUndefined(value.titre.titulaireIds) && isNotNullNorUndefined(value.titre.amodiataireIds), - () => ({ message: demarcheNonChargee }) + (demarche): demarche is ITitreDemarche & { etapes: ITitreEtape[] } => isNotNullNorUndefined(demarche.etapes), + () => ({ message: etapesNonChargees }) ) ) ), - Effect.let('titreTypeId', ({ titreDemarche }) => titreDemarche.titre.typeId), - Effect.let('isBrouillon', ({ titreEtapeOld }) => titreEtapeOld.isBrouillon), - - Effect.bind('flattenEtapeAndPerimetre', ({ etape, titreDemarche, titreTypeId, isBrouillon, titreEtapeOld, pool }) => + Effect.bind('titre', ({ titreDemarche }) => + Effect.Do.pipe( + Effect.map(() => titreDemarche.titre), + Effect.filterOrFail( + (value): value is ITitre => isNotNullNorUndefined(value), + () => ({ message: titreExistePas }) + ), + Effect.filterOrFail( + (value): value is ITitre & { demarches: ITitreDemarche[] } => isNotNullNorUndefined(value.demarches), + () => ({ message: demarchesNonChargees }) + ) + ) + ), + Effect.filterOrFail( + ({ titreEtapeOld, titre, user }) => + canEditEtape(user, titreEtapeOld.typeId, titreEtapeOld.isBrouillon, titre.titulaireIds ?? [], titreEtapeOld.demarche.titre.administrationsLocales ?? [], titreEtapeOld.demarche.typeId, { + typeId: titreEtapeOld.demarche.titre.typeId, + titreStatutId: titreEtapeOld.demarche.titre.titreStatutId, + }), + () => ({ message: droitsInsuffisantsUpdate }) + ), + Effect.bind('flattenEtapeAndPerimetre', ({ etape, titreDemarche, titre, titreEtapeOld, pool }) => getFlattenEtape( etape as RestEtapeModification, // TODO 2024-11-14 comment on fait là, si on met le deepReadonly ça transpire partout et c'est violent :( titreDemarche, - titreTypeId, - isBrouillon, + titre.typeId, + titreEtapeOld.isBrouillon, titreEtapeOld.slug, titreEtapeOld.concurrence, titreEtapeOld.hasTitreFrom, @@ -903,23 +969,23 @@ export const updateEtape: RestNewPutCall<'/rest/etapes'> = (rootPipe): Effect.Ef Effect.bind('entrepriseDocuments', ({ pool, flattenEtapeAndPerimetre, etape, user }) => validateAndGetEntrepriseDocuments(pool, flattenEtapeAndPerimetre.flattenEtape, etape.entrepriseDocumentIds, user) ), - Effect.let('firstEtapeDate', ({ titreDemarche, etape }) => { + Effect.let('machineInfo', ({ body: etape, titreDemarche, titre }) => { const firstEtapeDate = demarcheEnregistrementDemandeDateFind(titreDemarche.etapes) - - return isNotNullNorUndefined(firstEtapeDate) ? firstEtapeDate : firstEtapeDateValidator.parse(etape.date) + const value = isNotNullNorUndefined(firstEtapeDate) ? firstEtapeDate : firstEtapeDateValidator.parse(etape.date) + return MachineInfo.withDate(titre.typeId, titreDemarche.typeId, titreDemarche.id, value) }), - Effect.tap(({ flattenEtapeAndPerimetre, titreDemarche, entrepriseDocuments, etape, user, titreEtapeOld, firstEtapeDate }) => { + Effect.tap(({ flattenEtapeAndPerimetre, titre, titreDemarche, entrepriseDocuments, etape, user, titreEtapeOld, machineInfo }) => { const rulesErrors = titreEtapeUpdationValidate( flattenEtapeAndPerimetre.flattenEtape, - titreDemarche, - titreDemarche.titre, + titreDemarche.etapes, + titre.demarches, etape.etapeDocuments, etape.etapeAvis, entrepriseDocuments, flattenEtapeAndPerimetre.perimetreInfos.sdomZones, flattenEtapeAndPerimetre.perimetreInfos.communes.map(({ id }) => id), user, - firstEtapeDate, + machineInfo, titreEtapeOld ) if (isNotNullNorUndefinedNorEmpty(rulesErrors)) { @@ -928,7 +994,7 @@ export const updateEtape: RestNewPutCall<'/rest/etapes'> = (rootPipe): Effect.Ef return Effect.succeed(null) }), Effect.tap(({ etape, pool }) => checkEntreprisesExist(pool, [...etape.titulaireIds, ...etape.amodiataireIds])), - Effect.bind('etapeUpdated', ({ etape, flattenEtapeAndPerimetre, titreEtapeOld, user, titreDemarche, isBrouillon }) => + Effect.bind('etapeUpdated', ({ etape, flattenEtapeAndPerimetre, titreEtapeOld, user, titreDemarche }) => Effect.tryPromise({ try: async () => { const value = await titreEtapeUpsert( @@ -936,7 +1002,7 @@ export const updateEtape: RestNewPutCall<'/rest/etapes'> = (rootPipe): Effect.Ef ...etape, statutId: getStatutId(flattenEtapeAndPerimetre.flattenEtape, getCurrent()), ...flattenEtapeAndPerimetre.perimetreInfos, - isBrouillon, + isBrouillon: titreEtapeOld.isBrouillon, demarcheIdsConsentement: titreEtapeOld.demarcheIdsConsentement, }, user, @@ -953,18 +1019,15 @@ export const updateEtape: RestNewPutCall<'/rest/etapes'> = (rootPipe): Effect.Ef Effect.tap(({ pool, etapeUpdated, etape }) => updateEtapeDocuments(pool, etapeUpdated.id, etape.etapeDocuments)), Effect.tap(({ pool, etapeUpdated }) => deleteTitreEtapeEntrepriseDocument(pool, { titre_etape_id: etapeUpdated.id })), Effect.tap(({ pool, etapeUpdated, entrepriseDocuments }) => insertTitreEtapeEntrepriseDocuments(pool, etapeUpdated.id, entrepriseDocuments)), - Effect.tap(({ pool, isBrouillon, etapeUpdated, etape, titreTypeId, titreDemarche, flattenEtapeAndPerimetre, firstEtapeDate }) => + Effect.tap(({ pool, titreEtapeOld, etapeUpdated, etape, flattenEtapeAndPerimetre, machineInfo }) => updateEtapeAvis( pool, etapeUpdated.id, - isBrouillon, + titreEtapeOld.isBrouillon, etape.etapeAvis, etape.typeId, flattenEtapeAndPerimetre.flattenEtape.contenu, - titreTypeId, - titreDemarche.typeId, - titreDemarche.id, - firstEtapeDate, + machineInfo, flattenEtapeAndPerimetre.perimetreInfos.communes.map(({ id }) => id) ) ), @@ -974,16 +1037,16 @@ export const updateEtape: RestNewPutCall<'/rest/etapes'> = (rootPipe): Effect.Ef catch: e => ({ message: tachesAnnexes, extra: e }), }) ), - Effect.tap(({ titreDemarche, titreEtapeOld, flattenEtapeAndPerimetre, user }) => + Effect.tap(({ titreDemarche, titreEtapeOld, flattenEtapeAndPerimetre, user, titre }) => Effect.tryPromise({ - try: () => titreEtapeAdministrationsEmailsSend(flattenEtapeAndPerimetre.flattenEtape, titreDemarche.typeId, titreDemarche.titreId, titreDemarche.titre.typeId, user, titreEtapeOld), + try: () => titreEtapeAdministrationsEmailsSend(flattenEtapeAndPerimetre.flattenEtape, titreDemarche.typeId, titreDemarche.titreId, titre.typeId, user, titreEtapeOld), catch: e => ({ message: envoieMails, extra: e }), }) ), Effect.map(({ titreEtapeOld }) => ({ id: titreEtapeOld.id })), Effect.mapError(caminoError => Match.value(caminoError.message).pipe( - Match.whenOr("la démarche n'existe pas", "L'étape n'existe pas", () => ({ ...caminoError, status: HTTP_STATUS.NOT_FOUND })), + Match.whenOr("la démarche n'existe pas", "L'étape n'existe pas", "le titre n'existe pas", () => ({ ...caminoError, status: HTTP_STATUS.NOT_FOUND })), Match.whenOr( "l'étape n'est pas valide", "certaines entreprises n'existent pas", @@ -1011,11 +1074,12 @@ export const updateEtape: RestNewPutCall<'/rest/etapes'> = (rootPipe): Effect.Ef "impossible d'insérer un fichier en base", 'Une erreur inattendue est survenue lors de la récupération des informations geojson en base', 'Impossible de transformer la feature collection', - 'pas de démarche chargée', - 'pas de démarche ou de titre chargé', "pas d'héritage chargé", 'pas de slug', 'Les données en base ne correspondent pas à ce qui est attendu', + 'La machine associée à la démarche est incohérente', + "la liste des étapes n'est pas chargée", + "la liste des démarches n'est pas chargée", () => ({ ...caminoError, status: HTTP_STATUS.INTERNAL_SERVER_ERROR }) ), Match.exhaustive @@ -1048,6 +1112,7 @@ type DeposeEtapeErrors = | typeof impossibleDeRecupererLEtapeApresMaj | typeof impossibleDeMajLEtape | typeof envoieMails + | typeof incoherentMachineInfo | EffectDbQueryAndValidateErrors | GetGeojsonInformationErrorMessages | TitreEtapeToFlattenEtapeErrors @@ -1095,7 +1160,7 @@ export const deposeEtape: RestNewPutCall<'/rest/etapes/:etapeId/depot'> = (rootP Effect.bind('titre', ({ titreDemarche }) => Effect.succeed(titreDemarche.titre).pipe( Effect.filterOrFail( - titre => isNotNullNorUndefined(titre), + (titre): titre is NonNullable<ITitre> => isNotNullNorUndefined(titre), () => ({ message: titreNonExistant }) ), Effect.filterOrFail( @@ -1143,8 +1208,15 @@ export const deposeEtape: RestNewPutCall<'/rest/etapes/:etapeId/depot'> = (rootP } ) ), - Effect.bind('flattenEtape', ({ titreEtape }) => iTitreEtapeToFlattenEtape(titreEtape)), - Effect.let('firstEtapeDate', ({ titreDemarche }) => demarcheEnregistrementDemandeDateFind(titreDemarche.etapes)), + Effect.bind('machineInfo', ({ titreDemarche, titre }) => { + const machineInfo = MachineInfo.withMachineId(titre.typeId, titreDemarche.typeId, titreDemarche.id, titreDemarche.machineId) + if (!machineInfo.valid) { + return Effect.fail({ message: incoherentMachineInfo, extra: machineInfo.error }) + } + + return Effect.succeed(machineInfo.value) + }), + Effect.bind('flattenEtape', ({ titreEtape, machineInfo }) => iTitreEtapeToFlattenEtape(machineInfo, titreEtape)), Effect.let('date', ({ user, titreEtape }) => (isEntreprise(user) || isBureauDEtudes(user) ? getCurrent() : titreEtape.date)), Effect.bind('sdomEtCommunes', ({ titreEtape, pool }) => { if (isNotNullNorUndefined(titreEtape.geojson4326Perimetre)) { @@ -1156,19 +1228,17 @@ export const deposeEtape: RestNewPutCall<'/rest/etapes/:etapeId/depot'> = (rootP return Effect.succeed(emptyResult) }), Effect.filterOrFail( - ({ user, titre, titreDemarche, flattenEtape, etapeDocuments, entrepriseDocuments, sdomEtCommunes, etapeAvis, firstEtapeDate, date }) => + ({ user, titre, flattenEtape, etapeDocuments, entrepriseDocuments, sdomEtCommunes, etapeAvis, machineInfo }) => canDeposeEtape( user, + machineInfo, { ...titre, titulaires: titre.titulaireIds ?? [], administrationsLocales: titre.administrationsLocales ?? [] }, - titreDemarche.id, - titreDemarche.typeId, flattenEtape, etapeDocuments, entrepriseDocuments, sdomEtCommunes.sdomZones, sdomEtCommunes.communes, - etapeAvis, - isNotNullNorUndefined(firstEtapeDate) ? firstEtapeDate : firstEtapeDateValidator.parse(date) + etapeAvis ), () => ({ message: droitsInsuffisantsDeposeEtape }) ), @@ -1241,14 +1311,13 @@ export const deposeEtape: RestNewPutCall<'/rest/etapes/:etapeId/depot'> = (rootP 'Problème de validation de données', 'Une erreur inattendue est survenue lors de la récupération des informations geojson en base', "pas d'héritage chargé", - 'pas de démarche chargée', - 'pas de démarche ou de titre chargé', 'pas de slug', 'une erreur est survenue lors des envois de mail', 'une erreur est survenue lors des tâches annexes', "une erreur s'est produite lors de la vérification des droits de lecture d'un avis", "une erreur s'est produite lors de la vérification des droits de lecture d'un document", "Impossible de transformer le document en base en document d'API", + 'La machine associée à la démarche est incohérente', () => ({ ...caminoError, status: HTTP_STATUS.INTERNAL_SERVER_ERROR }) ), Match.exhaustive @@ -1273,6 +1342,7 @@ export const getEtapesTypesEtapesStatusWithMainStep: RestNewGetCall<'/rest/etape "impossible de récupérer l'étape", 'impossible de récupérer la démarche', 'Les données en base ne correspondent pas à ce qui est attendu', + 'La machine associée à la démarche est incohérente', () => ({ ...caminoError, status: HTTP_STATUS.INTERNAL_SERVER_ERROR }) ), Match.exhaustive @@ -1297,6 +1367,7 @@ type DemarcheEtapesTypesGetErrors = | typeof impossibleDeRecupererLEtape | typeof etapeNonExistante | typeof impossibleDeRecupererLesEtapesTypes + | typeof incoherentMachineInfo const demarcheEtapesTypesGet = ( titreDemarcheId: DemarcheId, date: CaminoDate, @@ -1322,19 +1393,30 @@ const demarcheEtapesTypesGet = ( userSuper ), catch: e => ({ message: impossibleDeRecupererLaDemarche, extra: e }), - }) - ), - Effect.filterOrFail( - (result): result is NotNullableKeys<typeof result> => isNotNullNorUndefined(result.titreDemarche), - () => ({ message: demarcheInexistante }) + }).pipe( + Effect.filterOrFail( + (demarche): demarche is ITitreDemarche => isNotNullNorUndefined(demarche), + () => ({ message: demarcheInexistante }) + ) + ) ), - Effect.filterOrFail( - (result): result is NotNullableKeys<typeof result> & { titreDemarche: { titre: ITitre } } => isNotNullNorUndefined(result.titreDemarche.titre?.titulaireIds), - () => ({ message: demarcheIncomplete }) + Effect.bind('titre', ({ titreDemarche }) => + Effect.Do.pipe( + Effect.map(() => titreDemarche.titre), + Effect.filterOrFail( + (titre): titre is ITitre => isNotNullNorUndefined(titre), + () => ({ message: demarcheIncomplete }) + ) + ) ), - Effect.filterOrFail( - ({ titreDemarche }) => isNotNullNorUndefined(titreDemarche.etapes), - () => ({ message: etapeNonChargees }) + Effect.bind('etapes', ({ titreDemarche }) => + Effect.Do.pipe( + Effect.map(() => titreDemarche.etapes), + Effect.filterOrFail( + (etapes): etapes is ITitreEtape[] => isNotNullNorUndefined(etapes), + () => ({ message: etapeNonChargees }) + ) + ) ), Effect.bind('etape', () => Effect.tryPromise({ @@ -1352,33 +1434,45 @@ const demarcheEtapesTypesGet = ( ({ etape }) => isNullOrUndefined(titreEtapeId) || (isNotNullNorUndefined(titreEtapeId) && isNotNullNorUndefined(etape)), () => ({ message: etapeNonExistante }) ), - Effect.let('firstEtapeDate', ({ titreDemarche }) => demarcheEnregistrementDemandeDateFind(titreDemarche.etapes)), - Effect.let('machine', ({ titreDemarche, firstEtapeDate }) => - machineFind(titreDemarche.titre.typeId, titreDemarche.typeId, titreDemarche.id, isNotNullNorUndefined(firstEtapeDate) ? firstEtapeDate : firstEtapeDateValidator.parse(date)) - ), + Effect.bind('machine', ({ etapes, titre, titreDemarche }) => { + if (isNullOrUndefinedOrEmpty(etapes)) { + return Effect.succeed(new ApiMachineInfo(MachineInfo.withDate(titre.typeId, titreDemarche.typeId, titreDemarche.id, firstEtapeDateValidator.parse(date)))) + } + const newDateMachine = demarcheEnregistrementDemandeDateFind( + etapes.map(etape => { + if (etape.id === titreEtapeId) { + return { ...etape, date: date } + } + + return etape + }) + ) + if (isNotNullNorUndefined(newDateMachine)) { + return Effect.succeed(new ApiMachineInfo(MachineInfo.withDate(titre.typeId, titreDemarche.typeId, titreDemarche.id, newDateMachine))) + } + + const machineInfo = MachineInfo.withMachineId(titre.typeId, titreDemarche.typeId, titreDemarche.id, titreDemarche.machineId) + if (!machineInfo.valid) { + return Effect.fail({ message: incoherentMachineInfo, extra: machineInfo.error }) + } + + return Effect.succeed(new ApiMachineInfo(machineInfo.value)) + }), Effect.bind('etapesTypes', ({ machine, titreDemarche, etape }) => Effect.try({ try: () => { - const etapesTypes: EtapeTypeEtapeStatutWithMainStep = getPossiblesEtapesTypes( - machine, - titreDemarche.titre.typeId, - titreDemarche.typeId, - etape?.typeId, - titreEtapeId ?? undefined, - date, - titreDemarche.etapes ?? [] - ) + const etapesTypes: EtapeTypeEtapeStatutWithMainStep = getPossiblesEtapesTypes(machine, etape?.typeId, titreEtapeId ?? undefined, date, titreDemarche.etapes ?? []) return etapesTypes }, catch: e => ({ message: impossibleDeRecupererLesEtapesTypes, extra: e }), }) ), - Effect.map(({ etapesTypes, titreDemarche }) => + Effect.map(({ etapesTypes, titreDemarche, titre }) => getKeys(etapesTypes, isEtapeTypeId).reduce<EtapeTypeEtapeStatutWithMainStep>((acc, etapeTypeId) => { if ( - canCreateEtape(user, etapeTypeId, ETAPE_IS_BROUILLON, titreDemarche.titre.titulaireIds ?? [], titreDemarche.titre.administrationsLocales ?? [], titreDemarche.typeId, { - typeId: titreDemarche.titre.typeId, - titreStatutId: titreDemarche.titre.titreStatutId, + canCreateEtape(user, etapeTypeId, ETAPE_IS_BROUILLON, titre.titulaireIds ?? [], titre.administrationsLocales ?? [], titreDemarche.typeId, { + typeId: titre.typeId, + titreStatutId: titre.titreStatutId, }) ) { acc[etapeTypeId] = etapesTypes[etapeTypeId] diff --git a/packages/api/src/api/rest/format/titres.ts b/packages/api/src/api/rest/format/titres.ts index e852d4c9180476c5b84311dafc23cd33866e6e21..91f8e17fac3508f8c8b089a999f47c9e94ece67b 100644 --- a/packages/api/src/api/rest/format/titres.ts +++ b/packages/api/src/api/rest/format/titres.ts @@ -25,6 +25,7 @@ import { GetEntreprises, getEntreprises } from '../entreprises.queries' import { EntrepriseId } from 'camino-common/src/entreprise' import { slugify } from 'camino-common/src/strings' import { callAndExit } from '../../../tools/fp-tools' +import { MachineInfo } from 'camino-common/src/machines' const getFacadesMaritimeCell = (secteursMaritime: SecteursMaritimes[], separator: string): string => getFacadesComputed(secteursMaritime) @@ -37,9 +38,16 @@ const titreContenuTableFormat = (titre: ITitre): Record<string, string> => { if (isNullOrUndefinedOrEmpty(orderedDemarches)) { return {} } + // TODO 2025-03-27: ne pas prendre la première démarche mais la dernière démarche valide avec infos publiques (?) const demarche = orderedDemarches[0] + const machineInfo = MachineInfo.withMachineId(titre.typeId, demarche.typeId, demarche.id, demarche.machineId) + if (!machineInfo.valid) { + console.error(`La machine associée à la démarche est invalide : ${machineInfo.error}`) + return {} + } + const etapes = (demarche.etapes ?? []).map(etape => { - const sections = getSections(titre.typeId, demarche.typeId, etape.typeId) + const sections = getSections(machineInfo.value, etape.typeId) .map(section => ({ ...section, elements: section.elements.filter(element => !(etape.heritageContenu?.[section.id]?.[element.id]?.actif ?? false)) })) .filter(section => section.elements.length > 0) diff --git a/packages/api/src/api/rest/index.test.integration.ts b/packages/api/src/api/rest/index.test.integration.ts index 932304974c7d6c2d4f1a49eb263da0a369159779..f3e4184086ab8ebfc7f4cee893ec03a6b8e4cea3 100644 --- a/packages/api/src/api/rest/index.test.integration.ts +++ b/packages/api/src/api/rest/index.test.integration.ts @@ -59,6 +59,7 @@ beforeAll(async () => { id: demarcheId, titreId: titreId, typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: null, etapes: [ { id: etapeId, diff --git a/packages/api/src/api/rest/perimetre.test.integration.ts b/packages/api/src/api/rest/perimetre.test.integration.ts index 64aaeb1d0352a91bd286f3cac921236606ae7370..d2c644c903c653ff42a2a22ee4bc1fbbe8784311 100644 --- a/packages/api/src/api/rest/perimetre.test.integration.ts +++ b/packages/api/src/api/rest/perimetre.test.integration.ts @@ -1724,6 +1724,7 @@ describe('getPerimetreInfosByEtape', () => { propsTitreEtapesIds: { titulaires: 'titre-id-demarche-id-dpu', points: 'titre-id-demarche-id-dpu' }, demarches: [ { + machineId: null, id: newDemarcheId('titre-id-demarche-id'), titreId: newTitreId('titre-id'), typeId: 'oct', @@ -1783,6 +1784,7 @@ describe('getPerimetreInfosByDemarche', () => { propsTitreEtapesIds: { titulaires: 'titre-id-demarche-id-dpu', points: 'titre-id-demarche-id-dpu' }, demarches: [ { + machineId: null, id: demarcheId, titreId: newTitreId('titre-id'), typeId: 'oct', @@ -1837,6 +1839,7 @@ describe('getPerimetreInfosByDemarche', () => { propsTitreEtapesIds: { titulaires: 'titre-id-demarche-id-dpu', points: 'titre-id-demarche-id-dpu' }, demarches: [ { + machineId: null, id: demarcheId, titreId: newTitreId('titre-id'), typeId: 'oct', diff --git a/packages/api/src/api/rest/rest-test-utils.ts b/packages/api/src/api/rest/rest-test-utils.ts index 6f8f1669e8a4c52c5f3af6d0b129d82262dd5a4f..c91c2764777b74c774ed80cfeedaaf1a9ed81046 100644 --- a/packages/api/src/api/rest/rest-test-utils.ts +++ b/packages/api/src/api/rest/rest-test-utils.ts @@ -1,4 +1,4 @@ -import { CaminoDate, toCaminoDate } from 'camino-common/src/date' +import { CaminoDate, firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { DemarcheId } from 'camino-common/src/demarche' import { EtapeBrouillon, EtapeId } from 'camino-common/src/etape' import { EtapeTypeId, canBeBrouillon } from 'camino-common/src/static/etapesTypes' @@ -7,6 +7,8 @@ import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools' import { TitreId } from 'camino-common/src/validators/titres' import { insertTitreGraph } from '../../../tests/integration-test-helper' import { newDemarcheId, newEtapeId, newTitreId } from '../../database/models/_format/id-create' +import { MachineInfo } from 'camino-common/src/machines' +import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' export async function etapeCreate( typeId?: EtapeTypeId, @@ -32,8 +34,8 @@ export async function etapeCreate( { id: demarcheId, titreId: titreId, - typeId: 'oct', - + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(titreTypeId, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(date)).machineId ?? null, etapes: [ { id: etapeId, diff --git a/packages/api/src/api/rest/titre-demande.queries.ts b/packages/api/src/api/rest/titre-demande.queries.ts index 9633e3e9d5decc5e6615d6e3ad5898cdee9bee20..6ce330e92e7779a814fee55663aa6a2b26082df1 100644 --- a/packages/api/src/api/rest/titre-demande.queries.ts +++ b/packages/api/src/api/rest/titre-demande.queries.ts @@ -12,6 +12,10 @@ import { ICreateTitreDemarcheInternalQuery, ICreateTitreInternalQuery } from './ import { TitreDemande } from 'camino-common/src/titres.js' import { DemarcheId, DemarcheSlug } from 'camino-common/src/demarche.js' import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes.js' +import { CaminoMachineId } from 'camino-common/src/validators/machine.js' +import { MachineInfo } from 'camino-common/src/machines.js' +import { TitreTypeId } from 'camino-common/src/static/titresTypes.js' +import { firstEtapeDateValidator, getCurrent } from 'camino-common/src/date.js' type CreateTitreInput = Omit<TitreDemande, 'titreFromIds' | 'entrepriseId'> @@ -39,22 +43,25 @@ INSERT INTO titres (id, slug, nom, type_id, "references") VALUES ($ id !, $slug!, $ nom !, $ titreTypeId!, $references!) ` -const creationDemarcheImpossible = 'Création de la démarche impossible' as const -export type CreateDemarcheErrors = EffectDbQueryAndValidateErrors | 'Accès interdit' | typeof creationDemarcheImpossible -export const createDemarche = (pool: Pool, titreId: TitreId, demarcheTypeId: DemarcheTypeId): Effect.Effect<DemarcheId, CaminoError<CreateDemarcheErrors>> => { +export type CreateDemarcheErrors = EffectDbQueryAndValidateErrors +export const createDemarche = ( + pool: Pool, + titreId: TitreId, + titreTypeId: TitreTypeId, + demarcheTypeId: DemarcheTypeId, + description: string = '' +): Effect.Effect<DemarcheId, CaminoError<CreateDemarcheErrors>> => { return Effect.Do.pipe( - Effect.bind('id', () => Effect.succeed(newDemarcheId())), - Effect.bind('slug', () => - Effect.try({ - try: () => newDemarcheSlug(titreId, demarcheTypeId), - catch: unknown => ({ message: creationDemarcheImpossible, extra: unknown }), - }) - ), - Effect.tap(({ id, slug }) => effectDbQueryAndValidate(createTitreDemarcheInternal, { id, slug, titre_id: titreId, demarcheTypeId }, pool, z.void())), + Effect.let('id', () => newDemarcheId()), + Effect.let('slug', () => newDemarcheSlug(titreId, demarcheTypeId)), + Effect.let('machineId', ({ id }) => MachineInfo.withDate(titreTypeId, demarcheTypeId, id, firstEtapeDateValidator.parse(getCurrent())).machineId ?? null), + Effect.tap(({ id, slug, machineId }) => effectDbQueryAndValidate(createTitreDemarcheInternal, { id, slug, titre_id: titreId, demarcheTypeId, machineId, description }, pool, z.void())), Effect.map(({ id }) => id) ) } -const createTitreDemarcheInternal = sql<Redefine<ICreateTitreDemarcheInternalQuery, { id: DemarcheId; slug: DemarcheSlug; titre_id: TitreId; demarcheTypeId: DemarcheTypeId }, void>>` -INSERT INTO titres_demarches (id, slug, titre_id, type_id) - VALUES ($ id !, $slug!, $ titre_id !, $demarcheTypeId) +const createTitreDemarcheInternal = sql< + Redefine<ICreateTitreDemarcheInternalQuery, { id: DemarcheId; slug: DemarcheSlug; titre_id: TitreId; demarcheTypeId: DemarcheTypeId; machineId: CaminoMachineId | null; description: string }, void> +>` +INSERT INTO titres_demarches (id, slug, titre_id, type_id, machine_id, description) + VALUES ($ id !, $slug!, $ titre_id !, $demarcheTypeId!, $machineId!, $description) ` diff --git a/packages/api/src/api/rest/titre-demande.queries.types.ts b/packages/api/src/api/rest/titre-demande.queries.types.ts index 04d202f4c47c2a5913b2a2dd2ba6aab0388089c3..fb3fbfcfbba92262464fdae4fc720ee409b2c38a 100644 --- a/packages/api/src/api/rest/titre-demande.queries.types.ts +++ b/packages/api/src/api/rest/titre-demande.queries.types.ts @@ -21,8 +21,10 @@ export interface ICreateTitreInternalQuery { /** 'CreateTitreDemarcheInternal' parameters type */ export interface ICreateTitreDemarcheInternalParams { - demarcheTypeId?: string | null | void; + demarcheTypeId: string; + description?: string | null | void; id: string; + machineId: string; slug: string; titre_id: string; } diff --git a/packages/api/src/api/rest/titre-demande.ts b/packages/api/src/api/rest/titre-demande.ts index 6cfa6427f7db62dd8db1a142486cc523f494761b..77dcd9a7926932445fa782df9aabe80e8495d976 100644 --- a/packages/api/src/api/rest/titre-demande.ts +++ b/packages/api/src/api/rest/titre-demande.ts @@ -22,6 +22,7 @@ import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' import { updateUtilisateurTitre } from './titres.queries' +import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' type TitreDemandeCreerErrors = | 'Accès interdit' @@ -90,7 +91,7 @@ export const titreDemandeCreer: RestNewPostCall<'/rest/titres'> = (rootPipe): Ef catch: unknown => ({ message: 'Problème lors de la mise à jour des taches du titre' as const, extra: unknown }), }) ), - Effect.bind('demarcheId', ({ titreId, pool }) => createDemarche(pool, titreId, 'oct')), + Effect.bind('demarcheId', ({ titreId, pool, titreDemande }) => createDemarche(pool, titreId, titreDemande.titreTypeId, DEMARCHES_TYPES_IDS.Octroi)), Effect.tap(({ titreId, demarcheId, pool }) => { return Effect.tryPromise({ try: async () => { @@ -161,7 +162,6 @@ export const titreDemandeCreer: RestNewPostCall<'/rest/titres'> = (rootPipe): Ef 'Création du titre impossible', "Impossible d'exécuter la requête dans la base de données", 'Problème lors de la mise à jour des taches du titre', - 'Création de la démarche impossible', 'Problème lors de la mise à jour des taches de la démarche', "Problème lors de la création de l'étape", "Problème lors de la mise à jour des tâches de l'étape", diff --git a/packages/api/src/api/rest/titres.queries.ts b/packages/api/src/api/rest/titres.queries.ts index aece42351915cf79b9cab68add31d175b1b1e5ba..099b0a5c21cda1df2408b6c68cd8d372c281faf3 100644 --- a/packages/api/src/api/rest/titres.queries.ts +++ b/packages/api/src/api/rest/titres.queries.ts @@ -12,7 +12,7 @@ import { IGetTitresDbQuery, IGetTitulairesAmodiatairesByTitreIdDbQuery, } from './titres.queries.types' -import { caminoDateValidator, firstEtapeDateValidator } from 'camino-common/src/date' +import { caminoDateValidator } from 'camino-common/src/date' import { z } from 'zod' import { Commune, communeIdValidator } from 'camino-common/src/static/communes' import { Pool } from 'pg' @@ -20,16 +20,7 @@ import { titreTypeIdValidator } from 'camino-common/src/static/titresTypes' import { isAdministration, isSuper, User, UtilisateurId } from 'camino-common/src/roles' import { titreStatutIdValidator } from 'camino-common/src/static/titresStatuts' import { titreReferenceValidator } from 'camino-common/src/titres-references' -import { - demarcheEnregistrementDemandeDateFind, - DemarcheEtape, - DemarcheEtapeCommon, - DemarcheEtapeFondamentale, - DemarcheEtapeNonFondamentale, - DemarcheId, - demarcheIdValidator, - demarcheSlugValidator, -} from 'camino-common/src/demarche' +import { DemarcheEtape, DemarcheEtapeCommon, DemarcheEtapeFondamentale, DemarcheEtapeNonFondamentale, DemarcheId, demarcheIdValidator, demarcheSlugValidator } from 'camino-common/src/demarche' import { demarcheStatutIdValidator } from 'camino-common/src/static/demarchesStatuts' import { demarcheTypeIdValidator } from 'camino-common/src/static/demarchesTypes' import { getDemarcheByIdOrSlug, getEtapesByDemarcheId } from './demarches.queries' @@ -57,9 +48,17 @@ import { Effect } from 'effect' import { CaminoError } from 'camino-common/src/zod-tools' import { getAvisTypes } from 'camino-common/src/avisTypes' import { isArmMecanise } from 'camino-common/src/static/mecanise' +import { MachineInfo } from 'camino-common/src/machines' +import { machineIdValidator } from 'camino-common/src/validators/machine' type SuperEtapeDemarcheTitreGet = OmitDistributive<DemarcheEtape, 'etape_documents' | 'avis_documents'> -type SuperDemarcheTitreGet = Omit<TitreGet['demarches'][0], 'etapes'> & { etapes: SuperEtapeDemarcheTitreGet[]; public_lecture: boolean; entreprises_lecture: boolean; titre_public_lecture: boolean } +type SuperDemarcheTitreGet = Omit<TitreGet['demarches'][0], 'etapes'> & { + etapes: SuperEtapeDemarcheTitreGet[] + public_lecture: boolean + entreprises_lecture: boolean + titre_public_lecture: boolean + machine_info: MachineInfo +} export const getTitre = async (pool: Pool, user: User, idOrSlug: TitreIdOrSlug): Promise<TitreGet | null> => { const titres = await dbQueryAndValidate(getTitreInternal, { id: idOrSlug }, pool, getTitreInternalValidator) @@ -67,7 +66,6 @@ export const getTitre = async (pool: Pool, user: User, idOrSlug: TitreIdOrSlug): return null } else { const titre = titres[0] - const titreDateLastModified = canSeeTitreLastModifiedDate(user) ? await callAndExit(getDateLastJournal(pool, titre.id)) : null const titreDoublon = titre.titre_doublon_id !== null && titre.titre_doublon_nom !== null ? { id: titre.titre_doublon_id, nom: titre.titre_doublon_nom } : null @@ -77,11 +75,17 @@ export const getTitre = async (pool: Pool, user: User, idOrSlug: TitreIdOrSlug): const superDemarches: SuperDemarcheTitreGet[] = [] for (const demarche of demarchesFromDatabase) { + const machineInfoResult = MachineInfo.withMachineId(titre.titre_type_id, demarche.demarche_type_id, demarche.id, demarche.machine_id) + if (!machineInfoResult.valid) { + throw new Error(machineInfoResult.error) + } + const machineInfo = machineInfoResult.value + const etapes = await callAndExit(getEtapesByDemarcheId(pool, demarche.id)) const formatedEtapes: SuperEtapeDemarcheTitreGet[] = [] for (const etape of etapes) { - const sections = getSections(titre.titre_type_id, demarche.demarche_type_id, etape.etape_type_id) + const sections = getSections(machineInfo, etape.etape_type_id) .map(section => ({ ...section, elements: section.elements.filter(element => !(etape.heritage_contenu?.[section.id]?.[element.id]?.actif ?? false)) })) .filter(section => section.elements.length > 0) @@ -89,7 +93,7 @@ export const getTitre = async (pool: Pool, user: User, idOrSlug: TitreIdOrSlug): const entrepriseDocuments = [] - const entrepriseDocumentsTypes = getEntrepriseDocuments(titre.titre_type_id, demarche.demarche_type_id, etape.etape_type_id) + const entrepriseDocumentsTypes = getEntrepriseDocuments(machineInfo, etape.etape_type_id) if (entrepriseDocumentsTypes.length > 0) { entrepriseDocuments.push(...(await callAndExit(getEntrepriseDocumentIdsByEtapeId({ titre_etape_id: etape.id }, pool, user)))) } @@ -205,6 +209,8 @@ export const getTitre = async (pool: Pool, user: User, idOrSlug: TitreIdOrSlug): id: demarche.id, slug: demarche.slug, description: demarche.description, + machine_id: demarche.machine_id, + machine_info: machineInfo, demarche_type_id: demarche.demarche_type_id, demarche_statut_id: demarche.demarche_statut_id, demarche_visibilite: demarche.public_lecture ? 'Publique' : 'Confidentielle', @@ -249,18 +255,7 @@ export const getTitre = async (pool: Pool, user: User, idOrSlug: TitreIdOrSlug): if (canRead) { const etape_documents: EtapeDocument[] = [] const isEtapeArmMecanise = isArmMecanise(superEtape.sections_with_values) - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(superDemarche.etapes.map(({ etape_type_id, date }) => ({ date, typeId: etape_type_id }))) - - const firstEtapeDateOk = isNotNullNorUndefined(firstEtapeDate) ? firstEtapeDate : firstEtapeDateValidator.parse(superEtape.date) - const documentsTypes = getDocuments( - titre.titre_type_id, - superDemarche.demarche_type_id, - superEtape.etape_type_id, - firstEtapeDateOk, - superDemarche.id, - perimetre?.sdom_zones ?? [], - isEtapeArmMecanise - ) + const documentsTypes = getDocuments(superDemarche.machine_info, superEtape.etape_type_id, perimetre?.sdom_zones ?? [], isEtapeArmMecanise) if (isNotNullNorUndefinedNorEmpty(documentsTypes)) { etape_documents.push( ...(await callAndExit( @@ -271,15 +266,7 @@ export const getTitre = async (pool: Pool, user: User, idOrSlug: TitreIdOrSlug): const avis_documents: EtapeAvis[] = [] - const avisTypes = getAvisTypes( - superEtape.etape_type_id, - titre.titre_type_id, - superDemarche.demarche_type_id, - superDemarche.id, - firstEtapeDateOk, - perimetre?.communes.map(({ id }) => id) ?? [], - isEtapeArmMecanise - ) + const avisTypes = getAvisTypes(superEtape.etape_type_id, superDemarche.machine_info, perimetre?.communes.map(({ id }) => id) ?? [], isEtapeArmMecanise) if (isNotNullNorUndefinedNorEmpty(Object.keys(avisTypes))) { const avisWithLargeObjectId = await callAndExit( getEtapeAvisLargeObjectIdsByEtapeId(superEtape.id, pool, user, titreTypeId, administrationsLocales, entreprisesTitulairesOuAmodiataires, superEtape.etape_type_id, superDemarche) @@ -295,6 +282,7 @@ export const getTitre = async (pool: Pool, user: User, idOrSlug: TitreIdOrSlug): formattedDemarches.push({ id: superDemarche.id, slug: superDemarche.slug, + machine_id: superDemarche.machine_id, description: superDemarche.description, demarche_type_id: superDemarche.demarche_type_id, demarche_statut_id: superDemarche.demarche_statut_id, @@ -391,6 +379,7 @@ const getDemarchesByTitreIdQueryDbValidator = z.object({ entreprises_lecture: z.boolean().default(false), demarche_date_debut: caminoDateValidator.nullable(), demarche_date_fin: caminoDateValidator.nullable(), + machine_id: machineIdValidator.nullable(), ordre: z.number(), }) type GetDemarchesByTitreIdQueryDb = z.infer<typeof getDemarchesByTitreIdQueryDbValidator> @@ -409,6 +398,7 @@ select d.entreprises_lecture, d.demarche_date_debut, d.demarche_date_fin, + d.machine_id, d.ordre from titres_demarches d diff --git a/packages/api/src/api/rest/titres.queries.types.ts b/packages/api/src/api/rest/titres.queries.types.ts index 6852ce711a76133cec23c6e870b5b84214112e6b..a28d40ace1cf8b4f691e7d0e43ca33f6695b4696 100644 --- a/packages/api/src/api/rest/titres.queries.types.ts +++ b/packages/api/src/api/rest/titres.queries.types.ts @@ -40,6 +40,7 @@ export interface IGetDemarchesByTitreIdQueryDbResult { description: string | null; entreprises_lecture: boolean; id: string; + machine_id: string | null; ordre: number; public_lecture: boolean; slug: string | null; diff --git a/packages/api/src/api/rest/titres.test.integration.ts b/packages/api/src/api/rest/titres.test.integration.ts index d1193926ad68fca93d6bfb65d163a37aada57b90..54d19b96e4b29705769aae93f757581308493300 100644 --- a/packages/api/src/api/rest/titres.test.integration.ts +++ b/packages/api/src/api/rest/titres.test.integration.ts @@ -1,6 +1,5 @@ import { dbManager } from '../../../tests/db-manager' import { titreUpdate } from '../../database/queries/titres' -import { titreDemarcheCreate } from '../../database/queries/titres-demarches' import { titreEtapeCreate } from '../../database/queries/titres-etapes' import { userSuper } from '../../database/user-super' import { restCall, restDeleteCall, restNewCall, restNewPostCall } from '../../../tests/_utils/index' @@ -8,7 +7,7 @@ import { ADMINISTRATION_IDS } from 'camino-common/src/static/administrations' import { ITitreDemarche, ITitreEtape } from '../../types' import { entreprisesUpsert } from '../../database/queries/entreprises' import { Knex } from 'knex' -import { caminoDateValidator, toCaminoDate } from 'camino-common/src/date' +import { caminoDateValidator, firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { afterAll, beforeAll, beforeEach, describe, test, expect, vi } from 'vitest' import { newEntrepriseId } from 'camino-common/src/entreprise' import type { Pool } from 'pg' @@ -27,6 +26,11 @@ import { testBlankUser } from 'camino-common/src/tests-utils' import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' +import { MachineInfo } from 'camino-common/src/machines' +import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' +import { demarcheEnregistrementDemandeDateFind } from '../../business/rules-demarches/machines' +import { createDemarche } from './titre-demande.queries' +import { callAndExit } from '../../tools/fp-tools' console.info = vi.fn() console.error = vi.fn() @@ -118,7 +122,7 @@ afterAll(async () => { await dbManager.closeKnex() }) -const titreEtapesCreate = async (demarche: ITitreDemarche, etapes: Omit<ITitreEtape, 'id' | 'titreDemarcheId' | 'concurrence' | 'hasTitreFrom'>[]) => { +const titreEtapesCreate = async (demarche: Pick<ITitreDemarche, 'id' | 'titreId'>, etapes: Omit<ITitreEtape, 'id' | 'titreDemarcheId' | 'concurrence' | 'hasTitreFrom'>[]) => { const etapesCrees = [] for (const etape of etapes) { etapesCrees.push( @@ -142,10 +146,12 @@ async function createTitreWithEtapes( entreprises: any ) { const titreId = newTitreId(`id-${nomTitre}`) + const titreTypeId = TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX + const demarcheTypeId = DEMARCHES_TYPES_IDS.Octroi await insertTitreGraph({ id: titreId, nom: nomTitre, - typeId: 'arm', + typeId: titreTypeId, titreStatutId: 'mod', propsTitreEtapesIds: {}, references: [ @@ -156,18 +162,18 @@ async function createTitreWithEtapes( ], }) - const titreDemarche = await titreDemarcheCreate({ - titreId, - typeId: 'oct', - }) + const titreDemarcheId = await callAndExit(createDemarche(dbPool, titreId, titreTypeId, demarcheTypeId)) const [firstEtape, ...remainingEtapes] = etapes - const etapesCrees = await titreEtapesCreate(titreDemarche, [ + const etapesCrees = await titreEtapesCreate({ id: titreDemarcheId, titreId }, [ { demarcheIdsConsentement: [], ...firstEtape, titulaireIds: [entreprises[0].id] }, ...remainingEtapes.map(e => ({ demarcheIdsConsentement: [], ...e })), ]) + const firstEtapeDate = demarcheEnregistrementDemandeDateFind(etapes) + await knex('titres_demarches').update({ machineId: MachineInfo.withDate(titreTypeId, demarcheTypeId, titreDemarcheId, firstEtapeDate ?? firstEtapeDateValidator.parse(firstEtape.date)).machineId }) + await knex('titres') .update({ propsTitreEtapesIds: { titulaires: etapesCrees[0].id, points: etapesCrees[0].id } }) .where('id', titreId) @@ -590,6 +596,7 @@ describe('getTitre', () => { }, ], "id": "demarche-id", + "machine_id": null, "ordre": 0, "slug": "titre-id-oct99", }, @@ -690,6 +697,7 @@ describe('titresSuper', () => { demarches: [ { id: demarcheId, + machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi, titreId: id, etapes: [ @@ -716,6 +724,7 @@ describe('titresSuper', () => { demarches: [ { id: demarcheIdSansBrouillon, + machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi, titreId: idSansBrouillon, etapes: [ @@ -741,6 +750,7 @@ describe('titresSuper', () => { "etape_date": "2025-01-10", "etape_slug": "demarcheIdAvecBrouillon-mfr99", "etape_type_id": "mfr", + "machine_id": null, "titre_nom": "mon titre avec brouillon", "titre_slug": "slug", "titre_statut_id": "val", diff --git a/packages/api/src/api/rest/titres.ts b/packages/api/src/api/rest/titres.ts index c44b988e06999763470ce3264f0959f1f12271ba..9915077812f0a73f6e00ea65876a1f5cda3179b1 100644 --- a/packages/api/src/api/rest/titres.ts +++ b/packages/api/src/api/rest/titres.ts @@ -27,11 +27,11 @@ import { RestNewGetCall, RestNewPostCall } from '../../server/rest' import { Effect, Match, pipe } from 'effect' import { CaminoError } from 'camino-common/src/zod-tools' import { EffectDbQueryAndValidateErrors } from '../../pg-database' -import { CaminoMachines, machineFind } from '../../business/rules-demarches/machines' -import { demarcheEnregistrementDemandeDateFind } from 'camino-common/src/demarche' import { DBTitre } from '../../database/models/titres' import { AdministrationId } from 'camino-common/src/static/administrations' import { filterOrFailFromValid } from '../../tools/fp-tools' +import { ApiMachineInfo } from '../../business/rules-demarches/machines' +import { MachineInfo } from 'camino-common/src/machines' const etapesAMasquer = [ETAPES_TYPES.classementSansSuite, ETAPES_TYPES.desistementDuDemandeur, ETAPES_TYPES.demandeDeComplements_RecevabiliteDeLaDemande_] @@ -148,21 +148,21 @@ export const titresAdministrations = if (demarcheLaPlusRecente.statutId !== DemarchesStatutsIds.EnConstruction) { const etapes = demarcheLaPlusRecente.etapes.map(etape => titreEtapeForMachineValidator.parse(etape)) const etapesDerniereDemarche = toMachineEtapes(etapes) - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(demarcheLaPlusRecente.etapes) - let machine: CaminoMachines | undefined - // TODO 2024-12-02 à virer quand on enlève deepreadonly et qu'on type mieux demarcheEnregistrementDemandeDateFind - if (isNotNullNorUndefined(firstEtapeDate)) { - machine = machineFind(titre.typeId, demarcheLaPlusRecente.typeId, demarcheLaPlusRecente.id, firstEtapeDate) + const machineInfo = MachineInfo.withMachineId(titre.typeId, demarcheLaPlusRecente.typeId, demarcheLaPlusRecente.id, demarcheLaPlusRecente.machineId) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente : ${machineInfo.error}`) } + + const machine = new ApiMachineInfo(machineInfo.value) derniereEtape = etapesDerniereDemarche[etapesDerniereDemarche.length - 1] - if (isNotNullNorUndefined(machine)) { + if (isNotNullNorUndefined(machine.machine)) { try { - const whoIsBlocking = machine.whoIsBlocking(etapesDerniereDemarche) + const whoIsBlocking = machine.machine.whoIsBlocking(etapesDerniereDemarche) if (!whoIsBlocking.valid) { throw new Error(whoIsBlocking.error) } enAttenteDeAdministration = whoIsBlocking.value.includes(user.administrationId) - const nextEtapes = machine.possibleNextEtapes(etapesDerniereDemarche, getCurrent()) + const nextEtapes = machine.machine.possibleNextEtapes(etapesDerniereDemarche, getCurrent()) if (!nextEtapes.valid) { throw new Error(nextEtapes.error) } diff --git a/packages/api/src/business/check-prolongations.ts b/packages/api/src/business/check-prolongations.ts index 370e61b2d8a72d99f1d5dbd31f2169a267999018..7e69109c5a2fb4527e404614d6e2e4d3b17cbaf9 100644 --- a/packages/api/src/business/check-prolongations.ts +++ b/packages/api/src/business/check-prolongations.ts @@ -24,6 +24,7 @@ import { isDemarcheTypeProlongations } from 'camino-common/src/static/demarchesT import { getMostRecentValuePropFromEtapeFondamentaleValide, TitreGetDemarche } from 'camino-common/src/titres' import { isDemarcheStatutNonStatue, isDemarcheStatutNonValide } from 'camino-common/src/static/demarchesStatuts' import { getTitre } from '../api/rest/titres.queries' +import { MachineInfo } from 'camino-common/src/machines' type CheckedProlongation = { titre_slug: TitreSlug | null @@ -102,7 +103,6 @@ const checkOneProlongation = (pool: Pool, demarcheId: DemarcheId): Effect.Effect } ) ), - Effect.bind('flattenFirstEtape', ({ firstEtape }) => iTitreEtapeToFlattenEtape(firstEtape)), Effect.bind('firstEtapeDate', ({ demarche }) => getFirstEtapeDateByDemarcheIdOrSlug(demarche.demarche_id, pool).pipe( Effect.filterOrFail( @@ -111,19 +111,18 @@ const checkOneProlongation = (pool: Pool, demarcheId: DemarcheId): Effect.Effect ) ) ), - Effect.map(({ demarche, firstEtape, flattenFirstEtape, etapeDocuments, entrepriseDocuments, etapeAvis, firstEtapeDate }) => { + Effect.let('machineInfo', ({ demarche, firstEtapeDate }) => MachineInfo.withDate(demarche.titre_type_id, demarche.demarche_type_id, demarcheId, firstEtapeDate)), + Effect.bind('flattenFirstEtape', ({ firstEtape, machineInfo }) => iTitreEtapeToFlattenEtape(machineInfo, firstEtape)), + Effect.map(({ demarche, firstEtape, flattenFirstEtape, etapeDocuments, entrepriseDocuments, etapeAvis, machineInfo }) => { const isFirstEtapeComplete = isEtapeComplete( flattenFirstEtape, - demarche.titre_type_id, - demarcheId, - demarche.demarche_type_id, + machineInfo, etapeDocuments, entrepriseDocuments, firstEtape.sdomZones, isNotNullNorUndefined(firstEtape.communes) ? firstEtape.communes.map(({ id }) => id) : [], etapeAvis, - userSuper, - firstEtapeDate + userSuper ) return { diff --git a/packages/api/src/business/daily.ts b/packages/api/src/business/daily.ts index d659a33cbf3b6d8a3ab31a865e79759ea20cc007..7ba3e8a6bdd74f7b3bf3fcbd6f62cc7c6aafa25a 100644 --- a/packages/api/src/business/daily.ts +++ b/packages/api/src/business/daily.ts @@ -31,6 +31,7 @@ import { createInterface } from 'node:readline' import { fetch } from 'undici' import { mailjetSend } from '../tools/api-mailjet/emails' import { EtapeId } from 'camino-common/src/etape' +import { demarcheMachineIdsUpdate } from './processes/demarche-machine-id-update' interface Daily { heritageWithUnknownEtapes: unknown[] @@ -47,6 +48,7 @@ interface Daily { updated: EtapeId[] errors: EtapeId[] } + demarcheMachineIdsUpdated: unknown[] titresDemarchesStatutUpdated: string[] titresDemarchesPublicUpdated: string[] titresDemarchesOrdreUpdated: string[] @@ -62,8 +64,8 @@ interface Daily { titresUpdatedIndex: TitreSlugUpdate[] } -// Mis à jour le 2025-03-12 -const NOMBRE_ERREURS_ETAPES = 9964 as const +// Mis à jour le 2025-04-07 +const NOMBRE_ERREURS_ETAPES = 9927 as const type DailyResult = { changes: false } | { changes: true; logs: NonEmptyArray<string> } const dailyResult = (daily: Daily | null): DailyResult => { @@ -129,6 +131,10 @@ const dailyResult = (daily: Daily | null): DailyResult => { logs.push(`erreurs: ${daily.titresEtapesHeritageContenuUpdated.errors.length} étape(s) (héritage du contenu) en erreur`) } + if (isNotNullNorUndefinedNorEmpty(daily.demarcheMachineIdsUpdated)) { + logs.push(`mise à jour: ${daily.demarcheMachineIdsUpdated.length} machines`) + } + if (isNotNullNorUndefinedNorEmpty(daily.titresDemarchesStatutUpdated)) { logs.push(`mise à jour: ${daily.titresDemarchesStatutUpdated.length} démarche(s) (statut)`) } @@ -239,6 +245,7 @@ const rawDaily = async (pool: Pool): Promise<DailyResult> => { const titresEtapesHeritageContenuUpdated = await titresEtapesHeritageContenuUpdate(pool, userSuper) const heritageWithUnknownEtapes = await callAndExit(checkEtapeInContenuHeritage(pool)) + const demarcheMachineIdsUpdated = await callAndExit(demarcheMachineIdsUpdate(pool)) const titresDemarchesStatutUpdated = await titresDemarchesStatutIdUpdate(pool) const titresDemarchesOrdreUpdated = await titresDemarchesOrdreUpdate() const titresDemarchesDatesUpdated = await titresDemarchesDatesUpdate(pool) @@ -260,6 +267,7 @@ const rawDaily = async (pool: Pool): Promise<DailyResult> => { const etapesCompletesErreurs = await etapesCompletesCheck(pool) return dailyResult({ + demarcheMachineIdsUpdated, heritageWithUnknownEtapes, etapesCompletesErreurs: etapesCompletesErreurs, tdeErreurs, diff --git a/packages/api/src/business/fill-documents-non-renseigne.ts b/packages/api/src/business/fill-documents-non-renseigne.ts index 7322127609b5e8b7acdd44b512bc6e08986ae384..2ecfa7f0d2dc695ea4c9d5077b780c81af16228c 100644 --- a/packages/api/src/business/fill-documents-non-renseigne.ts +++ b/packages/api/src/business/fill-documents-non-renseigne.ts @@ -1,7 +1,7 @@ import { Pool } from 'pg' import { Effect, pipe } from 'effect' import { CaminoError } from 'camino-common/src/zod-tools' -import { demarcheEnregistrementDemandeDateFind, DemarcheEtapeFondamentale, DemarcheId } from 'camino-common/src/demarche' +import { DemarcheEtapeFondamentale, DemarcheId } from 'camino-common/src/demarche' import { isEtapeComplete } from 'camino-common/src/permissions/titres-etapes' import { userSuper } from '../database/user-super' import { FirstEtapeDate } from 'camino-common/src/date' @@ -28,6 +28,8 @@ import { getMostRecentValuePropFromEtapeFondamentaleValide, TitreGetDemarche } f import { isDemarcheStatutNonStatue, isDemarcheStatutNonValide } from 'camino-common/src/static/demarchesStatuts' import { getAvisTypes } from 'camino-common/src/avisTypes' import { AvisRegularTypeId, isAvisRegularTypeId } from 'camino-common/src/static/avisTypes' +import { MachineInfo } from 'camino-common/src/machines' +import { demarcheEnregistrementDemandeDateFind } from './rules-demarches/machines' type CheckedProlongation = { titre_slug: TitreSlug @@ -158,7 +160,15 @@ const checkDemarcheEtapes = (pool: Pool, titreId: TitreId): Effect.Effect<Checke } ) ), - Effect.bind('flattenEtape', ({ etapeFull }) => iTitreEtapeToFlattenEtape(etapeFull)), + Effect.bind('machineInfo', () => { + const machineInfo = MachineInfo.withMachineId(titre.titre_type_id, demarche.demarche_type_id, demarche.id, demarche.machine_id) + if (!machineInfo.valid) { + return Effect.fail({ message: 'Machine associée à la démarche incohérente', extra: machineInfo.error }) + } + + return Effect.succeed(machineInfo.value) + }), + Effect.bind('flattenEtape', ({ etapeFull, machineInfo }) => iTitreEtapeToFlattenEtape(machineInfo, etapeFull)), Effect.map(({ etapeFull, flattenEtape, etapeDocuments, entrepriseDocuments, etapeAvis }) => { if (flattenEtape.isBrouillon === ETAPE_IS_BROUILLON) { @@ -166,16 +176,13 @@ const checkDemarcheEtapes = (pool: Pool, titreId: TitreId): Effect.Effect<Checke } const isFirstEtapeComplete = isEtapeComplete( flattenEtape, - titre.titre_type_id, - demarche.id, - demarche.demarche_type_id, + MachineInfo.withDate(titre.titre_type_id, demarche.demarche_type_id, demarche.id, firstEtapeDate), etapeDocuments, entrepriseDocuments, etapeFull.sdomZones, isNotNullNorUndefined(etapeFull.communes) ? etapeFull.communes.map(({ id }) => id) : [], etapeAvis, - userSuper, - firstEtapeDate + userSuper ) const result: CheckedProlongation = { titre_slug: titre.slug, @@ -237,11 +244,8 @@ const addDocumentNonRenseigne = (pool: Pool, checkedProlongation: CheckedProlong ), Effect.flatMap(({ titre, demarche }) => { const documentTypes = getDocuments( - titre.titre_type_id, - demarche.demarche_type_id, + MachineInfo.withDate(titre.titre_type_id, demarche.demarche_type_id, demarche.id, checkedProlongation.firstEtapeDate), checkedProlongation.etapeFull.typeId, - checkedProlongation.firstEtapeDate, - demarche.id, checkedProlongation.etapeFull.sdomZones ?? [], isArmMecanise(checkedProlongation.flattenEtape.contenu) ) @@ -298,10 +302,7 @@ const addAvisNonRenseigne = (pool: Pool, checkedProlongation: CheckedProlongatio Effect.flatMap(({ titre, demarche }) => { const avisTypes = getAvisTypes( checkedProlongation.etapeFull.typeId, - titre.titre_type_id, - demarche.demarche_type_id, - demarche.id, - checkedProlongation.firstEtapeDate, + MachineInfo.withDate(titre.titre_type_id, demarche.demarche_type_id, demarche.id, checkedProlongation.firstEtapeDate), (checkedProlongation.propsHeritees.perimetre?.communes ?? []).map(({ id }) => id), isArmMecanise(checkedProlongation.flattenEtape.contenu) ) diff --git a/packages/api/src/business/processes/demarche-machine-id-update.ts b/packages/api/src/business/processes/demarche-machine-id-update.ts new file mode 100644 index 0000000000000000000000000000000000000000..6f612b57486ca8571393894f2a92cf234e14452f --- /dev/null +++ b/packages/api/src/business/processes/demarche-machine-id-update.ts @@ -0,0 +1,51 @@ +import { CaminoMachineId } from 'camino-common/src/validators/machine' +import { CaminoError } from 'camino-common/src/zod-tools' +import { Effect } from 'effect' +import { Pool } from 'pg' +import { DemarcheId, DemarcheSlug } from 'camino-common/src/demarche' +import { getDemarcheByIdOrSlug, GetDemarcheByIdOrSlugErrors, getDemarches, getFirstEtapeDateByDemarcheIdOrSlug, GetFirstEtapeDateByDemarcheIdOrSlugErrors } from '../../api/rest/demarches.queries' +import { MachineInfo } from 'camino-common/src/machines' +import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools' +import { updateMachineId, UpdateMachineIdErrors } from './update-machine-id.queries' + +export const demarcheMachineIdsUpdate = (pool: Pool): Effect.Effect<Changes[], CaminoError<DemarcheMachineIdUpdateErrors>> => { + console.info('') + console.info('machine des démarches…') + return Effect.Do.pipe( + Effect.flatMap(() => getDemarches(pool)), + Effect.flatMap(demarches => Effect.forEach(demarches, demarche => demarcheMachineIdUpdate(pool, demarche.id))), + Effect.map(changesAndNoChanges => changesAndNoChanges.filter(value => value.changes)) + ) +} + +type Changes = { changes: true; demarcheSlug: DemarcheSlug; old: CaminoMachineId | null; new: CaminoMachineId | null } +type NoChange = { changes: false } +type ReturnValue = Changes | NoChange +type DemarcheMachineIdUpdateErrors = GetFirstEtapeDateByDemarcheIdOrSlugErrors | GetDemarcheByIdOrSlugErrors | UpdateMachineIdErrors +export const demarcheMachineIdUpdate = (pool: Pool, demarcheId: DemarcheId): Effect.Effect<ReturnValue, CaminoError<DemarcheMachineIdUpdateErrors>> => { + return Effect.Do.pipe( + Effect.bind('demarche', () => getDemarcheByIdOrSlug(pool, demarcheId)), + Effect.bind('firstEtapeDate', () => getFirstEtapeDateByDemarcheIdOrSlug(demarcheId, pool)), + Effect.let('newMachineId', ({ demarche, firstEtapeDate }) => + isNotNullNorUndefined(firstEtapeDate) ? (MachineInfo.withDate(demarche.titre_type_id, demarche.demarche_type_id, demarche.demarche_id, firstEtapeDate).machineId ?? null) : null + ), + Effect.flatMap(({ demarche, newMachineId }) => { + if (demarche.machine_id === newMachineId) { + return Effect.succeed<ReturnValue>({ changes: false }) + } + + return Effect.Do.pipe( + Effect.flatMap(() => updateMachineId(pool, demarcheId, newMachineId)), + Effect.map(() => { + console.info(`Changement de machine pour la démarche https://camino.beta.gouv.fr/demarches/${demarche.demarche_slug} old: ${demarche.machine_id} -> ${newMachineId}`) + return { + changes: true, + demarcheSlug: demarche.demarche_slug, + old: demarche.machine_id, + new: newMachineId, + } + }) + ) + }) + ) +} diff --git a/packages/api/src/business/processes/titres-demarches-public-update.ts b/packages/api/src/business/processes/titres-demarches-public-update.ts index a4fbcdd5e103c7a1af872cd579385fc8d4705deb..fe50f37b9c5fdc9088efeba76e912dcdcdc92441 100644 --- a/packages/api/src/business/processes/titres-demarches-public-update.ts +++ b/packages/api/src/business/processes/titres-demarches-public-update.ts @@ -3,6 +3,7 @@ import { titreDemarchePublicFind } from '../rules/titre-demarche-public-find' import { titresGet } from '../../database/queries/titres' import { userSuper } from '../../database/user-super' import { DemarcheId } from 'camino-common/src/demarche' +import { MachineInfo } from 'camino-common/src/machines' type ITitreDemarchePatch = { publicLecture: boolean @@ -33,7 +34,12 @@ export const titresDemarchesPublicUpdate = async (titresIds?: string[]): Promise for (const titre of titres) { for (const titreDemarche of titre.demarches!) { - const { publicLecture, entreprisesLecture } = titreDemarchePublicFind(titreDemarche, titre.typeId) + const machineInfo = MachineInfo.withMachineId(titre.typeId, titreDemarche.typeId, titreDemarche.id, titreDemarche.machineId) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente: ${machineInfo.error}`) + } + + const { publicLecture, entreprisesLecture } = titreDemarchePublicFind(machineInfo.value, titreDemarche) const patch = {} as ITitreDemarchePatch diff --git a/packages/api/src/business/processes/titres-demarches-statut-ids-update.test.ts b/packages/api/src/business/processes/titres-demarches-statut-ids-update.test.ts index b36f7ce186e3e4529819b92cd3412a48fa72e19c..dd571b91f8afc3358a2d628c605ee279670b4774 100644 --- a/packages/api/src/business/processes/titres-demarches-statut-ids-update.test.ts +++ b/packages/api/src/business/processes/titres-demarches-statut-ids-update.test.ts @@ -25,6 +25,7 @@ describe("statut des démarches d'un titre", () => { getDemarchesMock.mockReturnValue( Effect.succeed({ [newDemarcheId('')]: { + machineId: null, id: newDemarcheId('h-cx-courdemanges-1988-oct01'), slug: demarcheSlugValidator.parse('h-cx-courdemanges-1988-oct01'), titreId: newTitreId('h-cx-courdemanges-1988'), @@ -82,6 +83,7 @@ describe("statut des démarches d'un titre", () => { getDemarchesMock.mockReturnValue( Effect.succeed({ [newDemarcheId('')]: { + machineId: null, id: newDemarcheId('h-cx-courdemanges-1988-oct01'), slug: demarcheSlugValidator.parse('h-cx-courdemanges-1988-oct01'), titreId: newTitreId('h-cx-courdemanges-1988'), @@ -138,6 +140,7 @@ describe("statut des démarches d'un titre", () => { getDemarchesMock.mockReturnValue( Effect.succeed({ [newDemarcheId('')]: { + machineId: null, id: newDemarcheId('h-cx-courdemanges-1988-oct01'), slug: demarcheSlugValidator.parse('h-cx-courdemanges-1988-oct01'), titreId: newTitreId('h-cx-courdemanges-1988'), diff --git a/packages/api/src/business/processes/titres-demarches-statut-ids-update.ts b/packages/api/src/business/processes/titres-demarches-statut-ids-update.ts index 572123625855d30420675231e6c019cdee2143ac..4d9e7e04fef697c3aa50a36fb390e0d2ea3c531f 100644 --- a/packages/api/src/business/processes/titres-demarches-statut-ids-update.ts +++ b/packages/api/src/business/processes/titres-demarches-statut-ids-update.ts @@ -5,6 +5,7 @@ import { titreEtapesSortAscByOrdre } from '../utils/titre-etapes-sort' import { getDemarches } from './titres-etapes-heritage-contenu-update.queries' import { Pool } from 'pg' import { callAndExit } from '../../tools/fp-tools' +import { MachineInfo } from 'camino-common/src/machines' export const titresDemarchesStatutIdUpdate = async (pool: Pool, titreId?: TitreId): Promise<string[]> => { console.info() @@ -17,7 +18,12 @@ export const titresDemarchesStatutIdUpdate = async (pool: Pool, titreId?: TitreI for (const titreDemarche of Object.values(titresDemarches)) { const titreDemarcheEtapes = titreEtapesSortAscByOrdre(titreDemarche.etapes) - const statutId = titreDemarcheStatutIdFind(titreDemarche.typeId, titreDemarcheEtapes, titreDemarche.titreTypeId, titreDemarche.id) + const machineInfo = MachineInfo.withMachineId(titreDemarche.titreTypeId, titreDemarche.typeId, titreDemarche.id, titreDemarche.machineId) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente: ${machineInfo.error}`) + } + + const statutId = titreDemarcheStatutIdFind(machineInfo.value, titreDemarcheEtapes) if (titreDemarche.statutId !== statutId) { await titreDemarcheUpdate(titreDemarche.id, { statutId }) diff --git a/packages/api/src/business/processes/titres-etapes-consentement.test.integration.ts b/packages/api/src/business/processes/titres-etapes-consentement.test.integration.ts index 85475834d8ef4ae182bbeabb6e0c8f025fc49eb2..4e004485a5e8786bb453b0929e00ee4b996199fa 100644 --- a/packages/api/src/business/processes/titres-etapes-consentement.test.integration.ts +++ b/packages/api/src/business/processes/titres-etapes-consentement.test.integration.ts @@ -54,7 +54,7 @@ describe('etapeConsentementUpdate', () => { } test("ne fait rien si le périmètre de l'étape est null", async () => { - const { etapeId } = await createTitreWithDemarcheAndEtape(titre, { typeId: DEMARCHES_TYPES_IDS.Octroi }, etape) + const { etapeId } = await createTitreWithDemarcheAndEtape(titre, { machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi }, etape) await expect(callAndExit(etapeConsentementUpdate(dbPool, etapeId))).resolves.toBe(null) }) @@ -86,7 +86,7 @@ describe('etapeConsentementUpdate', () => { const perimetre = featureMultipolygon(index++) const { demarcheId: demarcheIdConsentement } = await createTitreWithDemarcheAndEtape( titre, - { typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: demarcheConsentementDateDebut }, + { machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: demarcheConsentementDateDebut }, { ...etape, geojson4326Perimetre: perimetre, @@ -98,7 +98,7 @@ describe('etapeConsentementUpdate', () => { const { etapeId } = await createTitreWithDemarcheAndEtape( titre, - { typeId: DEMARCHES_TYPES_IDS.Octroi }, + { machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi }, { ...etape, date: dateDemande, @@ -124,7 +124,7 @@ describe('etapeConsentementUpdate', () => { const perimetre = featureMultipolygon(index++) await createTitreWithDemarcheAndEtape( titre, - { typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: demarcheConsentementDateDebut }, + { machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: demarcheConsentementDateDebut }, { ...etape, geojson4326Perimetre: perimetre, @@ -135,7 +135,7 @@ describe('etapeConsentementUpdate', () => { const { etapeId } = await createTitreWithDemarcheAndEtape( titre, - { typeId: DEMARCHES_TYPES_IDS.Octroi }, + { machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi }, { ...etape, date: dateDemande, @@ -152,7 +152,7 @@ describe('etapeConsentementUpdate', () => { const perimetre1 = featureMultipolygon(index++) await createTitreWithDemarcheAndEtape( titre, - { typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: demarcheConsentementDateDebut }, + { machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: demarcheConsentementDateDebut }, { ...etape, geojson4326Perimetre: perimetre1, @@ -165,7 +165,7 @@ describe('etapeConsentementUpdate', () => { const perimetre2 = featureMultipolygon(index++) const { etapeId } = await createTitreWithDemarcheAndEtape( titre, - { typeId: DEMARCHES_TYPES_IDS.Octroi }, + { machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi }, { ...etape, date: dateDemande, @@ -185,7 +185,7 @@ describe('etapeConsentementUpdate', () => { //Se termine avant la demande await createTitreWithDemarcheAndEtape( titre, - { typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: demarcheConsentementDateDebut, demarcheDateFin: dateAddDays(demarcheConsentementDateDebut, 1) }, + { machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: demarcheConsentementDateDebut, demarcheDateFin: dateAddDays(demarcheConsentementDateDebut, 1) }, { ...etape, geojson4326Perimetre: perimetre1, @@ -198,7 +198,7 @@ describe('etapeConsentementUpdate', () => { //Commence après la demande await createTitreWithDemarcheAndEtape( titre, - { typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: dateAddDays(dateDemande, 10) }, + { machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: dateAddDays(dateDemande, 10) }, { ...etape, geojson4326Perimetre: perimetre1, @@ -211,7 +211,7 @@ describe('etapeConsentementUpdate', () => { const perimetre2 = featureMultipolygon(index++) const { etapeId } = await createTitreWithDemarcheAndEtape( titre, - { typeId: DEMARCHES_TYPES_IDS.Octroi }, + { machineId: null, typeId: DEMARCHES_TYPES_IDS.Octroi }, { ...etape, date: dateDemande, diff --git a/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.queries.ts b/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.queries.ts index 1a9e02c29b6a9f47ee59d3a06063203f6be6d2b0..12f49df34e79f82768a18f43ae7dbcc0e0eda0c4 100644 --- a/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.queries.ts +++ b/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.queries.ts @@ -18,6 +18,7 @@ import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools' import { km2Validator } from 'camino-common/src/number' import { CaminoError } from 'camino-common/src/zod-tools' import { Effect } from 'effect' +import { CaminoMachineId, machineIdValidator } from 'camino-common/src/validators/machine' const getAllEtapeIdValidator = z.object({ id: etapeIdValidator, heritage_contenu: z.record(z.record(z.object({ etapeId: etapeIdValidator.optional().nullable() }))).nullable() }) @@ -56,6 +57,7 @@ const getEtapesByDemarcheValidator = z.object({ is_brouillon: etapeBrouillonValidator.nullable(), has_titre_from: z.boolean(), demarche_ids_consentement: z.array(demarcheIdValidator).nullable(), + machine_id: machineIdValidator.nullable(), }) export const getDemarches = ( @@ -72,6 +74,7 @@ export const getDemarches = ( titreTypeId: TitreTypeId titreId: TitreId statutId: DemarcheStatutId + machineId: CaminoMachineId | null } }, CaminoError<EffectDbQueryAndValidateErrors> @@ -88,6 +91,7 @@ export const getDemarches = ( titreTypeId: TitreTypeId titreId: TitreId statutId: DemarcheStatutId + machineId: CaminoMachineId | null } }>((acc, row) => { if (!isNotNullNorUndefined(acc[row.demarche_id])) { @@ -99,6 +103,7 @@ export const getDemarches = ( titreTypeId: row.titre_type_id, typeId: row.demarche_type_id, statutId: row.demarche_statut_id, + machineId: row.machine_id, } } if ( @@ -161,6 +166,7 @@ SELECT demarche.slug as demarche_slug, demarche.type_id as demarche_type_id, demarche.statut_id as demarche_statut_id, + demarche.machine_id, etape.communes AS communes, demarche_concurrente.public_lecture as demarche_concurrente_public_lecture, EXISTS(select 1 from titres__titres tt where titre.id = tt.titre_to_id) as has_titre_from diff --git a/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.queries.types.ts b/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.queries.types.ts index dc9a602266c7a23c3cb32cdab1fc88a166a6fc2d..d800c3f30086a9025e5f6425cd585366608f3484 100644 --- a/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.queries.types.ts +++ b/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.queries.types.ts @@ -41,6 +41,7 @@ export interface IGetEtapesByDemarcheInternalResult { heritage_contenu: Json | null; id: string; is_brouillon: boolean; + machine_id: string | null; ordre: number; statut_id: string; surface: number | null; diff --git a/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.ts b/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.ts index 71a1d203327c27d452c899216e444bfd04a7442a..f042868026d9f07bfa262711a18f8f9234eddd63 100644 --- a/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.ts +++ b/packages/api/src/business/processes/titres-etapes-heritage-contenu-update.ts @@ -12,6 +12,7 @@ import { callAndExit } from '../../tools/fp-tools' import { Effect } from 'effect' import { CaminoError } from 'camino-common/src/zod-tools' import { EffectDbQueryAndValidateErrors } from '../../pg-database' +import { MachineInfo } from 'camino-common/src/machines' function isEmpty(obj: any) { for (const prop in obj) { if (Object.prototype.hasOwnProperty.call(obj, prop)) { @@ -69,11 +70,16 @@ export const titresEtapesHeritageContenuUpdate = async (pool: Pool, user: UserNo const titresEtapesIdsErrors: EtapeId[] = [] for (const titreDemarche of Object.values(titresDemarches)) { + const machineInfo = MachineInfo.withMachineId(titreDemarche.titreTypeId, titreDemarche.typeId, titreDemarche.id, titreDemarche.machineId) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente: ${machineInfo.error}`) + } + if (isNotNullNorUndefinedNorEmpty(titreDemarche.etapes)) { const etapeSectionsDictionary = titreDemarche.etapes.reduce<{ [etapeId in EtapeId]?: Section[] }>((acc, e) => { - acc[e.id] = getSections(titreDemarche.titreTypeId, titreDemarche.typeId, e.typeId) + acc[e.id] = getSections(machineInfo.value, e.typeId) return acc }, {}) diff --git a/packages/api/src/business/processes/titres-etapes-mise-en-concurrence.test.integration.ts b/packages/api/src/business/processes/titres-etapes-mise-en-concurrence.test.integration.ts index 326e2bc89c58dba3022e6b3a532fff26579e67cf..ac2cdae0b1e1a71f42026f212ccacd42a9b50670 100644 --- a/packages/api/src/business/processes/titres-etapes-mise-en-concurrence.test.integration.ts +++ b/packages/api/src/business/processes/titres-etapes-mise-en-concurrence.test.integration.ts @@ -80,6 +80,7 @@ const createTitreWithDemarcheAndEtape = async (titreTypeId: TitreTypeId, demarch typeId: titreTypeId, demarches: [ { + machineId: null, id: demarcheId, titreId, typeId: demarcheTypeId, @@ -152,6 +153,7 @@ describe('etapeMiseEnConcurrenceUpdate', () => { typeId: TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, demarches: [ { + machineId: null, id: demarcheId, titreId, typeId: DEMARCHES_TYPES_IDS.Octroi, @@ -187,6 +189,7 @@ describe('etapeMiseEnConcurrenceUpdate', () => { typeId: TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, demarches: [ { + machineId: null, id: demarcheId2, titreId: titreId2, typeId: DEMARCHES_TYPES_IDS.Octroi, @@ -232,6 +235,7 @@ describe('etapeMiseEnConcurrenceUpdate', () => { typeId: TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, demarches: [ { + machineId: null, id: demarcheId, titreId, typeId: DEMARCHES_TYPES_IDS.Octroi, @@ -259,6 +263,7 @@ describe('etapeMiseEnConcurrenceUpdate', () => { typeId: TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, demarches: [ { + machineId: null, id: demarcheId2, titreId: titreId2, typeId: DEMARCHES_TYPES_IDS.Octroi, diff --git a/packages/api/src/business/processes/titres-etapes-ordre-update.test.ts b/packages/api/src/business/processes/titres-etapes-ordre-update.test.ts index da4a78e5b78f2895c60042f0c8946cd797d419de..02e24dc1aead330ada8b63deb751cbd7d5d27907 100644 --- a/packages/api/src/business/processes/titres-etapes-ordre-update.test.ts +++ b/packages/api/src/business/processes/titres-etapes-ordre-update.test.ts @@ -6,12 +6,14 @@ import { vi, afterEach, describe, expect, test } from 'vitest' import { newDemarcheId, newEtapeId } from '../../database/models/_format/id-create' import { caminoDateValidator } from 'camino-common/src/date' import { DemarcheId } from 'camino-common/src/demarche' -import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' +import { DEMARCHES_TYPES_IDS, DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' +import { TITRES_TYPES_IDS, TitreTypeId } from 'camino-common/src/static/titresTypes' import { TitreId, titreIdValidator } from 'camino-common/src/validators/titres' import { TitreEtapeForMachine } from '../rules-demarches/machine-common' import { ETAPE_IS_NOT_BROUILLON } from 'camino-common/src/etape' import { ZERO_KM2 } from 'camino-common/src/number' +import { CaminoMachineId } from 'camino-common/src/validators/machine' +import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' vi.mock('../../database/queries/titres-etapes', () => ({ titreEtapeUpdate: vi.fn().mockResolvedValue(true), })) @@ -24,12 +26,14 @@ const titresDemarchesEtapes: { typeId: DemarcheTypeId titreTypeId: TitreTypeId titreId: TitreId + machineId: CaminoMachineId | null } } = { [demarcheId]: { id: demarcheId, - typeId: 'amo', - titreTypeId: 'apc', + machineId: 'ProcedureSimplifiee', + typeId: DEMARCHES_TYPES_IDS.Amodiation, + titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_CARRIERES, titreId: titreIdValidator.parse('titreId'), etapes: [ { @@ -39,7 +43,7 @@ const titresDemarchesEtapes: { dateFin: null, dateDebut: null, duree: null, - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', statutId: 'fai', @@ -55,7 +59,7 @@ const titresDemarchesEtapes: { dateFin: null, dateDebut: null, duree: null, - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -75,9 +79,17 @@ const titresDemarchesEtapesVides: { typeId: DemarcheTypeId titreTypeId: TitreTypeId titreId: TitreId + machineId: CaminoMachineId | null } } = { - [demarcheId]: { id: demarcheId, typeId: 'amo', titreTypeId: 'apc', titreId: titreIdValidator.parse('titreId'), etapes: [] }, + [demarcheId]: { + id: demarcheId, + machineId: null, + typeId: DEMARCHES_TYPES_IDS.Amodiation, + titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_CARRIERES, + titreId: titreIdValidator.parse('titreId'), + etapes: [], + }, } console.info = vi.fn() diff --git a/packages/api/src/business/processes/titres-etapes-ordre-update.ts b/packages/api/src/business/processes/titres-etapes-ordre-update.ts index cda09695fd1f2316a152ceeafc5612cb51e1542c..1bd31995f67ab35bbeb3f712ca4570c620636844 100644 --- a/packages/api/src/business/processes/titres-etapes-ordre-update.ts +++ b/packages/api/src/business/processes/titres-etapes-ordre-update.ts @@ -10,6 +10,8 @@ import { TitreId } from 'camino-common/src/validators/titres' import { TitreEtapeForMachine, titreEtapeForMachineValidator } from '../rules-demarches/machine-common' import { isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools' import { callAndExit } from '../../tools/fp-tools' +import { MachineInfo } from 'camino-common/src/machines' +import { CaminoMachineId } from 'camino-common/src/validators/machine' export const titresEtapesOrdreUpdate = async (pool: Pool, user: UserNotNull, demarcheId?: DemarcheId): Promise<string[]> => { console.info() @@ -29,6 +31,7 @@ export const titresEtapesOrdreUpdateVisibleForTesting = async ( typeId: DemarcheTypeId titreTypeId: TitreTypeId titreId: TitreId + machineId: CaminoMachineId | null } } ): Promise<string[]> => { @@ -38,7 +41,12 @@ export const titresEtapesOrdreUpdateVisibleForTesting = async ( if (isNotNullNorUndefinedNorEmpty(titreDemarche.etapes)) { const etapesMachine = titreDemarche.etapes.map(etape => titreEtapeForMachineValidator.parse(etape)) - const etapes = titreEtapesSortAscByDate(etapesMachine, titreDemarche.id, titreDemarche.typeId, titreDemarche.titreTypeId) + const machineInfo = MachineInfo.withMachineId(titreDemarche.titreTypeId, titreDemarche.typeId, titreDemarche.id, titreDemarche.machineId) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente: ${machineInfo.error}`) + } + + const etapes = titreEtapesSortAscByDate(etapesMachine, machineInfo.value) for (let index = 0; index < etapes.length; index++) { const titreEtape = etapes[index] if (titreEtape.ordre !== index + 1) { diff --git a/packages/api/src/business/processes/titres-etapes-statut-update.ts b/packages/api/src/business/processes/titres-etapes-statut-update.ts index 27fa3b83525a3b46da484dfcf819075242636727..861f170fa638ce0376e761623cd1b5a835b2bf88 100644 --- a/packages/api/src/business/processes/titres-etapes-statut-update.ts +++ b/packages/api/src/business/processes/titres-etapes-statut-update.ts @@ -4,6 +4,7 @@ import { getCurrent } from 'camino-common/src/date' import { EtapeStatutId } from 'camino-common/src/static/etapesStatuts' import { getEtapesWithAutomaticStatut, updateEtapeStatut } from '../../database/queries/titres-etapes.queries' import { simpleContenuToFlattenedContenu } from 'camino-common/src/sections' +import { MachineInfo } from 'camino-common/src/machines' export const titresEtapesStatutUpdate = async (pool: Pool): Promise<EtapeId[]> => { console.info() @@ -15,12 +16,17 @@ export const titresEtapesStatutUpdate = async (pool: Pool): Promise<EtapeId[]> = const etapesWithAutomaticStatut = await getEtapesWithAutomaticStatut(pool) for (const etape of etapesWithAutomaticStatut) { + const machineInfo = MachineInfo.withMachineId(etape.titre_type_id, etape.demarche_type_id, etape.demarche_id, etape.demarche_machine_id) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente: ${machineInfo.error}`) + } + const newStatut: EtapeStatutId = getStatutId( { ...etape, statutId: etape.etape_statut_id, typeId: etape.type_id, - contenu: simpleContenuToFlattenedContenu(etape.titre_type_id, etape.demarche_type_id, etape.type_id, etape.contenu, etape.heritage_contenu), + contenu: simpleContenuToFlattenedContenu(machineInfo.value, etape.type_id, etape.contenu, etape.heritage_contenu), }, currentDate ) diff --git a/packages/api/src/business/processes/titres-phases-update.test.ts b/packages/api/src/business/processes/titres-phases-update.test.ts index bbc7bec54faf8b3117c08f026cfc38e1ee270176..9c66d610f67e857493f0db049794a38273639696 100644 --- a/packages/api/src/business/processes/titres-phases-update.test.ts +++ b/packages/api/src/business/processes/titres-phases-update.test.ts @@ -41,6 +41,7 @@ describe("phases d'un titre", () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: null, id: newDemarcheId('h-cx-courdemanges-1988-oct01'), titreId: newTitreId('h-cx-courdemanges-1988'), typeId: 'oct', @@ -95,6 +96,7 @@ describe("phases d'un titre", () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: null, id: newDemarcheId('h-cx-courdemanges-1988-oct01'), titreId: newTitreId('h-cx-courdemanges-1988'), typeId: 'oct', @@ -150,6 +152,7 @@ describe("phases d'un titre", () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: null, id: newDemarcheId('h-cx-courdemanges-1988-oct01'), titreId: newTitreId('h-cx-courdemanges-1988'), typeId: 'oct', @@ -179,6 +182,7 @@ describe("phases d'un titre", () => { titreStatutId: 'ind', demarches: [ { + machineId: null, id: newDemarcheId('h-cx-courdemanges-1988-oct01'), titreId: newTitreId('h-cx-courdemanges-1988'), typeId: 'oct', @@ -234,6 +238,7 @@ describe("phases d'un titre", () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: null, id: newDemarcheId('h-cx-courdemanges-1988-oct01'), titreId: newTitreId('h-cx-courdemanges-1988'), typeId: 'oct', diff --git a/packages/api/src/business/processes/titres-statut-ids-update.test.ts b/packages/api/src/business/processes/titres-statut-ids-update.test.ts index 2ddc3ae50ca05817b58447993783096a747fafbc..0aed42c9970bbf700ea09f722b73fc1fc6500d51 100644 --- a/packages/api/src/business/processes/titres-statut-ids-update.test.ts +++ b/packages/api/src/business/processes/titres-statut-ids-update.test.ts @@ -29,6 +29,7 @@ describe("statut d'un titre", () => { titreStatutId: 'val', demarches: [ { + machineId: null, id: newDemarcheId('m-pr-saint-pierre-1914-oct01'), titreId: newTitreId('m-pr-saint-pierre-1914'), typeId: 'oct', @@ -56,6 +57,7 @@ describe("statut d'un titre", () => { propsTitreEtapesIds: {}, demarches: [ { + machineId: null, id: newDemarcheId('m-pr-saint-pierre-2014-oct01'), titreId: newTitreId('m-pr-saint-pierre-2014'), typeId: 'oct', diff --git a/packages/api/src/business/processes/update-machine-id.queries.ts b/packages/api/src/business/processes/update-machine-id.queries.ts new file mode 100644 index 0000000000000000000000000000000000000000..752fa8d5ff61dae1a3714681aa12111478743d71 --- /dev/null +++ b/packages/api/src/business/processes/update-machine-id.queries.ts @@ -0,0 +1,18 @@ +import { sql } from '@pgtyped/runtime' +import { z } from 'zod' +import { effectDbQueryAndValidate, EffectDbQueryAndValidateErrors, Redefine } from '../../pg-database' +import { Effect } from 'effect' +import { DemarcheId } from 'camino-common/src/demarche' +import { CaminoError } from 'camino-common/src/zod-tools' +import { CaminoMachineId } from 'camino-common/src/validators/machine' +import { IUpdateMachineIdDbQuery } from './update-machine-id.queries.types' +import { Pool } from 'pg' + +export type UpdateMachineIdErrors = EffectDbQueryAndValidateErrors +export const updateMachineId = (pool: Pool, demarcheId: DemarcheId, machineId: CaminoMachineId | null): Effect.Effect<DemarcheId, CaminoError<UpdateMachineIdErrors>> => { + return effectDbQueryAndValidate(updateMachineIdDb, { demarcheId, machineId }, pool, z.void()).pipe(Effect.map(() => demarcheId)) +} + +const updateMachineIdDb = sql<Redefine<IUpdateMachineIdDbQuery, { machineId: CaminoMachineId | null; demarcheId: DemarcheId }, void>>` +UPDATE titres_demarches SET machine_id = $machineId! WHERE id = $demarcheId! +` diff --git a/packages/api/src/business/processes/update-machine-id.queries.types.ts b/packages/api/src/business/processes/update-machine-id.queries.types.ts new file mode 100644 index 0000000000000000000000000000000000000000..fed60967c7d4c4cdef23eea3d748963bcbfd7da6 --- /dev/null +++ b/packages/api/src/business/processes/update-machine-id.queries.types.ts @@ -0,0 +1,17 @@ +/** Types generated for queries found in "src/business/processes/update-machine-id.queries.ts" */ + +/** 'UpdateMachineIdDb' parameters type */ +export interface IUpdateMachineIdDbParams { + demarcheId: string; + machineId: string; +} + +/** 'UpdateMachineIdDb' return type */ +export type IUpdateMachineIdDbResult = void; + +/** 'UpdateMachineIdDb' query type */ +export interface IUpdateMachineIdDbQuery { + params: IUpdateMachineIdDbParams; + result: IUpdateMachineIdDbResult; +} + diff --git a/packages/api/src/business/rules-demarches/machines.test.ts b/packages/api/src/business/rules-demarches/machines.test.ts index 63058ce568cd10842de09c52cb4d55318ecbaf99..eb4f01ea1fda92a6a9bda2ca8368d1e85c6edbc3 100644 --- a/packages/api/src/business/rules-demarches/machines.test.ts +++ b/packages/api/src/business/rules-demarches/machines.test.ts @@ -1,21 +1,46 @@ -import { expect, test } from 'vitest' +import { describe, expect, test } from 'vitest' -import { CaminoMachines, machineFind } from './machines' +import { ApiMachineInfo, demarcheEnregistrementDemandeDateFind } from './machines' import { isNotNullNorUndefined, isNullOrUndefined } from 'camino-common/src/typescript-tools' -import { demarcheEnregistrementDemandeDateFind } from 'camino-common/src/demarche' import { DemarcheWithEtapeForMachinesTest } from '../../tools/demarches/tests-creation' +import { MachineInfo } from 'camino-common/src/machines' +import { toCaminoDate } from 'camino-common/src/date' +import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' const etapesProdSpecifiqueArmAxm = require('./machines-cases.json') // eslint-disable-line // pour regénérer le machines-cases.json: `npm run test:generate-data -w packages/api` test.each(etapesProdSpecifiqueArmAxm as DemarcheWithEtapeForMachinesTest[])('cas réel N°$id', demarche => { const firstEtapeDate = demarcheEnregistrementDemandeDateFind(demarche.etapes.map(etape => ({ ...etape, typeId: etape.etapeTypeId }))) - let machine: CaminoMachines | undefined + let machine: ApiMachineInfo | undefined if (isNotNullNorUndefined(firstEtapeDate)) { - machine = machineFind(demarche.titreTypeId, demarche.demarcheTypeId, demarche.id, firstEtapeDate) + machine = new ApiMachineInfo(MachineInfo.withDate(demarche.titreTypeId, demarche.demarcheTypeId, demarche.id, firstEtapeDate)) } - if (isNullOrUndefined(machine)) { + if (isNullOrUndefined(machine) || isNullOrUndefined(machine.machine)) { throw new Error(`Impossible de trouver une machine alors qu'on aurait du avoir ${demarche.machineId}, ${demarche.id}`) } - machine.interpretMachine(demarche.etapes) - expect(machine.demarcheStatut(demarche.etapes), `${demarche.machineId}`).toStrictEqual(demarche.statut) + machine.machine.interpretMachine(demarche.etapes) + expect(machine.machine.demarcheStatut(demarche.etapes), `${demarche.machineId}`).toStrictEqual(demarche.statut) +}) + +describe('demarcheEnregistrementDemandeDateFind', () => { + test("pas d'étapes", () => { + expect(demarcheEnregistrementDemandeDateFind([])).toBe(null) + }) + + test('un enregistrement de la demande', () => { + expect( + demarcheEnregistrementDemandeDateFind([ + { typeId: ETAPES_TYPES.demande, date: toCaminoDate('2020-01-01') }, + { typeId: ETAPES_TYPES.enregistrementDeLaDemande, date: toCaminoDate('2024-01-01') }, + ]) + ).toBe(toCaminoDate('2024-01-01')) + }) + test('sans enregistrement de la demande', () => { + expect( + demarcheEnregistrementDemandeDateFind([ + { typeId: ETAPES_TYPES.demande, date: toCaminoDate('2020-01-01') }, + { typeId: ETAPES_TYPES.abrogationDeLaDecision, date: toCaminoDate('2024-01-01') }, + ]) + ).toBe(toCaminoDate('2020-01-01')) + }) }) diff --git a/packages/api/src/business/rules-demarches/machines.ts b/packages/api/src/business/rules-demarches/machines.ts index 19c42773bc01301830249152e5c29980e6557a7b..638291ba8c6acd5f6bcf85021106b18119a939f6 100644 --- a/packages/api/src/business/rules-demarches/machines.ts +++ b/packages/api/src/business/rules-demarches/machines.ts @@ -6,30 +6,66 @@ import { AxmProMachine } from './axm/pro.machine' import { PrmOctMachine } from './prm/oct.machine' import { ProcedureSimplifieeMachine } from './procedure-simplifiee/procedure-simplifiee.machine' import { ProcedureSpecifiqueMachine } from './procedure-specifique/procedure-specifique.machine' -import { machineIdFind, type CaminoMachineId } from 'camino-common/src/machines' +import { MachineInfo } from 'camino-common/src/machines' import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' -import { FirstEtapeDate } from 'camino-common/src/date' import { DemarcheId } from 'camino-common/src/demarche' -import { isNullOrUndefined } from 'camino-common/src/typescript-tools' +import { CaminoMachineId } from 'camino-common/src/validators/machine' +import { CaminoDate, FirstEtapeDate, firstEtapeDateValidator } from 'camino-common/src/date' +import { EtapeTypeId, ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' +import { isNullOrUndefinedOrEmpty, isNotNullNorUndefined, toSorted } from 'camino-common/src/typescript-tools' +import { NonEmptyArray } from 'zod-validation-error' const machines = { - ArmOct: (titreTypeId, demarcheTypeId) => new ArmOctMachine(titreTypeId, demarcheTypeId), - ArmRenPro: (titreTypeId, demarcheTypeId) => new ArmRenProMachine(titreTypeId, demarcheTypeId), - AxmOct: (titreTypeId, demarcheTypeId) => new AxmOctMachine(titreTypeId, demarcheTypeId), - AxmPro: (titreTypeId, demarcheTypeId) => new AxmProMachine(titreTypeId, demarcheTypeId), - PrmOct: (titreTypeId, demarcheTypeId) => new PrmOctMachine(titreTypeId, demarcheTypeId), + AncienLogigrammeOctroiARM: (titreTypeId, demarcheTypeId) => new ArmOctMachine(titreTypeId, demarcheTypeId), + AncienLogigrammeRenonciationEtProlongationARM: (titreTypeId, demarcheTypeId) => new ArmRenProMachine(titreTypeId, demarcheTypeId), + AncienLogigrammeOctroiAXM: (titreTypeId, demarcheTypeId) => new AxmOctMachine(titreTypeId, demarcheTypeId), + AncienLogigrammeProlongationAXM: (titreTypeId, demarcheTypeId) => new AxmProMachine(titreTypeId, demarcheTypeId), + AncienLogigrammeOctroiPRM: (titreTypeId, demarcheTypeId) => new PrmOctMachine(titreTypeId, demarcheTypeId), ProcedureSimplifiee: (titreTypeId, demarcheTypeId) => new ProcedureSimplifieeMachine(titreTypeId, demarcheTypeId), ProcedureSpecifique: (titreTypeId, demarcheTypeId) => new ProcedureSpecifiqueMachine(titreTypeId, demarcheTypeId), } as const satisfies Record<CaminoMachineId, (titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId) => CaminoMachines> -export const machineFind = (titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId, demarcheId: DemarcheId, date: FirstEtapeDate): CaminoMachines | undefined => { - const machineId = machineIdFind(titreTypeId, demarcheTypeId, demarcheId, date) - if (isNullOrUndefined(machineId)) { - return undefined +export class ApiMachineInfo { + private _machineInfo: MachineInfo + private _machine: CaminoMachines | undefined + public constructor(machineInfo: MachineInfo) { + this._machineInfo = machineInfo + this._machine = machineInfo.machineId === undefined ? undefined : machines[machineInfo.machineId](machineInfo.titreTypeId, machineInfo.demarcheTypeId) + } + + get machineId(): CaminoMachineId | undefined { + return this._machineInfo.machineId + } + get titreTypeId(): TitreTypeId { + return this._machineInfo.titreTypeId + } + get demarcheTypeId(): DemarcheTypeId { + return this._machineInfo.demarcheTypeId + } + get demarcheId(): DemarcheId { + return this._machineInfo.demarcheId + } + get machine(): CaminoMachines | undefined { + return this._machine } - return getMachineFromId({ machineId, titreTypeId, demarcheTypeId }) } -export const getMachineFromId = (entry: { machineId: CaminoMachineId; titreTypeId: TitreTypeId; demarcheTypeId: DemarcheTypeId } | undefined): CaminoMachines | undefined => - entry === undefined ? undefined : machines[entry.machineId](entry.titreTypeId, entry.demarcheTypeId) export type CaminoMachines = ArmOctMachine | AxmOctMachine | AxmProMachine | ArmRenProMachine | PrmOctMachine | ProcedureSimplifieeMachine | ProcedureSpecifiqueMachine + +type DemarcheEnregistrementDemandeDateFindEtape = { date: CaminoDate; typeId: EtapeTypeId } +export function demarcheEnregistrementDemandeDateFind<T extends DemarcheEnregistrementDemandeDateFindEtape[] | NonEmptyArray<DemarcheEnregistrementDemandeDateFindEtape>>( + titreEtapes: T | undefined +): T extends [DemarcheEnregistrementDemandeDateFindEtape, ...DemarcheEnregistrementDemandeDateFindEtape[]] ? FirstEtapeDate : FirstEtapeDate | null +export function demarcheEnregistrementDemandeDateFind(titreEtapes: DemarcheEnregistrementDemandeDateFindEtape[] | undefined): null | FirstEtapeDate { + if (isNullOrUndefinedOrEmpty(titreEtapes)) { + return null + } + + const titreEtapeDemande = titreEtapes.find(te => te.typeId === ETAPES_TYPES.enregistrementDeLaDemande) + + if (isNotNullNorUndefined(titreEtapeDemande)) { + return firstEtapeDateValidator.parse(titreEtapeDemande.date) + } + + return firstEtapeDateValidator.parse(toSorted(titreEtapes.map(te => te.date))[0]) +} diff --git a/packages/api/src/business/rules/titre-activites-build.test.ts b/packages/api/src/business/rules/titre-activites-build.test.ts index 1fa74fe87ea52f8528d066566e1afff994585d6d..7a53ca6ebf553552c131d210a2014a5c9b0777d1 100644 --- a/packages/api/src/business/rules/titre-activites-build.test.ts +++ b/packages/api/src/business/rules/titre-activites-build.test.ts @@ -55,6 +55,7 @@ describe("construction des activités d'un titre", () => { test('crée des activités', () => { const titreActivitesA = titreActivitesBuild(ACTIVITES_TYPES_IDS["rapport d'exploitation (permis et concessions M)"], [toCaminoAnnee(2018)], aujourdhui, titreId, 'pxm', [ { + machineId: null, id: newDemarcheId('demarche-id'), titreId: newTitreId('titreId'), statutId: 'acc', diff --git a/packages/api/src/business/rules/titre-date-demande-find.test.ts b/packages/api/src/business/rules/titre-date-demande-find.test.ts index a58e9777cf41f4ea1de6e57a579ab8285c709c09..d691d3c62857e9742547d03d88e632feacae6a0a 100644 --- a/packages/api/src/business/rules/titre-date-demande-find.test.ts +++ b/packages/api/src/business/rules/titre-date-demande-find.test.ts @@ -26,6 +26,7 @@ const titreDemarcheOctEtapeMen = [ const titreDemarcheOctSansEtapes = [ { + machineId: null, id: newDemarcheId('h-cx-courdemanges-1988-oct01'), titreId: newTitreId('h-cx-courdemanges-1988'), typeId: 'oct', diff --git a/packages/api/src/business/rules/titre-demarche-annulation-date-fin-find.test.ts b/packages/api/src/business/rules/titre-demarche-annulation-date-fin-find.test.ts index 307efb2d52de074fc46b38a6b3b6f6a601b380d1..35b4106dc3149f40c589917008b20e22091f6470 100644 --- a/packages/api/src/business/rules/titre-demarche-annulation-date-fin-find.test.ts +++ b/packages/api/src/business/rules/titre-demarche-annulation-date-fin-find.test.ts @@ -7,9 +7,10 @@ import { describe, expect, test } from 'vitest' import { ETAPE_IS_NOT_BROUILLON } from 'camino-common/src/etape' import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' -import { titreIdValidator } from 'camino-common/src/validators/titres' import { NonEmptyArray } from 'camino-common/src/typescript-tools' import { ETAPES_STATUTS, EtapeStatutId } from 'camino-common/src/static/etapesStatuts' +import { MachineInfo } from 'camino-common/src/machines' +import { demarcheEnregistrementDemandeDateFind } from '../rules-demarches/machines' describe("date de fin d'une démarche d'annulation", () => { test.each<{ typeId: EtapeTypeId; statutId: EtapeStatutId }>([ { typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.ACCEPTE }, @@ -30,12 +31,10 @@ describe("date de fin d'une démarche d'annulation", () => { }, ] as const satisfies ITitreEtape[] expect( - titreDemarcheAnnulationDateFinFind(TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, { - id: titreDemarcheId, - titreId: titreIdValidator.parse('titreId'), - typeId: DEMARCHES_TYPES_IDS.Retrait, - etapes: titreDemarcheAnnulationEtapes, - }) + titreDemarcheAnnulationDateFinFind( + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, DEMARCHES_TYPES_IDS.Retrait, titreDemarcheId, demarcheEnregistrementDemandeDateFind(titreDemarcheAnnulationEtapes)), + titreDemarcheAnnulationEtapes + ) ).toEqual('1999-05-21') }) // TODO 2025-01-15 cet id est ignoré explicitement dans la machine pour utiliser TDE, test à virer quand on arrête de faire des avenant dans les octrois mais qu'on fait des prolongations (tache à POH) @@ -60,12 +59,16 @@ describe("date de fin d'une démarche d'annulation", () => { }, ] expect( - titreDemarcheAnnulationDateFinFind(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, { - id: titreDemarcheId, - titreId: titreIdValidator.parse('titreId'), - typeId: DEMARCHES_TYPES_IDS.Octroi, - etapes: titreDemarcheAnnulationEtapesDateFin, - }) + titreDemarcheAnnulationDateFinFind( + MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + titreDemarcheId, + demarcheEnregistrementDemandeDateFind(titreDemarcheAnnulationEtapesDateFin) + ), + + titreDemarcheAnnulationEtapesDateFin + ) ).toEqual('2013-05-25') } ) @@ -87,12 +90,15 @@ describe("date de fin d'une démarche d'annulation", () => { }, ] expect( - titreDemarcheAnnulationDateFinFind(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, { - id: titreDemarcheIdExcluDesOctroisDArm, - titreId: titreIdValidator.parse('titreId'), - typeId: DEMARCHES_TYPES_IDS.Octroi, - etapes: titreDemarcheACOFaitEtapesDateFin, - }) + titreDemarcheAnnulationDateFinFind( + MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + titreDemarcheIdExcluDesOctroisDArm, + demarcheEnregistrementDemandeDateFind(titreDemarcheACOFaitEtapesDateFin) + ), + titreDemarcheACOFaitEtapesDateFin + ) ).toEqual('2013-05-25') }) }) diff --git a/packages/api/src/business/rules/titre-demarche-annulation-date-fin-find.ts b/packages/api/src/business/rules/titre-demarche-annulation-date-fin-find.ts index ce549bc405228d75988d3029a1a8c070bda80a0f..909a0b5923bdff75a6988bf272fa55fd3751d1c3 100644 --- a/packages/api/src/business/rules/titre-demarche-annulation-date-fin-find.ts +++ b/packages/api/src/business/rules/titre-demarche-annulation-date-fin-find.ts @@ -1,26 +1,25 @@ import { CaminoDate } from 'camino-common/src/date' import { titreEtapesSortAscByOrdre, titreEtapesSortDescByOrdre } from '../utils/titre-etapes-sort' -import { TitreDemarchePhaseFindWithEtapes, TitreEtapePhaseFind } from './titre-phases-find' +import { TitreEtapePhaseFind } from './titre-phases-find' import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' -import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools' -import { machineFind } from '../rules-demarches/machines' -import { demarcheEnregistrementDemandeDateFind } from 'camino-common/src/demarche' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' +import { isNotNullNorUndefined, NonEmptyArray } from 'camino-common/src/typescript-tools' import { toMachineEtapes } from '../rules-demarches/machine-common' import { demarcheStatutIdsSuccess } from 'camino-common/src/static/demarchesStatuts' +import { MachineInfo } from 'camino-common/src/machines' +import { ApiMachineInfo } from '../rules-demarches/machines' -export const titreDemarcheAnnulationDateFinFind = (titreTypeId: TitreTypeId, demarche: Omit<TitreDemarchePhaseFindWithEtapes, 'fullEtapes'>): CaminoDate | null | undefined => { - const machine = machineFind(titreTypeId, demarche.typeId, demarche.id, demarcheEnregistrementDemandeDateFind(demarche.etapes)) - if (isNotNullNorUndefined(machine)) { - const statut = machine.demarcheStatut(toMachineEtapes(demarche.etapes)) +export const titreDemarcheAnnulationDateFinFind = (machineInfo: MachineInfo, etapes: NonEmptyArray<TitreEtapePhaseFind>): CaminoDate | null | undefined => { + const machine = new ApiMachineInfo(machineInfo) + if (isNotNullNorUndefined(machine.machine)) { + const statut = machine.machine.demarcheStatut(toMachineEtapes(etapes)) if (demarcheStatutIdsSuccess.has(statut.demarcheStatut)) { if ('demarcheDateEffet' in statut) { return statut.demarcheDateEffet } - throw new Error(`Pas de date d'effet trouvée pour la démarche d'annulation https://camino.beta.gouv.fr/demarches/${demarche.id}`) + throw new Error(`Pas de date d'effet trouvée pour la démarche d'annulation https://camino.beta.gouv.fr/demarches/${machineInfo.demarcheId}`) } return null } else { @@ -32,7 +31,7 @@ export const titreDemarcheAnnulationDateFinFind = (titreTypeId: TitreTypeId, dem (te.typeId === ETAPES_TYPES.avenantALautorisationDeRechercheMiniere && te.statutId === ETAPES_STATUTS.FAIT) // la dernière étape qui valide l’annulation et qui contient une date de fin - const etapeAnnulationHasDateFin = titreEtapesSortDescByOrdre(demarche.etapes).find(te => isNotNullNorUndefined(te.dateFin) && etapeAnnulationValideCheck(te)) + const etapeAnnulationHasDateFin = titreEtapesSortDescByOrdre(etapes).find(te => isNotNullNorUndefined(te.dateFin) && etapeAnnulationValideCheck(te)) // si la démarche contient une date de fin if (etapeAnnulationHasDateFin) { @@ -41,7 +40,7 @@ export const titreDemarcheAnnulationDateFinFind = (titreTypeId: TitreTypeId, dem // sinon, // trouve la première étape qui valide l’annulation - const etapeAnnulation = titreEtapesSortAscByOrdre(demarche.etapes).find(etapeAnnulationValideCheck) + const etapeAnnulation = titreEtapesSortAscByOrdre(etapes).find(etapeAnnulationValideCheck) // la date de fin est la date de l'étape return etapeAnnulation?.date ?? null diff --git a/packages/api/src/business/rules/titre-demarche-public-find.test.ts b/packages/api/src/business/rules/titre-demarche-public-find.test.ts index a336a03a94b0aec81b26f1c4411d3331bc8393f6..dff05255600202aca1d6ff662fae7c8a86a2d90e 100644 --- a/packages/api/src/business/rules/titre-demarche-public-find.test.ts +++ b/packages/api/src/business/rules/titre-demarche-public-find.test.ts @@ -3,12 +3,13 @@ import { ITitreEtape } from '../../types' import { titreDemarchePublicFind } from './titre-demarche-public-find' import { ETAPES_TYPES, EtapeTypeId } from 'camino-common/src/static/etapesTypes' import { newDemarcheId, newEtapeId, newTitreId } from '../../database/models/_format/id-create' -import { toCaminoDate } from 'camino-common/src/date' +import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { describe, expect, test } from 'vitest' import { DEMARCHES_TYPES_IDS, DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' import { ETAPE_IS_NOT_BROUILLON } from 'camino-common/src/etape' import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' +import { MachineInfo } from 'camino-common/src/machines' const etapesBuild = (etapesProps: Partial<ITitreEtape>[]) => etapesProps.map( (etapeProps, i) => @@ -20,23 +21,19 @@ const etapesBuild = (etapesProps: Partial<ITitreEtape>[]) => ...etapeProps, ordre: i + 1, date: toCaminoDate('0001-01-01'), + demarcheIdsConsentement: [], }) as unknown as ITitreEtape ) describe("publicité d'une démarche", () => { test("une démarche sans étape n'est pas publique", () => { expect( - titreDemarchePublicFind( - { - id: newDemarcheId(), - typeId: DEMARCHES_TYPES_IDS.Octroi, - etapes: [], - titreId: newTitreId('titreId'), - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { + etapes: [], + titreId: newTitreId('titreId'), + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + }) ).toMatchObject({ publicLecture: false, entreprisesLecture: false, @@ -46,15 +43,13 @@ describe("publicité d'une démarche", () => { test("une démarche d'octroi sans étape décisive n'est pas publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - id: newDemarcheId(), - typeId: DEMARCHES_TYPES_IDS.Octroi, etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLaMissionAutoriteEnvironnementale_ExamenAuCasParCasDuProjet_ }]), titreId: newTitreId('titreId'), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: false, entreprisesLecture: false }) }) @@ -62,15 +57,13 @@ describe("publicité d'une démarche", () => { test("une démarche de retrait dont l'étape la plus récente est saisine du préfet est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([{ typeId: ETAPES_TYPES.saisineDuPrefet }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: false, entreprisesLecture: false }) }) @@ -78,15 +71,13 @@ describe("publicité d'une démarche", () => { test("une démarche de retrait dont l'étape la plus récente est saisine du préfet est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Retrait, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Retrait, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([{ typeId: ETAPES_TYPES.saisineDuPrefet }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true, entreprisesLecture: true }) }) @@ -94,15 +85,13 @@ describe("publicité d'une démarche", () => { test("une démarche de déchéance dont l'étape la plus récente est saisine du préfet est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Decheance, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Decheance, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([{ typeId: ETAPES_TYPES.saisineDuPrefet }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true, entreprisesLecture: true }) }) @@ -110,178 +99,132 @@ describe("publicité d'une démarche", () => { test("une démarche dont l'étape la plus récente est demande est visible uniquement par l'entreprise", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([{ typeId: ETAPES_TYPES.demande }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: false, entreprisesLecture: true }) }) test("une démarche d'une machine simplifiée dont l'étape la plus récente est décision de l'administration est visible", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), - demarcheDateDebut: toCaminoDate('2023-01-01'), - demarcheDateFin: toCaminoDate('2026-01-01'), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, date: toCaminoDate('2023-01-01'), statutId: ETAPES_STATUTS.ACCEPTE, isBrouillon: ETAPE_IS_NOT_BROUILLON }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_GEOTHERMIE - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_GEOTHERMIE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2023-01-01')), { + demarcheDateDebut: toCaminoDate('2023-01-01'), + demarcheDateFin: toCaminoDate('2026-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, date: toCaminoDate('2023-01-01'), statutId: ETAPES_STATUTS.ACCEPTE, isBrouillon: ETAPE_IS_NOT_BROUILLON }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true, entreprisesLecture: true }) }) test("une démarche dont l'étape la plus récente est classement sans suite n'est pas publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([{ typeId: ETAPES_TYPES.classementSansSuite }, { typeId: ETAPES_TYPES.demande }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: false }) }) test("une démarche d'un titre AXM dont l'étape la plus récente est classement sans suite ne change pas de visibilité", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2000-01-01') }, { typeId: ETAPES_TYPES.classementSansSuite }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2000-01-01') }, { typeId: ETAPES_TYPES.classementSansSuite }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche d'un titre ARM dont l'étape la plus récente est classement sans suite ne change pas de visibilité", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - etapes: etapesBuild([ - { typeId: ETAPES_TYPES.saisineDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_, date: toCaminoDate('2000-01-01') }, - { typeId: ETAPES_TYPES.classementSansSuite }, - ]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2000-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.saisineDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_, date: toCaminoDate('2000-01-01') }, { typeId: ETAPES_TYPES.classementSansSuite }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche d'un titre ARM dont l'étape la plus récente est désistement du demandeur est publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.desistementDuDemandeur, date: toCaminoDate('2000-01-01') }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2000-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.desistementDuDemandeur, date: toCaminoDate('2000-01-01') }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche d'un titre AXM dont l'étape la plus récente est désistement du demandeur est publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.desistementDuDemandeur, date: toCaminoDate('2000-01-01') }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.desistementDuDemandeur, date: toCaminoDate('2000-01-01') }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche ne pouvant pas faire l'objet d'une mise en concurrence dont l'étape la plus récente est recevabilité est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Prolongation1, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Prolongation1, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) test("une démarche d'un titre ARM ne pouvant pas faire l'objet d'une mise en concurrence dont l'étape la plus récente est recevabilité n'est pas publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2000-01-01') }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2000-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2000-01-01') }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: false }) }) test("une démarche pouvant faire l'objet d'une mise en concurrence dont l'étape la plus récente est recevabilité n'est pas publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.CONCESSION_GEOTHERMIE - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: false }) }) test("une démarche dont l'étape la plus récente est mise en concurrence au JORF est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([{ typeId: ETAPES_TYPES.avisDeMiseEnConcurrenceAuJORF }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) @@ -289,15 +232,13 @@ describe("publicité d'une démarche", () => { test("une démarche dont l'étape la plus récente est publication de l'avis de décision implicite (historique) est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([{ typeId: ETAPES_TYPES.publicationDeLavisDeDecisionImplicite }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) @@ -305,79 +246,60 @@ describe("publicité d'une démarche", () => { test("une démarche dont l'étape la plus récente est consultation du public est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([{ typeId: ETAPES_TYPES.consultationDuPublic }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) test("une démarche d'un titre ARM dont l'étape la plus récente est décision de l'ONF peu importe son statut (historique) est publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLOfficeNationalDesForets, date: toCaminoDate('2000-01-01') }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2000-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLOfficeNationalDesForets, date: toCaminoDate('2000-01-01') }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche d'un titre ARM dont l'étape la plus récente est commission ARM peu importe son statut (historique) est publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.avisDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_, date: toCaminoDate('2000-01-01') }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2000-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.avisDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_, date: toCaminoDate('2000-01-01') }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche d'un titre ARM dont l'étape la plus récente est saisine de la commission ARM est publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.saisineDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_, date: toCaminoDate('2000-01-01') }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2000-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.saisineDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_, date: toCaminoDate('2000-01-01') }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche dont l'étape la plus récente est décision implicite au statut accepté est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.ACCEPTE_DECISION_IMPLICITE }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) @@ -385,9 +307,8 @@ describe("publicité d'une démarche", () => { test("une démarche dont l'étape la plus récente est décision implicite au statut rejeté n'est pas publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, - id: newDemarcheId(), demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), etapes: etapesBuild([ @@ -395,8 +316,7 @@ describe("publicité d'une démarche", () => { { typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.REJETE_DECISION_IMPLICITE, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2021-01-02') }, ]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: false }) }) @@ -404,66 +324,52 @@ describe("publicité d'une démarche", () => { test("une démarche d'un titre non AXM dont l'étape la plus récente est décision de l'administration au statut rejeté n'est pas publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.REJETE }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: false }) }) test("une démarche d'un titre AXM dont l'étape la plus récente est décision de l'administration au statut rejeté est publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([ - { typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2000-01-01') }, - { typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.REJETE }, - ]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([ + { typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2000-01-01') }, + { typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.REJETE }, + ]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche d'un titre AXM dont l'étape la plus récente est décision de l'administration au statut accepté est publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.ACCEPTE, date: toCaminoDate('2000-01-01') }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.ACCEPTE, date: toCaminoDate('2000-01-01') }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche dont l'étape la plus récente est publication de décision au JORF au statut au statut accepté publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), etapes: etapesBuild([{ typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: ETAPES_STATUTS.ACCEPTE }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) @@ -471,15 +377,13 @@ describe("publicité d'une démarche", () => { test("une démarche dont l'étape la plus récente est décision de l'autorité administrative est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) @@ -487,15 +391,13 @@ describe("publicité d'une démarche", () => { test("une démarche dont l'étape la plus récente est publication de décision unilatérale est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), etapes: etapesBuild([{ typeId: ETAPES_TYPES.publicationDeDecisionAuJORF }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) @@ -503,63 +405,49 @@ describe("publicité d'une démarche", () => { test("une démarche dont l'étape la plus récente est publication de décision au recueil des actes administratifs est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), etapes: etapesBuild([{ typeId: ETAPES_TYPES.publicationDeDecisionAuRecueilDesActesAdministratifs }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) test("une démarche d'un titre ARM dont l'étape la plus récente est signature de l'autorisation de recherche minière est publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - demarcheDateDebut: toCaminoDate('2000-01-01'), - demarcheDateFin: toCaminoDate('2001-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.signatureDeLautorisationDeRechercheMiniere, date: toCaminoDate('2000-01-01') }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2000-01-01')), { + demarcheDateDebut: toCaminoDate('2000-01-01'), + demarcheDateFin: toCaminoDate('2001-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.signatureDeLautorisationDeRechercheMiniere, date: toCaminoDate('2000-01-01') }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche d'un titre ARM dont l'étape la plus récente est signature de l'avenant à l'autorisation de recherche minière est publique", () => { expect( - titreDemarchePublicFind( - { - typeId: DEMARCHES_TYPES_IDS.Octroi, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.signatureDeLautorisationDeRechercheMiniere, date: toCaminoDate('2000-01-01') }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2000-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.signatureDeLautorisationDeRechercheMiniere, date: toCaminoDate('2000-01-01') }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) }) test("une démarche dont l'étape la plus récente est décision d'annulation par le juge administratif est publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDuJugeAdministratif, statutId: ETAPES_STATUTS.FAVORABLE }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) @@ -567,15 +455,13 @@ describe("publicité d'une démarche", () => { test("une démarche dont l'étape la plus récente est décision d'annulation par le juge administratif au statut fait n'est pas publique", () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), etapes: etapesBuild([{ typeId: ETAPES_TYPES.decisionDuJugeAdministratif, statutId: ETAPES_STATUTS.FAIT }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: false }) }) @@ -584,33 +470,23 @@ describe("publicité d'une démarche", () => { "une démarche %s dont l'étape la plus récente est le dépot de la demande n'est pas publique", demarcheTypeId => { expect( - titreDemarchePublicFind( - { - typeId: demarcheTypeId, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, demarcheTypeId, newDemarcheId(), firstEtapeDateValidator.parse('2017-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: false }) expect( - titreDemarchePublicFind( - { - typeId: demarcheTypeId, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([ - { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-02'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - ]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, demarcheTypeId, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([ + { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-02'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + ]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: false }) } ) @@ -619,35 +495,25 @@ describe("publicité d'une démarche", () => { "une démarche %s dont l'étape la plus récente est recevabilité de la demande est publique", demarcheTypeId => { expect( - titreDemarchePublicFind( - { - typeId: demarcheTypeId, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, demarcheTypeId, newDemarcheId(), firstEtapeDateValidator.parse('2017-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) expect( - titreDemarchePublicFind( - { - typeId: demarcheTypeId, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([ - { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-02'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.recevabiliteDeLaDemande, statutId: ETAPES_STATUTS.FAVORABLE, date: toCaminoDate('2020-01-03'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - ]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, demarcheTypeId, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([ + { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-02'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.recevabiliteDeLaDemande, statutId: ETAPES_STATUTS.FAVORABLE, date: toCaminoDate('2020-01-03'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + ]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) } ) @@ -656,38 +522,33 @@ describe("publicité d'une démarche", () => { "une démarche %s dont l'étape la plus récente est l’expertise de l’onf est publique", demarcheTypeId => { expect( - titreDemarchePublicFind( - { - typeId: demarcheTypeId, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([ - { typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - ]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, demarcheTypeId, newDemarcheId(), firstEtapeDateValidator.parse('2017-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([ + { typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + ]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) expect( - titreDemarchePublicFind( - { - typeId: demarcheTypeId, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([ - { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-02'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.recevabiliteDeLaDemande, statutId: ETAPES_STATUTS.FAVORABLE, date: toCaminoDate('2020-01-03'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-05'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - ]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, demarcheTypeId, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([ + { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-02'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.recevabiliteDeLaDemande, statutId: ETAPES_STATUTS.FAVORABLE, date: toCaminoDate('2020-01-03'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, + statutId: ETAPES_STATUTS.FAIT, + date: toCaminoDate('2020-01-05'), + isBrouillon: ETAPE_IS_NOT_BROUILLON, + }, + ]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) } ) @@ -696,35 +557,25 @@ describe("publicité d'une démarche", () => { "une démarche %s dont l'étape la plus récente est la décision de classement sans suite est publique", demarcheTypeId => { expect( - titreDemarchePublicFind( - { - typeId: demarcheTypeId, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.classementSansSuite, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, demarcheTypeId, newDemarcheId(), firstEtapeDateValidator.parse('2017-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.classementSansSuite, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON, statutId: ETAPES_STATUTS.FAIT }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) expect( - titreDemarchePublicFind( - { - typeId: demarcheTypeId, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([ - { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-02'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.recevabiliteDeLaDemande, statutId: ETAPES_STATUTS.FAVORABLE, date: toCaminoDate('2020-01-03'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.classementSansSuite, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-05'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - ]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, demarcheTypeId, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([ + { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-02'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.recevabiliteDeLaDemande, statutId: ETAPES_STATUTS.FAVORABLE, date: toCaminoDate('2020-01-03'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.classementSansSuite, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-05'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + ]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) } ) @@ -734,35 +585,25 @@ describe("publicité d'une démarche", () => { demarcheTypeId => { // sans machine expect( - titreDemarchePublicFind( - { - typeId: demarcheTypeId, - demarcheDateDebut: toCaminoDate('2017-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([{ typeId: ETAPES_TYPES.desistementDuDemandeur, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, demarcheTypeId, newDemarcheId(), firstEtapeDateValidator.parse('2017-01-01')), { + demarcheDateDebut: toCaminoDate('2017-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([{ typeId: ETAPES_TYPES.desistementDuDemandeur, date: toCaminoDate('2017-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) // avec machine expect( - titreDemarchePublicFind( - { - typeId: demarcheTypeId, - demarcheDateDebut: toCaminoDate('2020-01-01'), - demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), - etapes: etapesBuild([ - { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-02'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - { typeId: ETAPES_TYPES.desistementDuDemandeur, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-05'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, - ]), - titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ) + titreDemarchePublicFind(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, demarcheTypeId, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-02')), { + demarcheDateDebut: toCaminoDate('2020-01-01'), + demarcheDateFin: toCaminoDate('2021-01-01'), + etapes: etapesBuild([ + { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-01'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-02'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + { typeId: ETAPES_TYPES.desistementDuDemandeur, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-01-05'), isBrouillon: ETAPE_IS_NOT_BROUILLON }, + ]), + titreId: newTitreId('titreId'), + }) ).toMatchObject({ publicLecture: true }) } ) @@ -777,15 +618,13 @@ describe("publicité d'une démarche", () => { ])("une démarche d’un titre non énergétique dont l'étape la plus récente est %s est public", etapeTypeId => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), etapes: etapesBuild([{ typeId: etapeTypeId, isBrouillon: ETAPE_IS_NOT_BROUILLON }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: true }) }) @@ -793,9 +632,8 @@ describe("publicité d'une démarche", () => { test('la demarche d’une prolongation déposée d’un PRM en survie provisoire est public ', () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Prolongation1, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - id: newDemarcheId(), - typeId: DEMARCHES_TYPES_IDS.Prolongation1, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: null, etapes: etapesBuild([ @@ -803,8 +641,7 @@ describe("publicité d'une démarche", () => { { typeId: ETAPES_TYPES.enregistrementDeLaDemande, isBrouillon: ETAPE_IS_NOT_BROUILLON }, ]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX + } ) ).toMatchObject({ publicLecture: true }) }) @@ -812,15 +649,13 @@ describe("publicité d'une démarche", () => { test('le titre WQaZgPfDcQw9tFliMgBIDH3Z ne doit pas être public', () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - typeId: DEMARCHES_TYPES_IDS.Octroi, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2021-01-01'), - id: newDemarcheId(), etapes: etapesBuild([{ typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, isBrouillon: ETAPE_IS_NOT_BROUILLON }]), titreId: newTitreId('WQaZgPfDcQw9tFliMgBIDH3Z'), - }, - TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_GRANULATS_MARINS + } ) ).toMatchObject({ publicLecture: false }) }) @@ -828,15 +663,13 @@ describe("publicité d'une démarche", () => { test('la demarche d’une prolongation non déposée d’un PRM en survie provisoire n’est pas public ', () => { expect( titreDemarchePublicFind( + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Prolongation1, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')), { - id: newDemarcheId(), - typeId: DEMARCHES_TYPES_IDS.Prolongation1, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: null, etapes: etapesBuild([{ typeId: ETAPES_TYPES.demande, isBrouillon: ETAPE_IS_NOT_BROUILLON }]), titreId: newTitreId('titreId'), - }, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX + } ) ).toMatchObject({ publicLecture: false }) }) diff --git a/packages/api/src/business/rules/titre-demarche-public-find.ts b/packages/api/src/business/rules/titre-demarche-public-find.ts index 95eeccb63692d715a646202351198e8843efde20..9630c8ac8ec7b9b2a3d969ea1d4a82088630448e 100644 --- a/packages/api/src/business/rules/titre-demarche-public-find.ts +++ b/packages/api/src/business/rules/titre-demarche-public-find.ts @@ -8,9 +8,9 @@ import { titreEtapesSortAscByOrdre } from '../utils/titre-etapes-sort' import { titreInModificationEnInstance } from './titre-statut-id-find' import { ETAPES_STATUTS, isEtapeStatusRejete } from 'camino-common/src/static/etapesStatuts' import { DOMAINES_IDS } from 'camino-common/src/static/domaines' -import { CaminoMachines, machineFind } from '../rules-demarches/machines' -import { demarcheEnregistrementDemandeDateFind } from 'camino-common/src/demarche' +import { ApiMachineInfo } from '../rules-demarches/machines' import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools' +import { MachineInfo } from 'camino-common/src/machines' const titreDemarchePublicLectureFind = ( publicLecture: boolean, demarcheTypeId: DemarcheTypeId, @@ -197,8 +197,8 @@ const titreDemarchePublicLectureFind = ( */ export const titreDemarchePublicFind = ( - titreDemarche: Pick<ITitreDemarche, 'titreId' | 'demarcheDateDebut' | 'demarcheDateFin' | 'id' | 'typeId' | 'etapes'>, - titreTypeId: TitreTypeId + machineInfo: MachineInfo, + titreDemarche: Pick<ITitreDemarche, 'titreId' | 'demarcheDateDebut' | 'demarcheDateFin' | 'etapes'> ): { publicLecture: boolean; entreprisesLecture: boolean } => { const titreDemarcheEtapes = titreEtapesSortAscByOrdre(titreDemarche.etapes ?? []) @@ -210,19 +210,14 @@ export const titreDemarchePublicFind = ( if (titreDemarche.titreId === 'WQaZgPfDcQw9tFliMgBIDH3Z') { publicLecture = false } else { - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(titreDemarcheEtapes) + const machine = new ApiMachineInfo(machineInfo) - let machine: CaminoMachines | undefined - if (isNotNullNorUndefined(firstEtapeDate)) { - machine = machineFind(titreTypeId, titreDemarche.typeId, titreDemarche.id, firstEtapeDate) - } - - if (isNotNullNorUndefined(machine)) { - publicLecture = machine.demarcheStatut(toMachineEtapes(titreDemarcheEtapes.map(etape => titreEtapeForMachineValidator.parse(etape)))).publique + if (isNotNullNorUndefined(machine.machine)) { + publicLecture = machine.machine.demarcheStatut(toMachineEtapes(titreDemarcheEtapes.map(etape => titreEtapeForMachineValidator.parse(etape)))).publique } else { - const demarcheTypeEtapesTypes = getEtapesTDE(titreTypeId, titreDemarche.typeId) + const demarcheTypeEtapesTypes = getEtapesTDE(machineInfo.titreTypeId, machineInfo.demarcheTypeId) publicLecture = titreDemarcheEtapes.reduce( - (publicLecture, titreEtape) => titreDemarchePublicLectureFind(publicLecture, titreDemarche.typeId, demarcheTypeEtapesTypes, titreEtape, titreDemarche, titreTypeId), + (publicLecture, titreEtape) => titreDemarchePublicLectureFind(publicLecture, machineInfo.demarcheTypeId, demarcheTypeEtapesTypes, titreEtape, titreDemarche, machineInfo.titreTypeId), false ) if (!publicLecture && titreDemarcheEtapes.length === 1 && titreDemarcheEtapes[0].typeId === ETAPES_TYPES.publicationDeDecisionAuJORF && titreDemarcheEtapes[0].statutId === ETAPES_STATUTS.FAIT) { diff --git a/packages/api/src/business/rules/titre-demarche-statut-id-find.test.ts b/packages/api/src/business/rules/titre-demarche-statut-id-find.test.ts index d59e0d59629c8049bf41e719d06b3fc39378e6c2..108fd556d2f05d42748bd6e2b0218e1b551fd7f2 100644 --- a/packages/api/src/business/rules/titre-demarche-statut-id-find.test.ts +++ b/packages/api/src/business/rules/titre-demarche-statut-id-find.test.ts @@ -11,6 +11,8 @@ import { ETAPE_IS_BROUILLON, ETAPE_IS_NOT_BROUILLON } from 'camino-common/src/et import { ETAPES_TYPES, EtapeTypeId } from 'camino-common/src/static/etapesTypes' import { TITRES_TYPES_IDS, TitreTypeId } from 'camino-common/src/static/titresTypes' import { DEMARCHES_TYPES_IDS, DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' +import { throwableMachineInfoForTestsOnly } from '../../../tests/_utils' + const etapesBuild = ( etapesProps: Partial<ITitreEtape>[], demarcheTypeId: DemarcheTypeId = DEMARCHES_TYPES_IDS.Octroi, @@ -30,16 +32,16 @@ const etapesBuild = ( describe("statut d'une démarche", () => { test('une démarche sans étape a le statut “indéfini”', () => { - expect(titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.Octroi, [], TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId())).toEqual(DemarchesStatutsIds.Indetermine) + expect(titreDemarcheStatutIdFind(throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), [])).toEqual( + DemarchesStatutsIds.Indetermine + ) }) test("une démarche d'octroi sans étape décisive a le statut “indéfini”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, - etapesBuild([{ typeId: ETAPES_TYPES.avisDeMiseEnConcurrenceAuJORF }], DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.avisDeMiseEnConcurrenceAuJORF }], DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX) ) ).toEqual(DemarchesStatutsIds.Indetermine) }) @@ -47,7 +49,7 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi dont l'étape de dpu la plus récente est acceptée a le statut “accepté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild( [ { typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.ACCEPTE }, @@ -55,9 +57,7 @@ describe("statut d'une démarche", () => { ], DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX - ), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + ) ) ).toEqual(DemarchesStatutsIds.Accepte) }) @@ -65,14 +65,12 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi d'un titre AXM dont l'étape de dex la plus récente est acceptée a le statut “accepté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild( [{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, date: toCaminoDate('2010-01-01'), statutId: ETAPES_STATUTS.ACCEPTE }], DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX - ), - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - newDemarcheId() + ) ) ).toEqual(DemarchesStatutsIds.Accepte) }) @@ -80,16 +78,14 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi d'un titre ARM dont l'étape de def la plus récente est acceptée a le statut “accepté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild([ { typeId: ETAPES_TYPES.decisionDeLOfficeNationalDesForets, statutId: ETAPES_STATUTS.ACCEPTE, date: toCaminoDate('2010-01-01'), }, - ]), - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - newDemarcheId() + ]) ) ).toEqual(DemarchesStatutsIds.Accepte) }) @@ -97,14 +93,12 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi d'un titre PRM dont l'étape de rpu la plus récente est acceptée a le statut “accepté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild( [{ typeId: ETAPES_TYPES.publicationDeDecisionAuRecueilDesActesAdministratifs, date: toCaminoDate('2010-01-01'), statutId: ETAPES_STATUTS.ACCEPTE }], DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX - ), - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, - newDemarcheId() + ) ) ).toEqual(DemarchesStatutsIds.Accepte) }) @@ -112,13 +106,11 @@ describe("statut d'une démarche", () => { test("une démarche de prolongation dont l'étape de dpu la plus récente est acceptée a le statut “accepté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Prolongation, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Prolongation, newDemarcheId(), null), etapesBuild([ { typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.ACCEPTE }, { typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: ETAPES_STATUTS.ACCEPTE }, - ]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + ]) ) ).toEqual(DemarchesStatutsIds.Accepte) }) @@ -126,7 +118,7 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi dont l'étape de sco est faite a le statut “accepté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild([ { typeId: ETAPES_TYPES.demande, @@ -153,23 +145,19 @@ describe("statut d'une démarche", () => { { typeId: ETAPES_TYPES.paiementDesFraisDeDossierComplementaires, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-07-16') }, { typeId: ETAPES_TYPES.validationDuPaiementDesFraisDeDossierComplementaires, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-07-17') }, { typeId: ETAPES_TYPES.signatureDeLautorisationDeRechercheMiniere, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2020-09-28') }, - ]), - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - newDemarcheId() + ]) ) ).toEqual(DemarchesStatutsIds.Accepte) expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild([ { typeId: ETAPES_TYPES.signatureDeLautorisationDeRechercheMiniere, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2010-09-28'), }, - ]), - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - newDemarcheId() + ]) ) ).toEqual(DemarchesStatutsIds.Accepte) }) @@ -177,10 +165,8 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi d'un titre autre qu'ARM dont l'étape de sco est faite a le statut “indéfini”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, - etapesBuild([{ typeId: ETAPES_TYPES.signatureDeLautorisationDeRechercheMiniere, statutId: ETAPES_STATUTS.FAIT }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.signatureDeLautorisationDeRechercheMiniere, statutId: ETAPES_STATUTS.FAIT }]) ) ).toEqual(DemarchesStatutsIds.Indetermine) }) @@ -188,10 +174,8 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi ne contenant une unique étape de dex acceptée a le statut “en instruction”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, - etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.ACCEPTE }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.ACCEPTE }]) ) ).toEqual(DemarchesStatutsIds.EnInstruction) }) @@ -199,13 +183,11 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi contenant une étape de publication acceptée après une dex acceptée a le statut “accepté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild([ { typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.ACCEPTE }, { typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: ETAPES_STATUTS.ACCEPTE }, - ]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + ]) ) ).toEqual(DemarchesStatutsIds.Accepte) }) @@ -213,24 +195,25 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi dont l'unique étape de dex est rejetée a le statut “rejeté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, - etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.REJETE }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: ETAPES_STATUTS.REJETE }]) ) ).toEqual(DemarchesStatutsIds.Rejete) }) test("une démarche d'octroi dont l'étape est men a le statut “déposé”", () => { expect( - titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.Octroi, etapesBuild([{ typeId: ETAPES_TYPES.enregistrementDeLaDemande }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId()) + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.enregistrementDeLaDemande }]) + ) ).toEqual(DemarchesStatutsIds.Depose) }) test("une démarche d'octroi d'un titre ARM dont l'étape de men (statut fai) a le statut “en instruction”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild( [ { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT }, @@ -238,9 +221,7 @@ describe("statut d'une démarche", () => { ], DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX - ), - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - newDemarcheId() + ) ) ).toEqual(DemarchesStatutsIds.EnInstruction) }) @@ -248,15 +229,13 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi d'un titre ARM dont l'étape de mcp a le statut “en instruction”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild([ { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT }, { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT }, { typeId: ETAPES_TYPES.paiementDesFraisDeDossier, statutId: ETAPES_STATUTS.FAIT }, { typeId: ETAPES_TYPES.completudeDeLaDemande, statutId: ETAPES_STATUTS.COMPLETE }, - ]), - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - newDemarcheId() + ]) ) ).toEqual(DemarchesStatutsIds.EnInstruction) }) @@ -264,16 +243,14 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi d'un titre ARM dont la dernière étape de def est acceptée a le statut “accepté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild([ { typeId: ETAPES_TYPES.decisionDeLOfficeNationalDesForets, statutId: ETAPES_STATUTS.ACCEPTE, date: toCaminoDate('2010-01-01'), }, - ]), - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - newDemarcheId() + ]) ) ).toEqual(DemarchesStatutsIds.Accepte) }) @@ -281,16 +258,14 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi d'un titre ARM dont la dernière étape de def est rejetée a le statut “rejeté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild([ { typeId: ETAPES_TYPES.decisionDeLOfficeNationalDesForets, statutId: ETAPES_STATUTS.REJETE, date: toCaminoDate('2010-01-12'), }, - ]), - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - newDemarcheId() + ]) ) ).toEqual(DemarchesStatutsIds.Rejete) }) @@ -298,47 +273,52 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi d'un titre autre qu'ARM dont la dernière étape est une def a le statut “indéfini”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, - etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLOfficeNationalDesForets, statutId: ETAPES_STATUTS.REJETE }]), - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_HYDROCARBURE, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_HYDROCARBURE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.decisionDeLOfficeNationalDesForets, statutId: ETAPES_STATUTS.REJETE }]) ) ).toEqual(DemarchesStatutsIds.Indetermine) }) test("une démarche d'octroi dont l'étape la plus récente est des a le statut “désisté”", () => { expect( - titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.Octroi, etapesBuild([{ typeId: ETAPES_TYPES.desistementDuDemandeur }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId()) + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.desistementDuDemandeur }]) + ) ).toEqual(DemarchesStatutsIds.Desiste) }) test("une démarche d'octroi dont l'étape la plus récente est mfr a le statut “en construction”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, - etapesBuild([{ typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, isBrouillon: ETAPE_IS_BROUILLON }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, isBrouillon: ETAPE_IS_BROUILLON }]) ) ).toEqual(DemarchesStatutsIds.EnConstruction) }) test("une démarche d'octroi dont l'étape la plus récente est mcr a le statut “en instruction”", () => { expect( - titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.Octroi, etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId()) + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.recevabiliteDeLaDemande }]) + ) ).toEqual(DemarchesStatutsIds.EnInstruction) }) test("une démarche d'octroi dont l'étape la plus récente est css a le statut “classé sans suite”", () => { - expect(titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.Octroi, etapesBuild([{ typeId: ETAPES_TYPES.classementSansSuite }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId())).toEqual( - DemarchesStatutsIds.ClasseSansSuite - ) + expect( + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.classementSansSuite }]) + ) + ).toEqual(DemarchesStatutsIds.ClasseSansSuite) }) test("une démarche d'octroi dont l'étape la plus récente d'aca est défavorable a le statut “rejeté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild([ { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2021-02-25') }, { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2021-02-26') }, @@ -349,9 +329,7 @@ describe("statut d'une démarche", () => { { typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2021-09-23') }, { typeId: ETAPES_TYPES.saisineDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2021-09-24') }, { typeId: ETAPES_TYPES.avisDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_, statutId: ETAPES_STATUTS.DEFAVORABLE, date: toCaminoDate('2021-09-25') }, - ]), - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - newDemarcheId() + ]) ) ).toEqual(DemarchesStatutsIds.Rejete) }) @@ -359,7 +337,7 @@ describe("statut d'une démarche", () => { test("une démarche d'octroi dont l'étape la plus récente d'aca est favorable reste “en instruction”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), etapesBuild([ { typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2021-02-25') }, { typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2021-02-26') }, @@ -370,43 +348,43 @@ describe("statut d'une démarche", () => { { typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2021-09-23') }, { typeId: ETAPES_TYPES.saisineDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_, statutId: ETAPES_STATUTS.FAIT, date: toCaminoDate('2021-09-24') }, { typeId: ETAPES_TYPES.avisDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_, statutId: ETAPES_STATUTS.FAVORABLE, date: toCaminoDate('2021-09-25') }, - ]), - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - newDemarcheId() + ]) ) ).toEqual(DemarchesStatutsIds.EnInstruction) }) test('une démarche de retrait sans aucune étape décisive a le statut “indéterminé”', () => { expect( - titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.Retrait, etapesBuild([{ typeId: ETAPES_TYPES.informationsHistoriquesIncompletes }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId()) + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Retrait, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.informationsHistoriquesIncompletes }]) + ) ).toEqual(DemarchesStatutsIds.Indetermine) }) test("une démarche de retrait dont l'étape la plus récente de dpu a été faite a le statut “terminé”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Retrait, - etapesBuild([{ typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: ETAPES_STATUTS.FAIT }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Retrait, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: ETAPES_STATUTS.FAIT }]) ) ).toEqual(DemarchesStatutsIds.Termine) }) test("une démarche de retrait dont l'étape la plus récente est spp a le statut “en instruction”", () => { - expect(titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.Retrait, etapesBuild([{ typeId: ETAPES_TYPES.saisineDuPrefet }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId())).toEqual( - DemarchesStatutsIds.EnInstruction - ) + expect( + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Retrait, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.saisineDuPrefet }]) + ) + ).toEqual(DemarchesStatutsIds.EnInstruction) }) test("une démarche de retrait dont l'étape la plus récente est asc a le statut “en instruction”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Retrait, - etapesBuild([{ typeId: ETAPES_TYPES.saisineDuPrefet }, { typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Retrait, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.saisineDuPrefet }, { typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives }]) ) ).toEqual(DemarchesStatutsIds.EnInstruction) }) @@ -414,39 +392,44 @@ describe("statut d'une démarche", () => { test("une démarche de retrait dont l'étape la plus récente est aco a le statut “terminé”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Retrait, - etapesBuild([{ typeId: ETAPES_TYPES.avenantALautorisationDeRechercheMiniere }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Retrait, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.avenantALautorisationDeRechercheMiniere }]) ) ).toEqual(DemarchesStatutsIds.Termine) }) test("une démarche de retrait dont l'étape la plus récente de css a été faite a le statut “classé sans suite”", () => { - expect(titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.Retrait, etapesBuild([{ typeId: ETAPES_TYPES.classementSansSuite }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId())).toEqual( - DemarchesStatutsIds.ClasseSansSuite - ) + expect( + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Retrait, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.classementSansSuite }]) + ) + ).toEqual(DemarchesStatutsIds.ClasseSansSuite) }) test("une démarche de demande dont l'étape la plus récente est spp ne change pas de statut", () => { - expect(titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.Octroi, etapesBuild([{ typeId: ETAPES_TYPES.saisineDuPrefet }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId())).toEqual( - DemarchesStatutsIds.Indetermine - ) + expect( + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.saisineDuPrefet }]) + ) + ).toEqual(DemarchesStatutsIds.Indetermine) }) test("une démarche dont l'étape la plus récente est de type “abrogation de la décision” a le statut “en instruction”", () => { expect( - titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.Octroi, etapesBuild([{ typeId: ETAPES_TYPES.abrogationDeLaDecision }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId()) + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.abrogationDeLaDecision }]) + ) ).toEqual(DemarchesStatutsIds.EnInstruction) }) test("une démarche dont l'étape la plus récente d'annulation de la décision est favorable a le statut “en instruction”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, - etapesBuild([{ typeId: ETAPES_TYPES.decisionDuJugeAdministratif, statutId: ETAPES_STATUTS.FAIT }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.decisionDuJugeAdministratif, statutId: ETAPES_STATUTS.FAIT }]) ) ).toEqual(DemarchesStatutsIds.EnInstruction) }) @@ -454,10 +437,8 @@ describe("statut d'une démarche", () => { test("une démarche dont l'étape la plus récente d'annulation de la décision est favorable a le statut “accepté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, - etapesBuild([{ typeId: ETAPES_TYPES.decisionDuJugeAdministratif, statutId: ETAPES_STATUTS.ACCEPTE }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.decisionDuJugeAdministratif, statutId: ETAPES_STATUTS.ACCEPTE }]) ) ).toEqual(DemarchesStatutsIds.Accepte) }) @@ -465,10 +446,8 @@ describe("statut d'une démarche", () => { test("une démarche dont l'étape la plus récente d'annulation de la décision est favorable a le statut “rejeté”", () => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.Octroi, - etapesBuild([{ typeId: ETAPES_TYPES.decisionDuJugeAdministratif, statutId: ETAPES_STATUTS.REJETE }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.decisionDuJugeAdministratif, statutId: ETAPES_STATUTS.REJETE }]) ) ).toEqual(DemarchesStatutsIds.Rejete) }) @@ -477,10 +456,8 @@ describe("statut d'une démarche", () => { expect( titreDemarcheStatutIdFind( // @ts-ignore - 'xxx', - etapesBuild([{ typeId: ETAPES_TYPES.demande }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, 'xxx', newDemarcheId(), null), + etapesBuild([{ typeId: ETAPES_TYPES.demande }]) ) ).toEqual(DemarchesStatutsIds.Indetermine) }) @@ -504,7 +481,10 @@ describe("statut d'une démarche", () => { [Travaux.DesistementDuDemandeur, ETAPES_STATUTS.FAIT, Demarches.Desiste], ])("pour une démarche de travaux de type 'AutorisationDOuvertureDeTravaux' sur un titre, dont la dernière étape est '%s' au statut %s, le résultat est %s", (etapeTypeId, statutId, resultId) => { expect( - titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.AutorisationDOuvertureDeTravaux, etapesBuild([{ typeId: etapeTypeId, statutId }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId()) + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.AutorisationDOuvertureDeTravaux, newDemarcheId(), null), + etapesBuild([{ typeId: etapeTypeId, statutId }]) + ) ).toEqual(resultId) }) @@ -523,7 +503,10 @@ describe("statut d'une démarche", () => { [Travaux.DesistementDuDemandeur, ETAPES_STATUTS.FAIT, Demarches.Desiste], ])("pour une démarche de travaux de type 'DeclarationDOuvertureDeTravaux' sur un titre, dont la dernière étape est '%s' au statut %s, le résultat est %s", (etapeTypeId, statutId, resultId) => { expect( - titreDemarcheStatutIdFind(DEMARCHES_TYPES_IDS.DeclarationDOuvertureDeTravaux, etapesBuild([{ typeId: etapeTypeId, statutId }]), TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, newDemarcheId()) + titreDemarcheStatutIdFind( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.DeclarationDOuvertureDeTravaux, newDemarcheId(), null), + etapesBuild([{ typeId: etapeTypeId, statutId }]) + ) ).toEqual(resultId) }) @@ -550,10 +533,8 @@ describe("statut d'une démarche", () => { (etapeTypeId, statutId, resultId) => { expect( titreDemarcheStatutIdFind( - DEMARCHES_TYPES_IDS.DeclarationDArretDefinitifDesTravaux, - etapesBuild([{ typeId: etapeTypeId, statutId }]), - TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, - newDemarcheId() + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.DeclarationDArretDefinitifDesTravaux, newDemarcheId(), null), + etapesBuild([{ typeId: etapeTypeId, statutId }]) ) ).toEqual(resultId) } diff --git a/packages/api/src/business/rules/titre-demarche-statut-id-find.ts b/packages/api/src/business/rules/titre-demarche-statut-id-find.ts index d3fe4ce2acffbd09c8bcd3ea5dc0cda3a232c68f..1ae0b2a1779b6fc7effdd5358ba8706fe52d3eff 100644 --- a/packages/api/src/business/rules/titre-demarche-statut-id-find.ts +++ b/packages/api/src/business/rules/titre-demarche-statut-id-find.ts @@ -1,5 +1,4 @@ import { ITitreEtape, TitreEtapesTravauxTypes as Travaux } from '../../types' -import { demarcheEnregistrementDemandeDateFind, DemarcheId } from 'camino-common/src/demarche' import { titreEtapesSortDescByOrdre } from '../utils/titre-etapes-sort' import { titreEtapePublicationCheck } from './titre-etape-publication-check' @@ -10,7 +9,8 @@ import { DemarcheTypeId, TravauxIds } from 'camino-common/src/static/demarchesTy import { ETAPES_TYPES, EtapeTypeId } from 'camino-common/src/static/etapesTypes' import { ETAPES_STATUTS, isEtapeStatusRejete } from 'camino-common/src/static/etapesStatuts' import { exhaustiveCheck, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, RecordPartial } from 'camino-common/src/typescript-tools' -import { machineFind } from '../rules-demarches/machines' +import { MachineInfo } from 'camino-common/src/machines' +import { ApiMachineInfo } from '../rules-demarches/machines' const titreEtapesDecisivesCommunesTypes = ['css', 'abd', 'and'] as const satisfies EtapeTypeId[] @@ -318,29 +318,20 @@ const titreDemarcheTravauxStatutIdFind = (titreDemarcheEtapes: Pick<ITitreEtape, return statuts[titreEtapesRecent.typeId] ?? DemarchesStatutsIds.Indetermine } -/** - * Retourne l'id du statut d'une démarche - * @param demarcheTypeId - id du type de la démarche - * @param titreDemarcheEtapes - étapes de la démarche - * @param titreTypeId - id du type de titre - */ - -export const titreDemarcheStatutIdFind = (demarcheTypeId: DemarcheTypeId, titreDemarcheEtapes: TitreEtapeForMachine[], titreTypeId: TitreTypeId, demarcheId: DemarcheId): DemarcheStatutId => { +export const titreDemarcheStatutIdFind = (machineInfo: MachineInfo, titreDemarcheEtapes: TitreEtapeForMachine[]): DemarcheStatutId => { // si la démarche ne contient pas d'étapes // -> le statut est indétrminé if (!isNotNullNorUndefinedNorEmpty(titreDemarcheEtapes)) return DemarchesStatutsIds.Indetermine // si la démarche est pour des travaux - if (titreDemarchesTravauxTypes.includes(demarcheTypeId)) { - return titreDemarcheTravauxStatutIdFind(titreDemarcheEtapes, demarcheTypeId) + if (titreDemarchesTravauxTypes.includes(machineInfo.demarcheTypeId)) { + return titreDemarcheTravauxStatutIdFind(titreDemarcheEtapes, machineInfo.demarcheTypeId) } - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(titreDemarcheEtapes) - - const machine = machineFind(titreTypeId, demarcheTypeId, demarcheId, firstEtapeDate) + const machine = new ApiMachineInfo(machineInfo) - if (isNotNullNorUndefined(machine)) { - return machine.demarcheStatut(toMachineEtapes(titreDemarcheEtapes)).demarcheStatut + if (isNotNullNorUndefined(machine.machine)) { + return machine.machine.demarcheStatut(toMachineEtapes(titreDemarcheEtapes)).demarcheStatut } // si la démarche fait l’objet d’une demande @@ -349,13 +340,13 @@ export const titreDemarcheStatutIdFind = (demarcheTypeId: DemarcheTypeId, titreD // - renonciation ou fusion (native ou virtuelle) ou extension du périmètre // - extension de substance ou mutation (native ou virtuelle) ou amodiation // - résiliation d’amodiation ou déplacement de périmètre) - if (titreDemarchesDemandesTypes.includes(demarcheTypeId)) { - return titreDemarcheDemandeStatutIdFind(titreDemarcheEtapes, titreTypeId) + if (titreDemarchesDemandesTypes.includes(machineInfo.demarcheTypeId)) { + return titreDemarcheDemandeStatutIdFind(titreDemarcheEtapes, machineInfo.titreTypeId) } // si la démarche ne fait pas l’objet d’une demande (unilatérale) // (son type est retrait ou abrogation ou prorogation) - else if (titreDemarchesUnilateralesTypes.includes(demarcheTypeId)) { + else if (titreDemarchesUnilateralesTypes.includes(machineInfo.demarcheTypeId)) { return titreDemarcheUnilateralStatutIdFind(titreDemarcheEtapes) } diff --git a/packages/api/src/business/rules/titre-etape-prop-find.test.ts b/packages/api/src/business/rules/titre-etape-prop-find.test.ts index 68295cf981a177defbbe7331797ca7d492057e44..384386b5c09230e906f37c5013b61356c1bc38c0 100644 --- a/packages/api/src/business/rules/titre-etape-prop-find.test.ts +++ b/packages/api/src/business/rules/titre-etape-prop-find.test.ts @@ -2,12 +2,16 @@ import { ITitreDemarche } from '../../types' import { titreEtapePropFind } from './titre-etape-prop-find' import { vi, describe, expect, test } from 'vitest' -import { toCaminoDate } from 'camino-common/src/date' +import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { ETAPE_IS_NOT_BROUILLON, etapeIdValidator } from 'camino-common/src/etape' import { titreIdValidator } from 'camino-common/src/validators/titres' import { demarcheIdValidator } from 'camino-common/src/demarche' import { ZERO_KM2 } from 'camino-common/src/number' import { newEntrepriseId } from 'camino-common/src/entreprise' +import { MachineInfo } from 'camino-common/src/machines' +import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' +import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' +import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' console.error = vi.fn() describe("valeur d'une propriété pour une étape", () => { @@ -31,12 +35,13 @@ describe("valeur d'une propriété pour une étape", () => { { id: demarcheId, titreId: titreIdValidator.parse('titreId'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('1000-01-01')).machineId ?? null, etapes: [ { id: etapeIdValidator.parse('demarche-01-etape-01'), titreDemarcheId: demarcheId, - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, statutId: 'fai', isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1000-01-01'), @@ -51,7 +56,7 @@ describe("valeur d'une propriété pour une étape", () => { { id: etapeIdValidator.parse('demarche-01-etape-02'), titreDemarcheId: demarcheId, - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, statutId: 'fai', isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1000-01-01'), @@ -66,7 +71,7 @@ describe("valeur d'une propriété pour une étape", () => { ], }, ], - 'pxm' + TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX ) ).toEqual(['fr-xxxxxxxxx']) }) @@ -81,12 +86,15 @@ describe("valeur d'une propriété pour une étape", () => { id: demarcheIdValidator.parse('demarche-01'), titreId: titreIdValidator.parse('titreId'), statutId: 'acc', - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarche-01'), firstEtapeDateValidator.parse('1000-01-01')) + .machineId ?? null, etapes: [ { id: etapeIdValidator.parse('demarche-01-etape-01'), titreDemarcheId: demarcheIdValidator.parse('demarche-01'), - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, statutId: 'fai', isBrouillon: ETAPE_IS_NOT_BROUILLON, surface: ZERO_KM2, @@ -103,13 +111,16 @@ describe("valeur d'une propriété pour une étape", () => { id: demarcheIdValidator.parse('demarche-02'), titreId: titreIdValidator.parse('titreId'), statutId: 'acc', - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarche-02'), firstEtapeDateValidator.parse('1000-01-01')) + .machineId ?? null, etapes: [ { id: etapeIdValidator.parse('demarche-02-etape-01'), titreDemarcheId: demarcheIdValidator.parse('demarche-02'), date: toCaminoDate('1000-01-01'), - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, statutId: 'fai', isBrouillon: ETAPE_IS_NOT_BROUILLON, surface: ZERO_KM2, @@ -122,7 +133,7 @@ describe("valeur d'une propriété pour une étape", () => { ], }, ], - 'pxm' + TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX ) ).toEqual(0) }) @@ -136,7 +147,10 @@ describe("valeur d'une propriété pour une étape", () => { { id: demarcheIdValidator.parse('demarche-01'), titreId: titreIdValidator.parse('titreId'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarche-01'), firstEtapeDateValidator.parse('1000-01-01')) + .machineId ?? null, etapes: [ { id: etapeIdValidator.parse('demarche-02-etape-01'), @@ -145,7 +159,7 @@ describe("valeur d'une propriété pour une étape", () => { statutId: 'fai', isBrouillon: ETAPE_IS_NOT_BROUILLON, titulaireIds: null, - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, surface: ZERO_KM2, ordre: 1, communes: null, @@ -156,7 +170,7 @@ describe("valeur d'une propriété pour une étape", () => { ], }, ], - 'pxm' + TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX ) ).toBeNull() }) diff --git a/packages/api/src/business/rules/titre-phases-find.test.ts b/packages/api/src/business/rules/titre-phases-find.test.ts index 564ccab51b5328dcca04e9dd661c3df7e72ef9ae..7df228e692d278983be35c3c10c50db0d41903ef 100644 --- a/packages/api/src/business/rules/titre-phases-find.test.ts +++ b/packages/api/src/business/rules/titre-phases-find.test.ts @@ -3,17 +3,18 @@ import { demarcheSlugValidator } from 'camino-common/src/demarche' import { titrePhasesFind, TitreDemarchePhaseFind } from './titre-phases-find' import { newDemarcheId, newEtapeId, newTitreId } from '../../database/models/_format/id-create' -import { toCaminoDate } from 'camino-common/src/date' +import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { describe, expect, test } from 'vitest' import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' import { DemarchesStatutsIds } from 'camino-common/src/static/demarchesStatuts' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' +import { TITRES_TYPES_IDS, TitreTypeId } from 'camino-common/src/static/titresTypes' import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' import { ETAPE_IS_BROUILLON, ETAPE_IS_NOT_BROUILLON, etapeSlugValidator } from 'camino-common/src/etape' import { FeatureMultiPolygon } from 'camino-common/src/perimetre' import { km2Validator } from 'camino-common/src/number' import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' +import { MachineInfo } from 'camino-common/src/machines' export type TitrePhasesTest = [TitreTypeId, TitreDemarchePhaseFind[]] const multiPolygonWith4Points: FeatureMultiPolygon = { @@ -43,6 +44,9 @@ describe("phases d'une démarche", () => { titreId: newTitreId('titreid'), id: newDemarcheId('demarcheId'), typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheId'), firstEtapeDateValidator.parse('2000-01-01')) + .machineId ?? null, statutId: DemarchesStatutsIds.Rejete, etapes: [ { @@ -68,7 +72,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'prr' + TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF ) ).toEqual({}) }) @@ -80,11 +84,14 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreid'), id: newDemarcheId('h-cx-courdemanges-1988-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('h-cx-courdemanges-1988-oct01'), firstEtapeDateValidator.parse('2000-01-01')) + .machineId ?? null, statutId: 'acc', etapes: [ { - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -94,7 +101,7 @@ describe("phases d'une démarche", () => { demarcheIdsConsentement: [], }, { - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -106,7 +113,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'cxh' + TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE ) ).toEqual({ 'h-cx-courdemanges-1988-oct01': { @@ -123,12 +130,13 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreId'), id: newDemarcheId('h-cx-courdemanges-1988-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: 'ProcedureSimplifiee', statutId: 'acc', etapes: [], }, ], - 'cxh' + TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE ) ).toEqual({}) }) @@ -140,11 +148,18 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreId'), id: newDemarcheId('h-ax-courdemanges-1988-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate( + TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_GEOTHERMIE, + DEMARCHES_TYPES_IDS.Octroi, + newDemarcheId('h-ax-courdemanges-1988-oct01'), + firstEtapeDateValidator.parse('2200-01-01') + ).machineId ?? null, statutId: 'acc', etapes: [ { - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -156,7 +171,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'pxg' + TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_GEOTHERMIE ) ).toEqual({ 'h-ax-courdemanges-1988-oct01': { @@ -173,11 +188,18 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreId'), id: newDemarcheId('m-pr-courdemanges-1988-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate( + TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + newDemarcheId('m-pr-courdemanges-1988-oct01'), + firstEtapeDateValidator.parse('1999-01-01') + ).machineId ?? null, statutId: 'acc', etapes: [ { - typeId: 'rpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuRecueilDesActesAdministratifs, statutId: 'fai', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -189,7 +211,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'prm' + TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX ) ).toEqual({ 'm-pr-courdemanges-1988-oct01': { @@ -206,11 +228,14 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreId'), id: newDemarcheId('h-cx-courdemanges-1988-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('h-cx-courdemanges-1988-oct01'), firstEtapeDateValidator.parse('2200-01-01')) + .machineId ?? null, statutId: 'acc', etapes: [ { - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -221,7 +246,7 @@ describe("phases d'une démarche", () => { demarcheIdsConsentement: [], }, { - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -234,7 +259,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'cxh' + TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE ) ).toEqual({ 'h-cx-courdemanges-1988-oct01': { @@ -251,14 +276,17 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreId'), id: newDemarcheId('h-cx-courdemanges-1988-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('h-cx-courdemanges-1988-oct01'), firstEtapeDateValidator.parse('2200-01-01')) + .machineId ?? null, statutId: 'acc', ordre: 1, etapes: [ { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-oct01'), demarcheIdsConsentement: [], - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -268,7 +296,7 @@ describe("phases d'une démarche", () => { { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-oct01'), demarcheIdsConsentement: [], - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -280,14 +308,21 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreId'), id: newDemarcheId('h-cx-courdemanges-1988-pro01'), - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, + machineId: + MachineInfo.withDate( + TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, + DEMARCHES_TYPES_IDS.Prolongation, + newDemarcheId('h-cx-courdemanges-1988-pro01'), + firstEtapeDateValidator.parse('2300-01-01') + ).machineId ?? null, statutId: 'acc', ordre: 2, etapes: [ { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-pro01'), demarcheIdsConsentement: [], - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -297,7 +332,7 @@ describe("phases d'une démarche", () => { { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-pro01'), demarcheIdsConsentement: [], - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -307,7 +342,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'cxh' + TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE ) ).toEqual({ 'h-cx-courdemanges-1988-oct01': { @@ -328,14 +363,17 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreId'), id: newDemarcheId('h-cx-courdemanges-1988-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('h-cx-courdemanges-1988-oct01'), firstEtapeDateValidator.parse('2000-01-01')) + .machineId ?? null, statutId: 'acc', ordre: 1, etapes: [ { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-oct01'), demarcheIdsConsentement: [], - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -345,7 +383,7 @@ describe("phases d'une démarche", () => { { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-oct01'), demarcheIdsConsentement: [], - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -357,14 +395,21 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreId'), id: newDemarcheId('h-cx-courdemanges-1988-ren01'), - typeId: 'rec', + typeId: DEMARCHES_TYPES_IDS.RenonciationTotale, + machineId: + MachineInfo.withDate( + TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, + DEMARCHES_TYPES_IDS.RenonciationTotale, + newDemarcheId('h-cx-courdemanges-1988-ren01'), + firstEtapeDateValidator.parse('2019-01-02') + ).machineId ?? null, statutId: 'acc', ordre: 2, etapes: [ { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-ren01'), demarcheIdsConsentement: [], - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -373,7 +418,7 @@ describe("phases d'une démarche", () => { { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-ren01'), demarcheIdsConsentement: [], - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'fai', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -382,7 +427,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'cxh' + TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE ) ).toEqual({ 'h-cx-courdemanges-1988-oct01': { @@ -399,14 +444,17 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreId'), id: newDemarcheId('h-cx-courdemanges-1988-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('h-cx-courdemanges-1988-oct01'), firstEtapeDateValidator.parse('2000-01-01')) + .machineId ?? null, statutId: 'acc', ordre: 1, etapes: [ { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-oct01'), demarcheIdsConsentement: [], - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -416,7 +464,7 @@ describe("phases d'une démarche", () => { { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-oct01'), demarcheIdsConsentement: [], - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -428,14 +476,21 @@ describe("phases d'une démarche", () => { { titreId: newTitreId('titreId'), id: newDemarcheId('h-cx-courdemanges-1988-ren01'), - typeId: 'rep', + typeId: DEMARCHES_TYPES_IDS.RenonciationPartielle, + machineId: + MachineInfo.withDate( + TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, + DEMARCHES_TYPES_IDS.RenonciationPartielle, + newDemarcheId('h-cx-courdemanges-1988-ren01'), + firstEtapeDateValidator.parse('2019-01-02') + ).machineId ?? null, statutId: 'acc', ordre: 2, etapes: [ { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-ren01'), demarcheIdsConsentement: [], - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -444,7 +499,7 @@ describe("phases d'une démarche", () => { { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-ren01'), demarcheIdsConsentement: [], - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -454,7 +509,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'cxh' + TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE ) ).toEqual({ 'h-cx-courdemanges-1988-oct01': { @@ -482,7 +537,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheId1, ordre: 11, - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Mutation, demarcheId1, firstEtapeDateValidator.parse('2016-12-28')).machineId ?? null, statutId: 'cls', etapes: [ { @@ -493,7 +549,7 @@ describe("phases d'une démarche", () => { date: toCaminoDate('2016-12-28'), duree: 1920, surface: km2Validator.parse(5.51), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -505,7 +561,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2016-12-28'), - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -517,7 +573,7 @@ describe("phases d'une démarche", () => { ordre: 3, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2017-04-07'), - typeId: 'css', + typeId: ETAPES_TYPES.classementSansSuite, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -529,7 +585,8 @@ describe("phases d'une démarche", () => { id: demarcheId2, titreId, ordre: 10, - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheId2, firstEtapeDateValidator.parse('2016-12-28')).machineId ?? null, statutId: 'cls', etapes: [ { @@ -540,7 +597,7 @@ describe("phases d'une démarche", () => { date: toCaminoDate('2016-12-28'), duree: 1920, surface: km2Validator.parse(5.51), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -552,7 +609,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2016-12-28'), - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -564,7 +621,7 @@ describe("phases d'une démarche", () => { ordre: 3, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2017-04-07'), - typeId: 'css', + typeId: ETAPES_TYPES.classementSansSuite, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -576,7 +633,10 @@ describe("phases d'une démarche", () => { titreId, id: demarcheId3, ordre: 9, - typeId: 'dam', + typeId: DEMARCHES_TYPES_IDS.DeclarationDArretDefinitifDesTravaux, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.DeclarationDArretDefinitifDesTravaux, demarcheId3, firstEtapeDateValidator.parse('2013-08-01')).machineId ?? + null, statutId: 'ins', etapes: [ { @@ -585,7 +645,7 @@ describe("phases d'une démarche", () => { ordre: 3, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2014-12-23'), - typeId: 'wpp', + typeId: ETAPES_TYPES.arretePrefectoralDePremierDonnerActe_DADT_, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -597,7 +657,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2013-08-01'), - typeId: 'wfd', + typeId: ETAPES_TYPES.declarationDarretDefinitifDeTravaux_DADT_, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -621,7 +681,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheId4, ordre: 8, - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Mutation, demarcheId4, firstEtapeDateValidator.parse('2002-12-24')).machineId ?? null, statutId: 'acc', etapes: [ { @@ -630,7 +691,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2002-12-24'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -642,7 +703,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2003-01-08'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -654,7 +715,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheId5, ordre: 7, - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Mutation, demarcheId5, firstEtapeDateValidator.parse('2000-09-26')).machineId ?? null, statutId: 'acc', etapes: [ { @@ -663,7 +725,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2000-09-26'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -675,7 +737,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2000-10-06'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -687,7 +749,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheId6, ordre: 6, - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Mutation, demarcheId6, firstEtapeDateValidator.parse('1975-11-24')).machineId ?? null, statutId: 'acc', etapes: [ { @@ -696,7 +759,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1975-11-24'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -708,7 +771,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1975-11-27'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -720,8 +783,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheId7, ordre: 5, - typeId: 'mut', - + typeId: DEMARCHES_TYPES_IDS.Mutation, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Mutation, demarcheId7, firstEtapeDateValidator.parse('1970-11-16')).machineId ?? null, statutId: 'acc', etapes: [ { @@ -730,7 +793,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1970-11-16'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -742,7 +805,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1970-11-19'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -754,7 +817,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheId8, ordre: 4, - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Mutation, demarcheId8, firstEtapeDateValidator.parse('1949-08-23')).machineId ?? null, statutId: 'acc', etapes: [ { @@ -763,7 +827,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1949-08-31'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -775,7 +839,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1949-08-23'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -787,7 +851,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheId9, ordre: 3, - typeId: 'exp', + typeId: DEMARCHES_TYPES_IDS.ExtensionDePerimetre, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.ExtensionDePerimetre, demarcheId9, firstEtapeDateValidator.parse('1889-02-27')).machineId ?? null, statutId: 'acc', etapes: [ { @@ -796,7 +861,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1889-02-27'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -808,7 +873,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1889-02-27'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -820,7 +885,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheId10, ordre: 2, - typeId: 'exp', + typeId: DEMARCHES_TYPES_IDS.ExtensionDePerimetre, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.ExtensionDePerimetre, demarcheId10, firstEtapeDateValidator.parse('1879-07-26')).machineId ?? null, statutId: 'acc', etapes: [ { @@ -829,7 +895,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1879-11-14'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -841,7 +907,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1879-07-26'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -853,7 +919,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheId11, ordre: 1, - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId11, firstEtapeDateValidator.parse('1858-03-24')).machineId ?? null, statutId: 'acc', etapes: [ { @@ -862,7 +929,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1858-03-24'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -874,7 +941,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1858-03-24'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -884,7 +951,7 @@ describe("phases d'une démarche", () => { }, ] - const tested = titrePhasesFind(demarches, 'cxm') + const tested = titrePhasesFind(demarches, TITRES_TYPES_IDS.CONCESSION_METAUX) expect(tested).toStrictEqual({ [newDemarcheId('demarcheId11')]: { dateDebut: '1858-03-24', @@ -902,7 +969,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheIdProlongation, ordre: 11, - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheIdProlongation, firstEtapeDateValidator.parse('2008-12-28')).machineId ?? null, statutId: 'cls', etapes: [ { @@ -911,7 +979,7 @@ describe("phases d'une démarche", () => { ordre: 3, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2011-04-07'), - typeId: 'css', + typeId: ETAPES_TYPES.classementSansSuite, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -923,7 +991,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2008-12-28'), - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -936,7 +1004,7 @@ describe("phases d'une démarche", () => { isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2008-12-28'), duree: 60, - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, statutId: 'fai', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -948,7 +1016,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheIdOctroi, ordre: 1, - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdOctroi, firstEtapeDateValidator.parse('2000-03-24')).machineId ?? null, statutId: 'acc', etapes: [ { @@ -957,7 +1026,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2000-03-24'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', duree: 120, concurrence: 'non-applicable', @@ -970,7 +1039,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2000-03-24'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -980,7 +1049,7 @@ describe("phases d'une démarche", () => { }, ] - const tested = titrePhasesFind(demarches, 'cxm') + const tested = titrePhasesFind(demarches, TITRES_TYPES_IDS.CONCESSION_METAUX) expect(tested).toStrictEqual({ [demarcheIdOctroi]: { dateDebut: '2000-03-24', @@ -1001,7 +1070,8 @@ describe("phases d'une démarche", () => { titreId, id: demarcheIdOctroi, ordre: 1, - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdOctroi, firstEtapeDateValidator.parse('2000-03-24')).machineId ?? null, statutId: 'acc', etapes: [ { @@ -1010,7 +1080,7 @@ describe("phases d'une démarche", () => { ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2000-03-24'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', duree: 120, concurrence: 'non-applicable', @@ -1023,7 +1093,7 @@ describe("phases d'une démarche", () => { ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2000-03-24'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'rej', concurrence: 'non-applicable', hasTitreFrom: 'non-applicable', @@ -1033,7 +1103,7 @@ describe("phases d'une démarche", () => { }, ] - const tested = titrePhasesFind(demarches, 'cxm') + const tested = titrePhasesFind(demarches, TITRES_TYPES_IDS.CONCESSION_METAUX) expect(tested).toStrictEqual({}) }) @@ -1042,14 +1112,15 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId1'), titreId: newTitreId('titreId'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheId1'), firstEtapeDateValidator.parse('1970-09-09')).machineId ?? null, statutId: 'acc', ordre: 1, etapes: [ { id: newEtapeId('demarcheId1etapeId2'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1061,7 +1132,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId1etapeId1'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1075,7 +1146,8 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId2'), titreId: newTitreId('titreId'), - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Mutation, newDemarcheId('demarcheId2'), firstEtapeDateValidator.parse('1994-10-13')).machineId ?? null, statutId: 'acc', ordre: 2, slug: demarcheSlugValidator.parse('m-cx-pontaubert-1970-mut01'), @@ -1083,7 +1155,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId2EtapeId2'), titreDemarcheId: newDemarcheId('demarcheId2'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1097,7 +1169,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId2EtapeId1'), titreDemarcheId: newDemarcheId('demarcheId2'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1112,14 +1184,16 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId3'), titreId: newTitreId('titreId'), - typeId: 'rec', + typeId: DEMARCHES_TYPES_IDS.RenonciationTotale, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.RenonciationTotale, newDemarcheId('demarcheId3'), firstEtapeDateValidator.parse('2019-11-20')).machineId ?? null, statutId: 'acc', ordre: 3, etapes: [ { id: newEtapeId('demarcheId3etapeId1'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, statutId: 'fai', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1131,7 +1205,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId3etapeId2'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: 'fai', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1143,7 +1217,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId3etapeId5'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 5, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1155,7 +1229,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId3etapeId6'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 6, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1167,7 +1241,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId3etapeId3'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'apd', + typeId: ETAPES_TYPES.rapportEtAvisDeLaDREAL, statutId: 'fav', ordre: 3, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1179,7 +1253,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId3etapeId4'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'app', + typeId: ETAPES_TYPES.avisDuPrefet, statutId: 'fav', ordre: 4, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1192,9 +1266,8 @@ describe("phases d'une démarche", () => { ], }, ] - const titreTypeId = 'cxm' - const tested = titrePhasesFind(demarches, titreTypeId) + const tested = titrePhasesFind(demarches, TITRES_TYPES_IDS.CONCESSION_METAUX) expect(tested).toStrictEqual({ [newDemarcheId('demarcheId1')]: { dateDebut: '1970-09-17', @@ -1212,14 +1285,15 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId1'), titreId: newTitreId('titreId'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheId1'), firstEtapeDateValidator.parse('1970-09-09')).machineId ?? null, statutId: 'acc', ordre: 1, etapes: [ { id: newEtapeId('demarcheId1etapeId2'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1231,7 +1305,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId1etapeId1'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1245,14 +1319,15 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId2'), titreId: newTitreId('titreId'), - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Mutation, newDemarcheId('demarcheId2'), firstEtapeDateValidator.parse('1994-10-13')).machineId ?? null, statutId: 'acc', ordre: 2, etapes: [ { id: newEtapeId('demarcheId2EtapeId2'), titreDemarcheId: newDemarcheId('demarcheId2'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1266,7 +1341,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId2EtapeId1'), titreDemarcheId: newDemarcheId('demarcheId2'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1281,14 +1356,16 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId3'), titreId: newTitreId('titreId'), - typeId: 'rec', + typeId: DEMARCHES_TYPES_IDS.RenonciationTotale, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.RenonciationTotale, newDemarcheId('demarcheId3'), firstEtapeDateValidator.parse('2019-11-20')).machineId ?? null, statutId: 'acc', ordre: 3, etapes: [ { id: newEtapeId('demarcheId3etapeId1'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, statutId: 'fai', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1300,7 +1377,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId3etapeId2'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, statutId: 'fai', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1312,7 +1389,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId3etapeId3'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'apd', + typeId: ETAPES_TYPES.rapportEtAvisDeLaDREAL, statutId: 'fav', ordre: 3, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1324,7 +1401,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId3etapeId5'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'aci', ordre: 5, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1336,7 +1413,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId3etapeId4'), titreDemarcheId: newDemarcheId('demarcheId3'), - typeId: 'app', + typeId: ETAPES_TYPES.avisDuPrefet, statutId: 'fav', ordre: 4, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1348,10 +1425,9 @@ describe("phases d'une démarche", () => { ], }, ] - const titreTypeId = 'cxm' // d'un côté on a une dim, de l'autre on a une dex suivie d'une dpu - const tested = titrePhasesFind(demarches, titreTypeId) + const tested = titrePhasesFind(demarches, TITRES_TYPES_IDS.CONCESSION_METAUX) expect(tested).toStrictEqual({ [newDemarcheId('demarcheId1')]: { dateDebut: '1970-09-17', @@ -1369,14 +1445,15 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId1'), titreId: newTitreId('titreId'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheId1'), firstEtapeDateValidator.parse('1968-01-13')).machineId ?? null, statutId: 'acc', ordre: 1, etapes: [ { id: newEtapeId('demarcheId1etapeId2'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1388,7 +1465,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId1etapeId1'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1403,13 +1480,16 @@ describe("phases d'une démarche", () => { id: newDemarcheId('demarcheId2'), titreId: newTitreId('titreId'), typeId: DEMARCHES_TYPES_IDS.ExtensionDePerimetre, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_METAUX, DEMARCHES_TYPES_IDS.ExtensionDePerimetre, newDemarcheId('demarcheId2'), firstEtapeDateValidator.parse('1981-09-09')).machineId ?? + null, statutId: 'acc', ordre: 2, etapes: [ { id: newEtapeId('demarcheId2EtapeId2'), titreDemarcheId: newDemarcheId('demarcheId2'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1422,7 +1502,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId2EtapeId1'), titreDemarcheId: newDemarcheId('demarcheId2'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1434,9 +1514,8 @@ describe("phases d'une démarche", () => { ], }, ] - const titreTypeId = 'cxm' - const tested = titrePhasesFind(demarches, titreTypeId) + const tested = titrePhasesFind(demarches, TITRES_TYPES_IDS.CONCESSION_METAUX) expect(tested).toStrictEqual({ [newDemarcheId('demarcheId1')]: { dateDebut: '1968-01-24', @@ -1453,14 +1532,17 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId1'), titreId: newTitreId('titreId'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheId1'), firstEtapeDateValidator.parse('2017-11-06')) + .machineId ?? null, statutId: 'acc', ordre: 1, etapes: [ { id: newEtapeId('demarcheId1etapeId2'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1473,7 +1555,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId1etapeId1'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1488,13 +1570,20 @@ describe("phases d'une démarche", () => { id: newDemarcheId('demarcheId2'), titreId: newTitreId('titreId'), typeId: DEMARCHES_TYPES_IDS.Prolongation1, + machineId: + MachineInfo.withDate( + TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS, + DEMARCHES_TYPES_IDS.Prolongation1, + newDemarcheId('demarcheId2'), + firstEtapeDateValidator.parse('2023-01-01') + ).machineId ?? null, statutId: DemarchesStatutsIds.Rejete, ordre: 2, etapes: [ { id: newEtapeId('demarcheId2EtapeIdDex'), titreDemarcheId: newDemarcheId('demarcheId2'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'rej', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1507,7 +1596,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId2EtapeIdDpu'), titreDemarcheId: newDemarcheId('demarcheId2'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'fai', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1520,9 +1609,8 @@ describe("phases d'une démarche", () => { ], }, ] - const titreTypeId = 'prw' - const tested = titrePhasesFind(demarches, titreTypeId) + const tested = titrePhasesFind(demarches, TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS) expect(tested).toStrictEqual({ [newDemarcheId('demarcheId1')]: { dateDebut: '2017-11-11', @@ -1539,14 +1627,17 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId1'), titreId: newTitreId('titreId'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheId1'), firstEtapeDateValidator.parse('2017-11-06')) + .machineId ?? null, statutId: 'acc', ordre: 1, etapes: [ { id: newEtapeId('demarcheId1etapeId2'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1559,7 +1650,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId1etapeId1'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1574,13 +1665,20 @@ describe("phases d'une démarche", () => { id: newDemarcheId('demarcheId2'), titreId: newTitreId('titreId'), typeId: DEMARCHES_TYPES_IDS.Prolongation1, + machineId: + MachineInfo.withDate( + TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS, + DEMARCHES_TYPES_IDS.Prolongation1, + newDemarcheId('demarcheId2'), + firstEtapeDateValidator.parse('2022-07-08') + ).machineId ?? null, statutId: DemarchesStatutsIds.EnConstruction, ordre: 2, etapes: [ { id: newEtapeId('demarcheId2EtapeId2'), titreDemarcheId: newDemarcheId('demarcheId2'), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, statutId: 'fai', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1593,9 +1691,8 @@ describe("phases d'une démarche", () => { ], }, ] - const titreTypeId = 'prw' - const tested = titrePhasesFind(demarches, titreTypeId) + const tested = titrePhasesFind(demarches, TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS) expect(tested).toStrictEqual({ [newDemarcheId('demarcheId1')]: { dateDebut: '2017-11-11', @@ -1613,14 +1710,17 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId1'), titreId: newTitreId('titreId'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheId1'), firstEtapeDateValidator.parse('2017-11-06')) + .machineId ?? null, statutId: 'acc', ordre: 1, etapes: [ { id: newEtapeId('demarcheId1etapeId2'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1633,7 +1733,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId1etapeId1'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1648,13 +1748,20 @@ describe("phases d'une démarche", () => { id: newDemarcheId('demarcheId2'), titreId: newTitreId('titreId'), typeId: DEMARCHES_TYPES_IDS.Prolongation1, + machineId: + MachineInfo.withDate( + TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS, + DEMARCHES_TYPES_IDS.Prolongation1, + newDemarcheId('demarcheId2'), + firstEtapeDateValidator.parse('2022-07-08') + ).machineId ?? null, statutId: DemarchesStatutsIds.EnConstruction, ordre: 2, etapes: [ { id: newEtapeId('demarcheId2EtapeId2'), titreDemarcheId: newDemarcheId('demarcheId2'), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, statutId: ETAPES_STATUTS.FAIT, ordre: 2, isBrouillon: ETAPE_IS_BROUILLON, @@ -1667,9 +1774,8 @@ describe("phases d'une démarche", () => { ], }, ] - const titreTypeId = 'prw' - const tested = titrePhasesFind(demarches, titreTypeId) + const tested = titrePhasesFind(demarches, TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS) expect(tested).toStrictEqual({ [newDemarcheId('demarcheId1')]: { dateDebut: '2017-11-11', @@ -1683,14 +1789,17 @@ describe("phases d'une démarche", () => { { id: newDemarcheId('demarcheId1'), titreId: newTitreId('titreId'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheId1'), firstEtapeDateValidator.parse('2017-11-06')) + .machineId ?? null, statutId: 'acc', ordre: 1, etapes: [ { id: newEtapeId('demarcheId1etapeId3'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'rej', ordre: 3, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1702,7 +1811,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId1etapeId2'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1715,7 +1824,7 @@ describe("phases d'une démarche", () => { { id: newEtapeId('demarcheId1etapeId1'), titreDemarcheId: newDemarcheId('demarcheId1'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -1728,7 +1837,7 @@ describe("phases d'une démarche", () => { }, ] - const tested = titrePhasesFind(demarches, 'prw') + const tested = titrePhasesFind(demarches, TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS) expect(tested).toStrictEqual({ [newDemarcheId('demarcheId1')]: { dateDebut: '2017-11-11', @@ -1750,14 +1859,16 @@ describe("phases d'une démarche", () => { titreId, statutId: 'acc', ordre: 1, - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId1, firstEtapeDateValidator.parse('2010-10-18')).machineId ?? null, id: demarcheId1, etapes: [ { titreDemarcheId: demarcheId1, demarcheIdsConsentement: [], ordre: 2, - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, duree: 36, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2010-11-05'), @@ -1768,7 +1879,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId1, demarcheIdsConsentement: [], ordre: 1, - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2010-10-18'), statutId: 'acc', @@ -1779,14 +1890,17 @@ describe("phases d'une démarche", () => { titreId, statutId: 'acc', ordre: 2, - typeId: 'pr1', + typeId: DEMARCHES_TYPES_IDS.Prolongation1, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Prolongation1, demarcheId2, firstEtapeDateValidator.parse('2013-10-30')).machineId ?? + null, id: demarcheId2, etapes: [ { titreDemarcheId: demarcheId2, demarcheIdsConsentement: [], ordre: 5, - typeId: 'apd', + typeId: ETAPES_TYPES.rapportEtAvisDeLaDREAL, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2015-05-13'), statutId: 'fav', @@ -1795,7 +1909,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId2, demarcheIdsConsentement: [], ordre: 9, - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2015-12-04'), statutId: 'acc', @@ -1804,7 +1918,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId2, demarcheIdsConsentement: [], ordre: 8, - typeId: 'scg', + typeId: ETAPES_TYPES.saisinesEtAvisCGE_AE, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2015-11-09'), statutId: 'fav', @@ -1813,7 +1927,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId2, demarcheIdsConsentement: [], ordre: 1, - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, duree: 60, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2013-10-30'), @@ -1823,7 +1937,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId2, demarcheIdsConsentement: [], ordre: 6, - typeId: 'app', + typeId: ETAPES_TYPES.avisDuPrefet, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2015-06-04'), statutId: 'fav', @@ -1832,7 +1946,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId2, demarcheIdsConsentement: [], ordre: 7, - typeId: 'scg', + typeId: ETAPES_TYPES.saisinesEtAvisCGE_AE, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2015-10-08'), statutId: 'fai', @@ -1841,7 +1955,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId2, demarcheIdsConsentement: [], ordre: 10, - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, dateFin: toCaminoDate('2018-11-05'), isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2015-12-17'), @@ -1851,7 +1965,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId2, demarcheIdsConsentement: [], ordre: 3, - typeId: 'spp', + typeId: ETAPES_TYPES.saisineDuPrefet, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2013-11-19'), statutId: 'fai', @@ -1860,7 +1974,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId2, demarcheIdsConsentement: [], ordre: 2, - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2013-10-30'), statutId: 'fai', @@ -1869,7 +1983,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId2, demarcheIdsConsentement: [], ordre: 4, - typeId: 'apo', + typeId: ETAPES_TYPES.avisDeLaCommissionDepartementaleDesMines_CDM_, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2015-02-11'), statutId: 'fav', @@ -1880,14 +1994,17 @@ describe("phases d'une démarche", () => { titreId, statutId: 'dep', ordre: 3, - typeId: 'vct', + typeId: DEMARCHES_TYPES_IDS.DemandeDeTitreDExploitation, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.DemandeDeTitreDExploitation, demarcheId3, firstEtapeDateValidator.parse('2015-07-31')) + .machineId ?? null, id: demarcheId3, etapes: [ { titreDemarcheId: demarcheId3, demarcheIdsConsentement: [], ordre: 2, - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2015-07-31'), statutId: 'fai', @@ -1896,7 +2013,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId3, demarcheIdsConsentement: [], ordre: 1, - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, duree: 540, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2015-07-31'), @@ -1908,14 +2025,17 @@ describe("phases d'une démarche", () => { titreId, statutId: 'ins', ordre: 4, - typeId: 'pr2', + typeId: DEMARCHES_TYPES_IDS.Prolongation2, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Prolongation2, demarcheId4, firstEtapeDateValidator.parse('2018-07-04')).machineId ?? + null, id: demarcheId4, etapes: [ { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 1, - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, duree: 60, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2018-06-29'), @@ -1925,7 +2045,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 12, - typeId: 'apd', + typeId: ETAPES_TYPES.rapportEtAvisDeLaDREAL, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2021-07-30'), statutId: 'fav', @@ -1934,7 +2054,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 4, - typeId: 'mco', + typeId: ETAPES_TYPES.demandeDeComplements, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2019-06-13'), statutId: 'fai', @@ -1943,7 +2063,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 10, - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2020-02-04'), statutId: 'fai', @@ -1952,7 +2072,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 14, - typeId: 'apd', + typeId: ETAPES_TYPES.rapportEtAvisDeLaDREAL, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2021-12-16'), statutId: 'fav', @@ -1961,7 +2081,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 5, - typeId: 'rco', + typeId: ETAPES_TYPES.receptionDeComplements, duree: 60, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2019-08-30'), @@ -1971,7 +2091,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 2, - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2018-07-04'), statutId: 'fai', @@ -1980,7 +2100,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 15, - typeId: 'ppu', + typeId: ETAPES_TYPES.consultationDuPublic, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2023-01-18'), statutId: 'fai', @@ -1989,7 +2109,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 6, - typeId: 'mco', + typeId: ETAPES_TYPES.demandeDeComplements, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2019-11-19'), statutId: 'fai', @@ -1998,7 +2118,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 3, - typeId: 'spp', + typeId: ETAPES_TYPES.saisineDuPrefet, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2018-07-20'), statutId: 'fai', @@ -2007,7 +2127,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 8, - typeId: 'mcr', + typeId: ETAPES_TYPES.recevabiliteDeLaDemande, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2020-01-29'), statutId: 'fav', @@ -2016,7 +2136,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 7, - typeId: 'rco', + typeId: ETAPES_TYPES.receptionDeComplements, duree: 60, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2019-12-26'), @@ -2026,7 +2146,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: demarcheId4, demarcheIdsConsentement: [], ordre: 13, - typeId: 'apo', + typeId: ETAPES_TYPES.avisDeLaCommissionDepartementaleDesMines_CDM_, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2021-10-29'), statutId: 'fav', @@ -2034,7 +2154,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'prm' + TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX ) ).toMatchInlineSnapshot(` { @@ -2062,14 +2182,17 @@ describe("phases d'une démarche", () => { titreId: newTitreId('nJ10z3Z74xi9OTh4oG6YXQBo'), statutId: 'acc', ordre: 1, - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheIdOctroi'), firstEtapeDateValidator.parse('2014-11-11')) + .machineId ?? null, id: newDemarcheId('demarcheIdOctroi'), etapes: [ { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 2, - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, dateFin: toCaminoDate('2014-11-11'), duree: 60, dateDebut: null, @@ -2082,7 +2205,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 1, - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, dateFin: toCaminoDate('2014-11-11'), duree: 60, dateDebut: null, @@ -2097,14 +2220,17 @@ describe("phases d'une démarche", () => { titreId: newTitreId('EW9cDeM6PfXS4TPznkjsNZVO'), statutId: 'rej', ordre: 2, - typeId: 'pr1', + typeId: DEMARCHES_TYPES_IDS.Prolongation1, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Prolongation1, newDemarcheId('demarcheIdPr1'), firstEtapeDateValidator.parse('2014-09-24')) + .machineId ?? null, id: newDemarcheId('demarcheIdPr1'), etapes: [ { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 3, - typeId: 'spp', + typeId: ETAPES_TYPES.saisineDuPrefet, dateFin: null, duree: null, dateDebut: null, @@ -2117,7 +2243,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 1, - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, dateFin: null, duree: 60, dateDebut: null, @@ -2130,7 +2256,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 4, - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, dateFin: null, duree: null, dateDebut: null, @@ -2143,7 +2269,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 2, - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, dateFin: null, duree: null, dateDebut: null, @@ -2155,7 +2281,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'pxm' + TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX ) ).toEqual({ demarcheIdOctroi: { @@ -2177,14 +2303,17 @@ describe("phases d'une démarche", () => { titreId: newTitreId('o3RzmZvqZcKMNmaE3nwXdvkE'), statutId: 'acc', ordre: 1, - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheIdOctroi'), firstEtapeDateValidator.parse('2009-11-17')) + .machineId ?? null, id: newDemarcheId('demarcheIdOctroi'), etapes: [ { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 2, - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, dateFin: toCaminoDate('2009-11-17'), duree: 60, dateDebut: null, @@ -2197,7 +2326,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 1, - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, dateFin: toCaminoDate('2009-11-17'), duree: 60, dateDebut: null, @@ -2212,14 +2341,17 @@ describe("phases d'une démarche", () => { titreId: newTitreId('Mef8FKNlX0WtohaO9wGOMQZs'), statutId: 'des', ordre: 2, - typeId: 'pr1', + typeId: DEMARCHES_TYPES_IDS.Prolongation1, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Prolongation1, newDemarcheId('demarcheIdPr1'), firstEtapeDateValidator.parse('2009-08-17')) + .machineId ?? null, id: newDemarcheId('demarcheIdPr1'), etapes: [ { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 1, - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, dateFin: null, duree: 24, dateDebut: null, @@ -2232,7 +2364,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 6, - typeId: 'app', + typeId: ETAPES_TYPES.avisDuPrefet, dateFin: null, duree: null, dateDebut: null, @@ -2245,7 +2377,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 3, - typeId: 'spp', + typeId: ETAPES_TYPES.saisineDuPrefet, dateFin: null, duree: null, dateDebut: null, @@ -2258,7 +2390,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 2, - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, dateFin: null, duree: null, dateDebut: null, @@ -2271,7 +2403,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 7, - typeId: 'des', + typeId: ETAPES_TYPES.desistementDuDemandeur, dateFin: null, duree: null, dateDebut: null, @@ -2284,7 +2416,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 5, - typeId: 'apo', + typeId: ETAPES_TYPES.avisDeLaCommissionDepartementaleDesMines_CDM_, dateFin: null, duree: null, dateDebut: null, @@ -2297,7 +2429,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 4, - typeId: 'apd', + typeId: ETAPES_TYPES.rapportEtAvisDeLaDREAL, dateFin: null, duree: null, dateDebut: null, @@ -2309,7 +2441,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'pxm' + TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX ) ).toEqual({ demarcheIdOctroi: { @@ -2331,14 +2463,17 @@ describe("phases d'une démarche", () => { titreId: newTitreId('nJ10z3Z74xi9OTh4oG6YXQBo'), statutId: 'acc', ordre: 1, - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheIdOctroi'), firstEtapeDateValidator.parse('2014-11-11')) + .machineId ?? null, id: newDemarcheId('demarcheIdOctroi'), etapes: [ { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 2, - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, dateFin: toCaminoDate('2014-11-11'), duree: 60, dateDebut: null, @@ -2351,7 +2486,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 1, - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, dateFin: toCaminoDate('2014-11-11'), duree: 60, dateDebut: null, @@ -2366,14 +2501,17 @@ describe("phases d'une démarche", () => { titreId: newTitreId('EW9cDeM6PfXS4TPznkjsNZVO'), statutId: 'rej', ordre: 2, - typeId: 'pr1', + typeId: DEMARCHES_TYPES_IDS.Prolongation1, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Prolongation1, newDemarcheId('demarcheIdPr1'), firstEtapeDateValidator.parse('2014-09-24')) + .machineId ?? null, id: newDemarcheId('demarcheIdPr1'), etapes: [ { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 4, - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, dateFin: null, duree: null, dateDebut: null, @@ -2386,7 +2524,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdPr1'), demarcheIdsConsentement: [], ordre: 2, - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, dateFin: null, duree: null, dateDebut: null, @@ -2398,7 +2536,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'pxm' + TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX ) ).toEqual({ demarcheIdOctroi: { @@ -2420,14 +2558,17 @@ describe("phases d'une démarche", () => { titreId: newTitreId('titreId'), statutId: 'acc', ordre: 1, - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheIdOctroi'), firstEtapeDateValidator.parse('2003-04-26')).machineId ?? + null, id: newDemarcheId('demarcheIdOctroi'), etapes: [ { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 3, - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, dateFin: toCaminoDate('2033-11-22'), dateDebut: toCaminoDate('2003-11-22'), isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -2439,7 +2580,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 2, - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, dateFin: toCaminoDate('2033-11-22'), dateDebut: toCaminoDate('2003-11-22'), isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -2451,7 +2592,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 1, - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2003-04-26'), statutId: 'rej', @@ -2460,7 +2601,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'cxh' + TITRES_TYPES_IDS.CONCESSION_HYDROCARBURE ) ).toMatchInlineSnapshot(` { @@ -2480,14 +2621,17 @@ describe("phases d'une démarche", () => { titreId: newTitreId('titreId'), statutId: 'acc', ordre: 1, - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId('demarcheIdOctroi'), firstEtapeDateValidator.parse('2003-04-26')) + .machineId ?? null, id: newDemarcheId('demarcheIdOctroi'), etapes: [ { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 3, - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, dateFin: toCaminoDate('2033-11-23'), dateDebut: toCaminoDate('2003-11-23'), isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -2499,7 +2643,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 2, - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, dateFin: toCaminoDate('2033-11-22'), dateDebut: toCaminoDate('2003-11-22'), isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -2511,7 +2655,7 @@ describe("phases d'une démarche", () => { titreDemarcheId: newDemarcheId('demarcheIdOctroi'), demarcheIdsConsentement: [], ordre: 1, - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2003-04-26'), statutId: 'acc', @@ -2520,7 +2664,7 @@ describe("phases d'une démarche", () => { ], }, ], - 'prm' + TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX ) ).toMatchInlineSnapshot(` { diff --git a/packages/api/src/business/rules/titre-phases-find.ts b/packages/api/src/business/rules/titre-phases-find.ts index 035488894dbb651479b3d939ebb99206119e3902..6a59c241c77f4e695e1f9d3f07bfeef68448507f 100644 --- a/packages/api/src/business/rules/titre-phases-find.ts +++ b/packages/api/src/business/rules/titre-phases-find.ts @@ -1,5 +1,5 @@ import { ITitreDemarche, ITitreEtape } from '../../types' -import { demarcheEnregistrementDemandeDateFind, DemarcheId } from 'camino-common/src/demarche' +import { DemarcheId } from 'camino-common/src/demarche' import { titreEtapesSortAscByOrdre, titreEtapesSortDescByOrdre } from '../utils/titre-etapes-sort' import { titreEtapePublicationCheck } from './titre-etape-publication-check' @@ -13,9 +13,10 @@ import { demarcheStatutIdsSuccess, isDemarcheStatutNonStatue } from 'camino-comm import { ETAPES_TYPES, EtapeTypeId } from 'camino-common/src/static/etapesTypes' import { isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefinedOrEmpty, NonEmptyArray } from 'camino-common/src/typescript-tools' import { ETAPE_IS_NOT_BROUILLON } from 'camino-common/src/etape' -import { machineFind } from '../rules-demarches/machines' import { toMachineEtapes } from '../rules-demarches/machine-common' import { DemarcheStatus, getPhase } from '../rules-demarches/machine-helper' +import { MachineInfo } from 'camino-common/src/machines' +import { ApiMachineInfo } from '../rules-demarches/machines' const DATE_PAR_DEFAUT_TITRE_INFINI = toCaminoDate('2018-12-31') /** * trouve une démarche acceptée ou terminée qui est @@ -88,7 +89,15 @@ export const titrePhasesFind = (titreDemarches: TitreDemarchePhaseFind[], titreT }) const titreDemarcheAnnulation = titreDemarcheAnnulationFind(titreDemarches) - const titreDemarcheAnnulationDate = isTitreDemarchePhaseFindWithEtapes(titreDemarcheAnnulation) ? titreDemarcheAnnulationDateFinFind(titreTypeId, titreDemarcheAnnulation) : null + let titreDemarcheAnnulationDate: CaminoDate | null | undefined = null + if (isNotNullNorUndefined(titreDemarcheAnnulation)) { + const annulationMachineInfo = MachineInfo.withMachineId(titreTypeId, titreDemarcheAnnulation.typeId, titreDemarcheAnnulation.id, titreDemarcheAnnulation.machineId) + if (!annulationMachineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente: ${annulationMachineInfo.error}`) + } + + titreDemarcheAnnulationDate = isTitreDemarchePhaseFindWithEtapes(titreDemarcheAnnulation) ? titreDemarcheAnnulationDateFinFind(annulationMachineInfo.value, titreDemarcheAnnulation.etapes) : null + } const filteredDemarches = sortedDemarches.filter( demarche => @@ -100,19 +109,24 @@ export const titrePhasesFind = (titreDemarches: TitreDemarchePhaseFind[], titreT if (!isTitreDemarchePhaseFindWithEtapes(demarche)) { return acc } - const machine = machineFind(titreTypeId, demarche.typeId, demarche.id, demarcheEnregistrementDemandeDateFind(demarche.fullEtapes)) + const machineInfo = MachineInfo.withMachineId(titreTypeId, demarche.typeId, demarche.id, demarche.machineId) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente: ${machineInfo.error}`) + } + + const machine = new ApiMachineInfo(machineInfo.value) let phase - let statut: DemarcheStatus | undefined - if (isNotNullNorUndefined(machine)) { - statut = machine.demarcheStatut(toMachineEtapes(demarche.fullEtapes)) - phase = getPhase(statut) + let machineDemarcheStatut: DemarcheStatus | undefined + if (isNotNullNorUndefined(machine.machine)) { + machineDemarcheStatut = machine.machine.demarcheStatut(toMachineEtapes(demarche.fullEtapes)) + phase = getPhase(machineDemarcheStatut) } const isFirstPhase = acc.length === 0 let dateDebutTDE: CaminoDate | null | undefined = findDateDebut(demarche, titreTypeId, isFirstPhase || (acc[acc.length - 1].dateDeFinParDefaut ?? false)) if (isFirstPhase) { - if (isNotNullNorUndefined(machine) && isNotNullNorUndefined(statut)) { - if (demarcheStatutIdsSuccess.has(statut.demarcheStatut) && isNotNullNorUndefined(phase) && isNotNullNorUndefined(phase.debut) && isNotNullNorUndefined(phase.fin)) { + if (isNotNullNorUndefined(machineDemarcheStatut)) { + if (demarcheStatutIdsSuccess.has(machineDemarcheStatut.demarcheStatut) && isNotNullNorUndefined(phase) && isNotNullNorUndefined(phase.debut) && isNotNullNorUndefined(phase.fin)) { acc.push({ dateDebut: phase.debut, dateFin: phase.fin, @@ -156,17 +170,17 @@ export const titrePhasesFind = (titreDemarches: TitreDemarchePhaseFind[], titreT return acc } else { - if (isNotNullNorUndefined(machine) && isNotNullNorUndefined(statut)) { + if (isNotNullNorUndefined(machineDemarcheStatut)) { if (isNotNullNorUndefined(phase) && isNotNullNorUndefined(phase.debut)) { let dateDebut: CaminoDate = phase.debut let dateFin: CaminoDate | null = phase.fin - if ('demarcheDateDebut' in statut) { - if (isNotNullNorUndefined(statut.demarcheDateDebut.dateDebut)) { - acc[acc.length - 1].dateFin = statut.demarcheDateDebut.dateDebut + if ('demarcheDateDebut' in machineDemarcheStatut) { + if (isNotNullNorUndefined(machineDemarcheStatut.demarcheDateDebut.dateDebut)) { + acc[acc.length - 1].dateFin = machineDemarcheStatut.demarcheDateDebut.dateDebut } else { dateDebut = acc[acc.length - 1].dateFin ?? phase.debut // le ?? est pour typescript uniquement, la date de fin de la phase précédente ne PEUT PAS être null - if (isNotNullNorUndefined(statut.demarcheDateFin.duree)) { - dateFin = dateAddMonths(dateDebut, statut.demarcheDateFin.duree) + if (isNotNullNorUndefined(machineDemarcheStatut.demarcheDateFin.duree)) { + dateFin = dateAddMonths(dateDebut, machineDemarcheStatut.demarcheDateFin.duree) } } } @@ -246,8 +260,10 @@ export type TitreEtapePhaseFind = Pick< | 'surface' | 'hasTitreFrom' > -export type TitreDemarchePhaseFind = Pick<ITitreDemarche, 'statutId' | 'ordre' | 'typeId' | 'id' | 'titreId' | 'demarcheDateDebut' | 'demarcheDateFin'> & { etapes?: TitreEtapePhaseFind[] } -export type TitreDemarchePhaseFindWithEtapes = Pick<ITitreDemarche, 'statutId' | 'ordre' | 'typeId' | 'id' | 'titreId' | 'demarcheDateDebut' | 'demarcheDateFin'> & { +export type TitreDemarchePhaseFind = Pick<ITitreDemarche, 'statutId' | 'ordre' | 'typeId' | 'id' | 'titreId' | 'demarcheDateDebut' | 'demarcheDateFin' | 'machineId'> & { + etapes?: TitreEtapePhaseFind[] +} +type TitreDemarchePhaseFindWithEtapes = Pick<ITitreDemarche, 'statutId' | 'ordre' | 'typeId' | 'id' | 'titreId' | 'demarcheDateDebut' | 'demarcheDateFin' | 'machineId'> & { etapes: NonEmptyArray<TitreEtapePhaseFind> fullEtapes: NonEmptyArray<TitreEtapePhaseFind> } diff --git a/packages/api/src/business/rules/titre-prop-etape-find.test.ts b/packages/api/src/business/rules/titre-prop-etape-find.test.ts index 76f611c97013c7b28cf4bdb39273e18137fad4eb..42431a8bd48b79d6b950f39aab31029de8d6e341 100644 --- a/packages/api/src/business/rules/titre-prop-etape-find.test.ts +++ b/packages/api/src/business/rules/titre-prop-etape-find.test.ts @@ -2,7 +2,7 @@ import { ITitreDemarche, IPropId, ITitreEtape, ICommune } from '../../types' import { titreContenuTitreEtapeFind, titrePropTitreEtapeFind } from './titre-prop-etape-find' import { newDemarcheId, newEtapeId, newTitreId } from '../../database/models/_format/id-create' -import { toCaminoDate } from 'camino-common/src/date' +import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { describe, expect, test } from 'vitest' import { TitresStatutIds } from 'camino-common/src/static/titresStatuts' import { newEntrepriseId } from 'camino-common/src/entreprise' @@ -10,6 +10,9 @@ import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' import { ETAPE_IS_NOT_BROUILLON, ETAPE_IS_BROUILLON } from 'camino-common/src/etape' import { km2Validator } from 'camino-common/src/number' +import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' +import { MachineInfo } from 'camino-common/src/machines' +import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' const currentDate = toCaminoDate('2023-04-06') describe("id de l'étape d'une propriété valide (dé-normalise)", () => { @@ -40,13 +43,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1989-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1989-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1989-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -56,7 +59,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { { id: newEtapeId('h-cx-courdemanges-1989-oct01-dex01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1989-oct01'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1989-01-01'), @@ -66,14 +69,14 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1989-mut01'), - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, statutId: 'acc', ordre: 2, etapes: [ { id: newEtapeId('h-cx-courdemanges-1989-mut01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1989-mut01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1989-02-03'), @@ -83,7 +86,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { { id: newEtapeId('h-cx-courdemanges-1989-mut01-dex01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1989-mut01'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1989-02-02'), statutId: 'acc', @@ -105,13 +108,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1988-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1988-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -121,7 +124,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { { id: newEtapeId('h-cx-courdemanges-1988-oct01-dex01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1988-oct01'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1989-01-01'), statutId: 'acc', @@ -162,13 +165,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1986-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1986-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1986-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1986-01-02'), statutId: 'acc', @@ -177,7 +180,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { { id: newEtapeId('h-cx-courdemanges-1986-oct01-dex01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1986-oct01'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1986-01-01'), @@ -187,14 +190,14 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1986-mut01'), - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, statutId: 'acc', ordre: 2, etapes: [ { id: newEtapeId('h-cx-courdemanges-1986-mut01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1986-mut01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -205,7 +208,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { { id: newEtapeId('h-cx-courdemanges-1986-mut01-dex01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1986-mut01'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -227,13 +230,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1986-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1986-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1986-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -242,7 +245,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { { id: newEtapeId('h-cx-courdemanges-1986-oct01-dex01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1986-oct01'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -252,14 +255,14 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1986-mut01'), - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, statutId: 'acc', ordre: 2, etapes: [ { id: newEtapeId('h-cx-courdemanges-1986-mut01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1986-mut01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -268,7 +271,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { { id: newEtapeId('h-cx-courdemanges-1986-mut01-dex01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1986-mut01'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -290,14 +293,14 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1985-mut01'), - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, statutId: 'ins', ordre: 2, etapes: [ { id: newEtapeId('h-cx-courdemanges-1985-mut01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1985-mut01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1985-01-01'), @@ -307,7 +310,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { { id: newEtapeId('h-cx-courdemanges-1985-mut01-dex01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1985-mut01'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1985-01-01'), statutId: 'acc', @@ -317,13 +320,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1985-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'ins', etapes: [ { id: newEtapeId('h-cx-courdemanges-1985-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1985-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -333,7 +336,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { { id: newEtapeId('h-cx-courdemanges-1985-oct01-dex01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1985-oct01'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -355,13 +358,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1984-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1984-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1984-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'rej', ordre: 2, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -373,7 +376,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1984-oct01'), isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1984-01-01'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, statutId: 'rej', ordre: 1, }, @@ -393,7 +396,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1983-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { @@ -401,7 +404,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1983-01-01'), titreDemarcheId: newDemarcheId(newDemarcheId('h-cx-courdemanges-1983-oct01')), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, statutId: 'acc', ordre: 1, geojson4326Perimetre: { properties: {}, geometry: { type: 'MultiPolygon', coordinates: [[[[1, 2]]]] }, type: 'Feature' }, @@ -422,13 +425,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1981-pro01'), - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, statutId: 'ins', etapes: [ { id: newEtapeId('h-cx-courdemanges-1981-pro01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1981-pro01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), @@ -439,13 +442,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1981-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1981-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1981-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), statutId: 'acc', @@ -467,7 +470,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1981-pro01'), - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, statutId: 'ins', etapes: [ { @@ -482,13 +485,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1981-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1981-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1981-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), statutId: 'acc', @@ -513,13 +516,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1981-mut01'), - typeId: 'mut', + typeId: DEMARCHES_TYPES_IDS.Mutation, statutId: 'ins', etapes: [ { id: newEtapeId('h-cx-courdemanges-1981-mut01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1981-mut01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), @@ -530,13 +533,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1981-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1981-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1981-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), statutId: 'acc', @@ -560,7 +563,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1981-pro01'), - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, statutId: 'ins', ordre: 2, etapes: [ @@ -569,7 +572,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1981-pro01'), - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, statutId: 'fai', ordre: 1, geojson4326Perimetre: { type: 'Feature', properties: {}, geometry: { type: 'MultiPolygon', coordinates: [[[[1, 2]]]] } }, @@ -581,14 +584,14 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1981-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', ordre: 1, etapes: [ { id: newEtapeId('h-cx-courdemanges-1981-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1981-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -629,7 +632,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1981-pro01'), - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, statutId: 'ins', ordre: 2, etapes: [ @@ -638,7 +641,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), titreDemarcheId: newDemarcheId(newDemarcheId('h-cx-courdemanges-1981-pro01')), - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, statutId: 'fai', ordre: 1, geojson4326Perimetre: { type: 'Feature', properties: {}, geometry: { type: 'MultiPolygon', coordinates: [[[[1, 2]]]] } }, @@ -651,14 +654,14 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1981-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', ordre: 1, etapes: [ { id: newEtapeId('h-cx-courdemanges-1981-oct01-dpu01'), titreDemarcheId: newDemarcheId(newDemarcheId('h-cx-courdemanges-1981-oct01')), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), @@ -699,13 +702,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1982-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1982-oct01-mfr01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1982-oct01'), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, statutId: 'fai', ordre: 1, isBrouillon: ETAPE_IS_BROUILLON, @@ -732,7 +735,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1982-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', demarcheDateDebut: toCaminoDate('1982-01-01'), demarcheDateFin: toCaminoDate('2018-12-31'), @@ -740,7 +743,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { { id: newEtapeId('h-cx-courdemanges-1982-oct01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1982-oct01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 1, isBrouillon: ETAPE_IS_NOT_BROUILLON, @@ -765,13 +768,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1982-amo01'), - typeId: 'amo', + typeId: DEMARCHES_TYPES_IDS.Amodiation, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1982-amo01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1982-amo01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 1, dateFin: toCaminoDate('4018-12-31'), @@ -783,7 +786,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1982-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', demarcheDateDebut: toCaminoDate('2021-01-01'), demarcheDateFin: toCaminoDate('2022-01-01'), @@ -803,13 +806,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { [ { id: newDemarcheId('h-cx-courdemanges-1981-amo01'), - typeId: 'amo', + typeId: DEMARCHES_TYPES_IDS.Amodiation, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1981-amo01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1981-amo01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), @@ -820,13 +823,13 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1981-pro01'), - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, statutId: 'acc', etapes: [ { id: newEtapeId('h-cx-courdemanges-1981-pro01-dpu01'), titreDemarcheId: newDemarcheId('h-cx-courdemanges-1981-pro01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), statutId: 'acc', @@ -836,7 +839,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { }, { id: newDemarcheId('h-cx-courdemanges-1981-oct01'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, statutId: 'acc', etapes: [ { @@ -844,7 +847,7 @@ describe("id de l'étape d'une propriété valide (dé-normalise)", () => { titreDemarcheId: newDemarcheId('h-cx-courdemanges-1981-oct01'), isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('1981-01-01'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, statutId: 'acc', ordre: 1, }, @@ -873,20 +876,23 @@ describe("id de l'étape qui a un contenu", () => { 'val' ) + const demarcheId = newDemarcheId('demarche-id') const etape3 = titreContenuTitreEtapeFind( { sectionId: 'arm', elementId: 'mecanisee' }, [ { - id: newDemarcheId('demarche-id'), + id: demarcheId, titreId: newTitreId('titre-id'), - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheId, firstEtapeDateValidator.parse('2020-01-01')).machineId ?? null, demarcheDateDebut: toCaminoDate('2020-01-01'), demarcheDateFin: toCaminoDate('2020-01-02'), etapes: [ { id: newEtapeId('etape-id'), - titreDemarcheId: newDemarcheId('demarche-id'), - typeId: 'dpu', + titreDemarcheId: demarcheId, + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2020-01-01'), statutId: 'acc', @@ -907,18 +913,21 @@ describe("id de l'étape qui a un contenu", () => { }) test("retourne l'id de l'étape si elle existe", () => { + const demarcheId = newDemarcheId('demarche-id') + const demarcheId2 = newDemarcheId('demarche-id-2') const etape1 = titreContenuTitreEtapeFind( { sectionId: 'arm', elementId: 'mecanisee' }, [ { - id: newDemarcheId('demarche-id'), + id: demarcheId, titreId: newTitreId('titre-id'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2020-01-03')).machineId ?? null, etapes: [ { id: newEtapeId('etape-id'), - titreDemarcheId: newDemarcheId('demarche-id'), - typeId: 'dpu', + titreDemarcheId: demarcheId, + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2020-01-03'), statutId: 'acc', @@ -930,14 +939,16 @@ describe("id de l'étape qui a un contenu", () => { ], }, { - id: newDemarcheId('demarche-id-2'), + id: demarcheId2, titreId: newTitreId('titre-id'), - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheId2, firstEtapeDateValidator.parse('2020-01-01')).machineId ?? null, etapes: [ { id: newEtapeId('etape-id-2'), - titreDemarcheId: newDemarcheId('demarche-id'), - typeId: 'dex', + titreDemarcheId: demarcheId2, + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2020-01-01'), statutId: 'fai', @@ -956,15 +967,17 @@ describe("id de l'étape qui a un contenu", () => { { sectionId: 'arm', elementId: 'mecanisee' }, [ { - id: newDemarcheId('demarche-id'), + id: demarcheId, titreId: newTitreId('titre-id'), - typeId: 'pro', + typeId: DEMARCHES_TYPES_IDS.Prolongation, + machineId: + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheId, firstEtapeDateValidator.parse('2020-01-01')).machineId ?? null, statutId: 'acc', etapes: [ { id: newEtapeId('etape-id'), - titreDemarcheId: newDemarcheId('demarche-id'), - typeId: 'dpu', + titreDemarcheId: demarcheId, + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2020-01-01'), statutId: 'acc', @@ -983,18 +996,20 @@ describe("id de l'étape qui a un contenu", () => { }) test("ne retourne pas l'id de la demande si le titre n’est pas en dmi", () => { + const demarcheId = newDemarcheId('demarche-id') const etape = titreContenuTitreEtapeFind( { sectionId: 'arm', elementId: 'mecanisee' }, [ { - id: newDemarcheId('demarche-id'), + id: demarcheId, titreId: newTitreId('titre-id'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2020-01-03')).machineId ?? null, etapes: [ { id: newEtapeId('etape-id'), - titreDemarcheId: newDemarcheId('demarche-id'), - typeId: 'mfr', + titreDemarcheId: demarcheId, + typeId: ETAPES_TYPES.demande, isBrouillon: ETAPE_IS_BROUILLON, date: toCaminoDate('2020-01-03'), statutId: 'fai', @@ -1012,18 +1027,20 @@ describe("id de l'étape qui a un contenu", () => { }) test("retourne l'id de la demande si le titre est en dmi", () => { + const demarcheId = newDemarcheId('demarche-id') const etape = titreContenuTitreEtapeFind( { sectionId: 'arm', elementId: 'mecanisee' }, [ { - id: newDemarcheId('demarche-id'), + id: demarcheId, titreId: newTitreId('titre-id'), - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2020-01-03')).machineId ?? null, etapes: [ { id: newEtapeId('etape-id'), titreDemarcheId: newDemarcheId('demarche-id'), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, isBrouillon: ETAPE_IS_BROUILLON, date: toCaminoDate('2020-01-03'), statutId: 'fai', diff --git a/packages/api/src/business/titre-etape-update.ts b/packages/api/src/business/titre-etape-update.ts index a669b992c08826f0477a541823dd1064d9c9c013..4ae7ae0a3a0fe24e68304d3b29cc7a6cb5363f75 100644 --- a/packages/api/src/business/titre-etape-update.ts +++ b/packages/api/src/business/titre-etape-update.ts @@ -24,6 +24,7 @@ import { callAndExit } from '../tools/fp-tools' import { etapeMiseEnConcurrenceUpdate } from './processes/titres-etapes-mise-en-concurrence' import { etapesFondamentaleIdUpdate } from './processes/titres-etapes-fondamentale-id-update' import { etapeConsentementUpdate } from './processes/titres-etapes-consentement' +import { demarcheMachineIdUpdate } from './processes/demarche-machine-id-update' export const titreEtapeUpdateTask = async (pool: Pool, titreEtapeId: EtapeId | null, titreDemarcheId: DemarcheId, user: UserNotNull): Promise<void> => { try { @@ -55,6 +56,7 @@ export const titreEtapeUpdateTask = async (pool: Pool, titreEtapeId: EtapeId | n await titresEtapesHeritageContenuUpdate(pool, user, titreDemarcheId) const titreId = titreDemarche.titreId + await callAndExit(demarcheMachineIdUpdate(pool, titreDemarcheId)) await titresDemarchesStatutIdUpdate(pool, titreId) await titresDemarchesOrdreUpdate([titreId]) await titresDemarchesDatesUpdate(pool, [titreId]) diff --git a/packages/api/src/business/utils/titre-demarches-etapes-rebuild.ts b/packages/api/src/business/utils/titre-demarches-etapes-rebuild.ts index cbfdeac34ff1191cf8b8564aa7de397d82f02d3b..f0d9b3679e81a7ccd9701ebca1b205fe22f4c661 100644 --- a/packages/api/src/business/utils/titre-demarches-etapes-rebuild.ts +++ b/packages/api/src/business/utils/titre-demarches-etapes-rebuild.ts @@ -5,21 +5,16 @@ import { titrePhasesFind } from '../rules/titre-phases-find' import { CaminoDate } from 'camino-common/src/date' import { titreEtapeForMachineValidator } from '../rules-demarches/machine-common' import { isNotNullNorUndefinedNorEmpty, isNullOrUndefinedOrEmpty } from 'camino-common/src/typescript-tools' +import { MachineInfo } from 'camino-common/src/machines' /** * Filtre les étapes antérieures à une date - * @param titreEtapes - étapes d'une démarche - * @param date - date */ const titreEtapesFilter = (titreEtapes: ITitreEtape[], date: string) => titreEtapes.filter(titreEtape => titreEtape.date <= date) /** * Reconstruit les démarches et étapes antérieures à une date * et recalcule le statut des démarches en fonction des étapes - * @param date - date - * @param titreDemarches - démarches du titre - * @param titreTypeId - id du type du titre - * @returns démarches du titre */ export const titreDemarchesEtapesRebuild = (date: CaminoDate, titreDemarches: ITitreDemarche[], titreTypeId: TitreTypeId): (Omit<ITitreDemarche, 'etapes'> & { etapes: ITitreEtape[] })[] => { const titreDemarchesRebuilt: ReturnType<typeof titreDemarchesEtapesRebuild> = [] @@ -33,8 +28,14 @@ export const titreDemarchesEtapesRebuild = (date: CaminoDate, titreDemarches: IT if (isNotNullNorUndefinedNorEmpty(titreEtapesFiltered)) { const titreDemarche = { ...td, etapes: titreEtapesFiltered } + // TODO 2025-03-26 c'est hyper dangereux d'utiliser zod pour stripper les données à l'intérieur de notre code, ça doit être utilisé uniquement aux abords des API et de la BDD const etapes = titreDemarche.etapes.map(etape => titreEtapeForMachineValidator.parse(etape)) - titreDemarche.statutId = titreDemarcheStatutIdFind(titreDemarche.typeId, etapes, titreTypeId, titreDemarche.id) + const machineInfo = MachineInfo.withMachineId(titreTypeId, titreDemarche.typeId, titreDemarche.id, titreDemarche.machineId) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente: ${machineInfo.error}`) + } + + titreDemarche.statutId = titreDemarcheStatutIdFind(machineInfo.value, etapes) titreDemarchesRebuilt.push(titreDemarche) } diff --git a/packages/api/src/business/utils/titre-etapes-sort.test.ts b/packages/api/src/business/utils/titre-etapes-sort.test.ts index 165918cd1e290a2bf17b4a566f4dddc3b967e1c1..69b5ce6ee3e1950dff64873a7b544a679f7ab0f3 100644 --- a/packages/api/src/business/utils/titre-etapes-sort.test.ts +++ b/packages/api/src/business/utils/titre-etapes-sort.test.ts @@ -1,21 +1,23 @@ import { titreEtapesSortAscByDate, titreEtapesSortAscByOrdre, titreEtapesSortDescByOrdre } from './titre-etapes-sort' import { newDemarcheId, newEtapeId } from '../../database/models/_format/id-create' import { vi, describe, test, expect } from 'vitest' -import { toCaminoDate } from 'camino-common/src/date' +import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' import { TitreEtapeForMachine } from '../rules-demarches/machine-common' import { ETAPE_IS_BROUILLON, ETAPE_IS_NOT_BROUILLON } from 'camino-common/src/etape' +import { MachineInfo } from 'camino-common/src/machines' +import { throwableMachineInfoForTestsOnly } from '../../../tests/_utils' const titreEtapesSortedDescResult = [ - { typeId: 'dpu', ordre: 2, date: '1988-03-11' }, - { typeId: 'dex', ordre: 1, date: '1988-03-06' }, + { typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, ordre: 2, date: '1988-03-11' }, + { typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, ordre: 1, date: '1988-03-06' }, ] as TitreEtapeForMachine[] const titreEtapesSortedAsc = [ - { typeId: 'dex', ordre: 1, date: '1988-03-06' }, - { typeId: 'dpu', ordre: 2, date: '1988-03-11' }, + { typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, ordre: 1, date: '1988-03-06' }, + { typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, ordre: 2, date: '1988-03-11' }, ] as TitreEtapeForMachine[] const titreEtapesSortedDesc = titreEtapesSortedAsc.slice().reverse() @@ -41,18 +43,22 @@ describe('trie les étapes', () => { }) test('des étapes organisées par date décroissante sont triées par date croissante', () => { - expect(titreEtapesSortAscByDate(titreEtapesSortedDesc, newDemarcheId(), 'oct', 'prh')).toMatchObject(titreEtapesSortedAsc) + expect( + titreEtapesSortAscByDate(titreEtapesSortedDesc, throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_HYDROCARBURE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null)) + ).toMatchObject(titreEtapesSortedAsc) }) test('des étapes organisées par date croissante restent triées par date croissante', () => { - expect(titreEtapesSortAscByDate(titreEtapesSortedAsc, newDemarcheId(), 'oct', 'prh')).toMatchObject(titreEtapesSortedAsc) + expect( + titreEtapesSortAscByDate(titreEtapesSortedAsc, throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_HYDROCARBURE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null)) + ).toMatchObject(titreEtapesSortedAsc) }) test('des étapes avec les mêmes dates organisées par ordre décroissant sont triées par ordre croissant', () => { const titreEtapesMemesDatesOrdreDesc: TitreEtapeForMachine[] = [ { id: newEtapeId('1'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, ordre: 2, date: toCaminoDate('1988-03-06'), dateFin: null, @@ -69,7 +75,7 @@ describe('trie les étapes', () => { }, { id: newEtapeId('2'), - typeId: 'dpu', + typeId: ETAPES_TYPES.publicationDeDecisionAuJORF, ordre: 1, date: toCaminoDate('1988-03-06'), dateFin: null, @@ -88,7 +94,12 @@ describe('trie les étapes', () => { const titreEtapesMemesDatesOrdreAscResult = titreEtapesMemesDatesOrdreDesc.slice().reverse() - expect(titreEtapesSortAscByDate(titreEtapesMemesDatesOrdreDesc, newDemarcheId(), 'oct', 'arm')).toStrictEqual(titreEtapesMemesDatesOrdreAscResult) + expect( + titreEtapesSortAscByDate( + titreEtapesMemesDatesOrdreDesc, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('1988-03-06')) + ) + ).toStrictEqual(titreEtapesMemesDatesOrdreAscResult) }) test('des étapes avec les mêmes dates sont triées par ordre de type croissant', () => { @@ -146,7 +157,12 @@ describe('trie les étapes', () => { demarcheIdsConsentement: [], }, ] - expect(titreEtapesSortAscByDate(titreEtapesMemesDatesOrdreEtapesTypesDesc, titreDemarcheId, DEMARCHES_TYPES_IDS.Retrait, TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX)).toMatchObject([ + expect( + titreEtapesSortAscByDate( + titreEtapesMemesDatesOrdreEtapesTypesDesc, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Retrait, titreDemarcheId, firstEtapeDateValidator.parse('1988-03-06')) + ) + ).toMatchObject([ { typeId: ETAPES_TYPES.saisineDuPrefet, ordre: 2, @@ -172,7 +188,7 @@ describe('trie les étapes', () => { const etapes: TitreEtapeForMachine[] = [ { id: newEtapeId('1'), - typeId: 'pfd', + typeId: ETAPES_TYPES.paiementDesFraisDeDossier, ordre: 1, date: toCaminoDate('2020-01-01'), dateFin: null, @@ -189,7 +205,7 @@ describe('trie les étapes', () => { }, { id: newEtapeId('2'), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, ordre: 2, date: toCaminoDate('2020-01-01'), dateFin: null, @@ -206,7 +222,7 @@ describe('trie les étapes', () => { }, { id: newEtapeId('3'), - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, ordre: 3, date: toCaminoDate('2020-01-01'), dateFin: null, @@ -223,7 +239,10 @@ describe('trie les étapes', () => { }, ] - const result = titreEtapesSortAscByDate(etapes, newDemarcheId(), DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX) + const result = titreEtapesSortAscByDate( + etapes, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')) + ) expect(result[0].typeId).toEqual('pfd') expect(result[1].typeId).toEqual('mfr') expect(result[2].typeId).toEqual('men') @@ -233,7 +252,7 @@ describe('trie les étapes', () => { const etapes: TitreEtapeForMachine[] = [ { id: newEtapeId('1'), - typeId: 'mcr', + typeId: ETAPES_TYPES.recevabiliteDeLaDemande, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -267,7 +286,7 @@ describe('trie les étapes', () => { }, { id: newEtapeId('3'), - typeId: 'vfd', + typeId: ETAPES_TYPES.validationDuPaiementDesFraisDeDossier, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -284,15 +303,18 @@ describe('trie les étapes', () => { }, ] - expect(() => titreEtapesSortAscByDate(etapes, newDemarcheId(), DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX)).toThrowErrorMatchingInlineSnapshot( - `[Error: l'état bof est inconnu]` - ) + expect(() => + titreEtapesSortAscByDate( + etapes, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')) + ) + ).toThrowErrorMatchingInlineSnapshot(`[Error: l'état bof est inconnu]`) }) test('utilise l’id pour trier des étapes totalement identiques', () => { const secondMcd: TitreEtapeForMachine = { id: newEtapeId('mcd2'), - typeId: 'mcd', + typeId: ETAPES_TYPES.demandeDeComplements_DecisionDeLaMissionAutoriteEnvironnementale_ExamenAuCasParCasDuProjet_, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -312,7 +334,7 @@ describe('trie les étapes', () => { { id: newEtapeId('mfr'), ordre: 1, - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -329,7 +351,7 @@ describe('trie les étapes', () => { { id: newEtapeId('men'), ordre: 2, - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -346,7 +368,7 @@ describe('trie les étapes', () => { { id: newEtapeId('mcd'), ordre: 3, - typeId: 'mcd', + typeId: ETAPES_TYPES.demandeDeComplements_DecisionDeLaMissionAutoriteEnvironnementale_ExamenAuCasParCasDuProjet_, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -363,7 +385,7 @@ describe('trie les étapes', () => { { id: newEtapeId('rcd'), ordre: 4, - typeId: 'rcd', + typeId: ETAPES_TYPES.receptionDeComplements_DecisionDeLaMissionAutoriteEnvironnementale_ExamenAuCasParCasDuProjet__, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -380,7 +402,10 @@ describe('trie les étapes', () => { secondMcd, ] - const result = titreEtapesSortAscByDate(etapes, newDemarcheId(), DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX) + const result = titreEtapesSortAscByDate( + etapes, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), firstEtapeDateValidator.parse('2020-01-01')) + ) expect(result).toContain(secondMcd) }) @@ -389,7 +414,7 @@ describe('trie les étapes', () => { { id: newEtapeId('mfr'), ordre: 1, - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -406,7 +431,7 @@ describe('trie les étapes', () => { { id: newEtapeId('men'), ordre: 2, - typeId: 'men', + typeId: ETAPES_TYPES.enregistrementDeLaDemande, date: toCaminoDate('2020-01-02'), dateFin: null, dateDebut: null, @@ -423,7 +448,7 @@ describe('trie les étapes', () => { { id: newEtapeId('pfd'), ordre: 3, - typeId: 'pfd', + typeId: ETAPES_TYPES.paiementDesFraisDeDossier, date: toCaminoDate('2020-01-03'), dateFin: null, dateDebut: null, @@ -440,7 +465,7 @@ describe('trie les étapes', () => { { id: newEtapeId('mcp'), ordre: 4, - typeId: 'mcp', + typeId: ETAPES_TYPES.completudeDeLaDemande, date: toCaminoDate('2020-01-04'), dateFin: null, dateDebut: null, @@ -457,7 +482,7 @@ describe('trie les étapes', () => { { id: newEtapeId('vfd'), ordre: 5, - typeId: 'vfd', + typeId: ETAPES_TYPES.validationDuPaiementDesFraisDeDossier, date: toCaminoDate('2020-01-05'), dateFin: null, dateDebut: null, @@ -474,7 +499,7 @@ describe('trie les étapes', () => { { id: newEtapeId('asc'), ordre: 0, - typeId: 'asc', + typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, date: toCaminoDate('2020-01-07'), dateFin: null, dateDebut: null, @@ -491,7 +516,7 @@ describe('trie les étapes', () => { { id: newEtapeId('mcr'), ordre: 6, - typeId: 'pfd', + typeId: ETAPES_TYPES.paiementDesFraisDeDossier, date: toCaminoDate('2020-01-06'), dateFin: null, dateDebut: null, @@ -507,7 +532,7 @@ describe('trie les étapes', () => { }, ] - const result = titreEtapesSortAscByDate(etapes, newDemarcheId(), DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX) + const result = titreEtapesSortAscByDate(etapes, throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), null)) expect(result.map(({ id }) => id)).toMatchInlineSnapshot(` [ "mfr", @@ -526,7 +551,7 @@ describe('trie les étapes', () => { const etapes: TitreEtapeForMachine[] = [ { id: newEtapeId('mfr'), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -543,7 +568,7 @@ describe('trie les étapes', () => { }, { id: newEtapeId('dex'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -559,7 +584,10 @@ describe('trie les étapes', () => { demarcheIdsConsentement: [], }, ] - const result = titreEtapesSortAscByDate(etapes, newDemarcheId(), DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_GEOTHERMIE) + const result = titreEtapesSortAscByDate( + etapes, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), 'ProcedureSimplifiee') + ) expect(result.map(({ id }) => id)).toMatchInlineSnapshot(` [ @@ -573,7 +601,7 @@ describe('trie les étapes', () => { const etapes: TitreEtapeForMachine[] = [ { id: newEtapeId('mfr'), - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, date: toCaminoDate('2020-01-02'), dateFin: null, dateDebut: null, @@ -590,7 +618,7 @@ describe('trie les étapes', () => { }, { id: newEtapeId('dex'), - typeId: 'dex', + typeId: ETAPES_TYPES.decisionDeLAutoriteAdministrative, date: toCaminoDate('2020-01-01'), dateFin: null, dateDebut: null, @@ -606,7 +634,10 @@ describe('trie les étapes', () => { demarcheIdsConsentement: [], }, ] - const result = titreEtapesSortAscByDate(etapes, newDemarcheId(), DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_GEOTHERMIE) + const result = titreEtapesSortAscByDate( + etapes, + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), 'ProcedureSimplifiee') + ) expect(result.map(({ id }) => id)).toMatchInlineSnapshot(` [ diff --git a/packages/api/src/business/utils/titre-etapes-sort.ts b/packages/api/src/business/utils/titre-etapes-sort.ts index 6d1225a9d76e291aa872378936c6a46efb7d6d24..72eea3f429a1040a1206f47a95b424cdebab6ba9 100644 --- a/packages/api/src/business/utils/titre-etapes-sort.ts +++ b/packages/api/src/business/utils/titre-etapes-sort.ts @@ -1,13 +1,11 @@ import { ITitreEtape } from '../../types' import { TitreEtapeForMachine, toMachineEtapes } from '../rules-demarches/machine-common' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' -import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' import { getEtapesTDE } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/index' -import { demarcheEnregistrementDemandeDateFind, DemarcheId } from 'camino-common/src/demarche' -import { isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools' +import { isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools' import { ETAPE_IS_BROUILLON } from 'camino-common/src/etape' import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' -import { CaminoMachines, machineFind } from '../rules-demarches/machines' +import { ApiMachineInfo } from '../rules-demarches/machines' +import { MachineInfo } from 'camino-common/src/machines' // classe les étapes selon leur ordre inverse: 3, 2, 1. export const titreEtapesSortDescByOrdre = <T extends Pick<ITitreEtape, 'ordre'>>(titreEtapes: T[]): T[] => titreEtapes.toSorted((a, b) => b.ordre! - a.ordre!) @@ -15,17 +13,13 @@ export const titreEtapesSortDescByOrdre = <T extends Pick<ITitreEtape, 'ordre'>> // classe les étapes selon leur ordre: 1, 2, 3, … export const titreEtapesSortAscByOrdre = <T extends Pick<ITitreEtape, 'ordre'>>(titreEtapes: T[]): T[] => titreEtapes.toSorted((a, b) => a.ordre! - b.ordre!) // classe les étapes selon leur dates, ordre et etapesTypes.ordre le cas échéant -export const titreEtapesSortAscByDate = <T extends TitreEtapeForMachine>(titreEtapes: T[], demarcheId: DemarcheId, demarcheTypeId: DemarcheTypeId, titreTypeId: TitreTypeId): T[] => { - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(titreEtapes) - let machine: CaminoMachines | undefined - if (isNotNullNorUndefinedNorEmpty(firstEtapeDate)) { - machine = machineFind(titreTypeId, demarcheTypeId, demarcheId, firstEtapeDate) - } +export const titreEtapesSortAscByDate = <T extends TitreEtapeForMachine>(titreEtapes: T[], machineInfo: MachineInfo): T[] => { + const machine = new ApiMachineInfo(machineInfo) - if (machine) { - const etapes = machine.orderMachine(toMachineEtapes(titreEtapes)) - if (!machine.isEtapesOk(etapes)) { - console.error(`impossible de trouver un ordre pour la démarche '${demarcheId}' où ces étapes sont valides ${JSON.stringify(etapes)}`) + if (isNotNullNorUndefined(machine.machine)) { + const etapes = machine.machine.orderMachine(toMachineEtapes(titreEtapes)) + if (!machine.machine.isEtapesOk(etapes)) { + console.error(`impossible de trouver un ordre pour la démarche '${machine.demarcheId}' où ces étapes sont valides ${JSON.stringify(etapes)}`) } const result: T[] = [] @@ -69,13 +63,13 @@ export const titreEtapesSortAscByDate = <T extends TitreEtapeForMachine>(titreEt if (dateA < dateB) return -1 if (dateA > dateB) return 1 - const etapes = getEtapesTDE(titreTypeId, demarcheTypeId) + const etapes = getEtapesTDE(machine.titreTypeId, machine.demarcheTypeId) const aTypeIndex = etapes.findIndex(e => e === a.typeId) const bTypeIndex = etapes.findIndex(e => e === b.typeId) if (aTypeIndex === -1 || bTypeIndex === -1) { - console.warn(`${demarcheId}: les étapes ${a.typeId} ou ${b.typeId} ne devraient pas être possible pour une démarche de type ${demarcheTypeId}`) + console.warn(`${machine.demarcheId}: les étapes ${a.typeId} ou ${b.typeId} ne devraient pas être possible pour une démarche de type ${machine.demarcheTypeId}`) return a.ordre! - b.ordre! } diff --git a/packages/api/src/business/utils/titre-slug-and-relations-update.test.integration.ts b/packages/api/src/business/utils/titre-slug-and-relations-update.test.integration.ts index 838a539042253844b1f2a62a5ba99a786e4478b2..976158177bdc9cfd036f3b8657954978bcb3f9f3 100644 --- a/packages/api/src/business/utils/titre-slug-and-relations-update.test.integration.ts +++ b/packages/api/src/business/utils/titre-slug-and-relations-update.test.integration.ts @@ -11,6 +11,7 @@ import { insertTitreGraph } from '../../../tests/integration-test-helper' import { isNullOrUndefined } from 'camino-common/src/typescript-tools' import { newDemarcheId, newTitreId } from '../../database/models/_format/id-create' import { demarcheSlugValidator } from 'camino-common/src/demarche' +import { throwableMachineInfoForTestsOnly } from '../../../tests/_utils' beforeAll(async () => { await dbManager.populateDb() }) @@ -132,6 +133,7 @@ describe('vérifie la mis à jour des slugs sur les relations d’un titre', () test('génère un slug pour une démarche', async () => { await Titres.query().delete() const id = newTitreId() + const demarcheId = newDemarcheId() const titre = await titreAdd({ nom: 'titre-nom', id, @@ -141,10 +143,11 @@ describe('vérifie la mis à jour des slugs sur les relations d’un titre', () slug: titreSlugValidator.parse('m-ar-titre-nom-0000'), demarches: [ { - id: newDemarcheId(), + id: demarcheId, titreId: id, typeId: 'oct', statutId: 'dep', + machineId: throwableMachineInfoForTestsOnly('arm', 'oct', demarcheId, null).machineId ?? null, slug: demarcheSlugValidator.parse('slug'), }, ], diff --git a/packages/api/src/business/validations/titre-demarche-etat-validate.test.ts b/packages/api/src/business/validations/titre-demarche-etat-validate.test.ts index 97e529467e2215494711b823dc82f52892f6618c..6eb6a0d8ea45ff62caeb22c2a96163421d53e93d 100644 --- a/packages/api/src/business/validations/titre-demarche-etat-validate.test.ts +++ b/packages/api/src/business/validations/titre-demarche-etat-validate.test.ts @@ -4,30 +4,28 @@ import { getPossiblesEtapesTypes, titreDemarcheUpdatedEtatValidate } from './tit import { newDemarcheId, newEtapeId } from '../../database/models/_format/id-create' import { EtapesTypesEtapesStatuts } from 'camino-common/src/static/etapesTypesEtapesStatuts' import { describe, test, expect, vi } from 'vitest' -import { caminoDateValidator, dateAddDays, toCaminoDate } from 'camino-common/src/date' +import { caminoDateValidator, dateAddDays, firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { ETAPES_TYPES, EtapeTypeId } from 'camino-common/src/static/etapesTypes' import { ETAPE_IS_BROUILLON, ETAPE_IS_NOT_BROUILLON, etapeIdValidator } from 'camino-common/src/etape' -import { ArmOctMachine } from '../rules-demarches/arm/oct.machine' import { TitreEtapeForMachine } from '../rules-demarches/machine-common' import { communeIdValidator, toCommuneId } from 'camino-common/src/static/communes' import { km2Validator } from 'camino-common/src/number' -import { ProcedureSpecifiqueMachine } from '../rules-demarches/procedure-specifique/procedure-specifique.machine' import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' -import { PrmOctMachine } from '../rules-demarches/prm/oct.machine' +import { MachineInfo } from 'camino-common/src/machines' +import { ApiMachineInfo } from '../rules-demarches/machines' +import { throwableMachineInfoForTestsOnly } from '../../../tests/_utils' console.warn = vi.fn() describe('titreDemarcheUpdatedEtatValidate', () => { test('ajoute une étape à une démarche vide', () => { const demarcheId = newDemarcheId() + const machineInfo = throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, null) const valid = titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'arm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { typeId: 'mfr', date: caminoDateValidator.parse('2030-01-01'), @@ -40,8 +38,7 @@ describe('titreDemarcheUpdatedEtatValidate', () => { hasTitreFrom: true, demarcheIdsConsentement: [], }, - demarcheId, - null + [] ) expect(valid.valid).toBe(true) @@ -49,12 +46,10 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('ajoute une étape à une démarche qui contient déjà une étape', () => { const demarcheId = newDemarcheId() + const machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2022-05-03')) const valid = titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'arm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { typeId: 'men', statutId: 'fai', @@ -67,8 +62,6 @@ describe('titreDemarcheUpdatedEtatValidate', () => { hasTitreFrom: true, demarcheIdsConsentement: [], }, - demarcheId, - [ { id: newEtapeId('1'), @@ -109,95 +102,87 @@ describe('titreDemarcheUpdatedEtatValidate', () => { hasTitreFrom: true, demarcheIdsConsentement: [], } - const valid = titreDemarcheUpdatedEtatValidate( - 'oct', + const machineInfo = MachineInfo.withDate('prm', DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2020-12-17')) + const valid = titreDemarcheUpdatedEtatValidate(machineInfo, [{ id: demarcheId }], demande, [ + demande, { - typeId: 'prm', - demarches: [{ id: demarcheId }], + id: etapeIdValidator.parse('idMdp'), + typeId: 'men', + statutId: 'fai', + isBrouillon: ETAPE_IS_NOT_BROUILLON, + date: toCaminoDate('2020-12-17'), + ordre: 2, + concurrence: { amIFirst: true }, + hasTitreFrom: true, + demarcheIdsConsentement: [], }, - demande, - demarcheId, - [ - demande, - { - id: etapeIdValidator.parse('idMdp'), - typeId: 'men', - statutId: 'fai', - isBrouillon: ETAPE_IS_NOT_BROUILLON, - date: toCaminoDate('2020-12-17'), - ordre: 2, - concurrence: { amIFirst: true }, - hasTitreFrom: true, - demarcheIdsConsentement: [], - }, - { - id: etapeIdValidator.parse('idSpp'), - typeId: 'spp', - statutId: 'fai', - isBrouillon: ETAPE_IS_NOT_BROUILLON, - date: toCaminoDate('2021-01-18'), - ordre: 3, - concurrence: { amIFirst: true }, - hasTitreFrom: true, - demarcheIdsConsentement: [], - }, - { - id: etapeIdValidator.parse('idMcr'), - typeId: 'mcr', - statutId: 'fav', - isBrouillon: ETAPE_IS_NOT_BROUILLON, - date: toCaminoDate('2022-11-17'), - ordre: 4, - concurrence: { amIFirst: true }, - hasTitreFrom: true, - demarcheIdsConsentement: [], - }, - { - id: etapeIdValidator.parse('idAnf'), - typeId: 'anf', - statutId: 'ter', - isBrouillon: ETAPE_IS_NOT_BROUILLON, - date: toCaminoDate('2022-11-17'), - ordre: 5, - concurrence: { amIFirst: true }, - hasTitreFrom: true, - demarcheIdsConsentement: [], - }, - { - id: etapeIdValidator.parse('idAsc'), - typeId: 'asc', - statutId: 'fai', - isBrouillon: ETAPE_IS_NOT_BROUILLON, - date: toCaminoDate('2022-11-17'), - ordre: 6, - concurrence: { amIFirst: true }, - hasTitreFrom: true, - demarcheIdsConsentement: [], - }, - { - id: etapeIdValidator.parse('idAdc'), - typeId: 'adc', - statutId: 'fai', - isBrouillon: ETAPE_IS_NOT_BROUILLON, - date: toCaminoDate('2022-11-17'), - ordre: 7, - concurrence: { amIFirst: true }, - hasTitreFrom: true, - demarcheIdsConsentement: [], - }, - { - id: etapeIdValidator.parse('idApo'), - typeId: 'apo', - statutId: 'fav', - isBrouillon: ETAPE_IS_NOT_BROUILLON, - date: toCaminoDate('2023-02-08'), - ordre: 8, - concurrence: { amIFirst: true }, - hasTitreFrom: true, - demarcheIdsConsentement: [], - }, - ] - ) + { + id: etapeIdValidator.parse('idSpp'), + typeId: 'spp', + statutId: 'fai', + isBrouillon: ETAPE_IS_NOT_BROUILLON, + date: toCaminoDate('2021-01-18'), + ordre: 3, + concurrence: { amIFirst: true }, + hasTitreFrom: true, + demarcheIdsConsentement: [], + }, + { + id: etapeIdValidator.parse('idMcr'), + typeId: 'mcr', + statutId: 'fav', + isBrouillon: ETAPE_IS_NOT_BROUILLON, + date: toCaminoDate('2022-11-17'), + ordre: 4, + concurrence: { amIFirst: true }, + hasTitreFrom: true, + demarcheIdsConsentement: [], + }, + { + id: etapeIdValidator.parse('idAnf'), + typeId: 'anf', + statutId: 'ter', + isBrouillon: ETAPE_IS_NOT_BROUILLON, + date: toCaminoDate('2022-11-17'), + ordre: 5, + concurrence: { amIFirst: true }, + hasTitreFrom: true, + demarcheIdsConsentement: [], + }, + { + id: etapeIdValidator.parse('idAsc'), + typeId: 'asc', + statutId: 'fai', + isBrouillon: ETAPE_IS_NOT_BROUILLON, + date: toCaminoDate('2022-11-17'), + ordre: 6, + concurrence: { amIFirst: true }, + hasTitreFrom: true, + demarcheIdsConsentement: [], + }, + { + id: etapeIdValidator.parse('idAdc'), + typeId: 'adc', + statutId: 'fai', + isBrouillon: ETAPE_IS_NOT_BROUILLON, + date: toCaminoDate('2022-11-17'), + ordre: 7, + concurrence: { amIFirst: true }, + hasTitreFrom: true, + demarcheIdsConsentement: [], + }, + { + id: etapeIdValidator.parse('idApo'), + typeId: 'apo', + statutId: 'fav', + isBrouillon: ETAPE_IS_NOT_BROUILLON, + date: toCaminoDate('2023-02-08'), + ordre: 8, + concurrence: { amIFirst: true }, + hasTitreFrom: true, + demarcheIdsConsentement: [], + }, + ]) expect(valid).toMatchInlineSnapshot(` { @@ -209,12 +194,10 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('modifie une étape à une démarche', () => { const demarcheId = newDemarcheId() + const machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2022-05-04')) const valid = titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'arm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { id: newEtapeId('1'), typeId: 'mfr', @@ -228,8 +211,6 @@ describe('titreDemarcheUpdatedEtatValidate', () => { hasTitreFrom: true, demarcheIdsConsentement: [], }, - demarcheId, - [ { id: newEtapeId('1'), @@ -267,12 +248,10 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('l’ajout d’une étape d’une démarche historique est valide', () => { const demarcheId = newDemarcheId() + const machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2000-01-01')) const valid = titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'arm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { typeId: 'mfr', isBrouillon: ETAPE_IS_BROUILLON, @@ -282,8 +261,6 @@ describe('titreDemarcheUpdatedEtatValidate', () => { demarcheIdsConsentement: [], hasTitreFrom: true, }, - demarcheId, - [ { id: etapeIdValidator.parse('1'), @@ -309,22 +286,19 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('l’ajout d’une étape à une démarche sans étape est valide', () => { const demarcheId = newDemarcheId() + const machineInfo = throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, null) const valid = titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'arm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { - typeId: 'mfr', + typeId: ETAPES_TYPES.demande, isBrouillon: ETAPE_IS_BROUILLON, date: caminoDateValidator.parse('2000-01-01'), - statutId: 'fai', + statutId: ETAPES_STATUTS.FAIT, concurrence: { amIFirst: true }, demarcheIdsConsentement: [], hasTitreFrom: true, }, - demarcheId, [] ) @@ -333,25 +307,21 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test("retourne une erreur si la démarche en cours de modification n'existe pas", () => { const demarcheId = newDemarcheId() + const etapeDate = caminoDateValidator.parse('2000-01-01') expect( titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'arm', - demarches: [{ id: newDemarcheId() }], - }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(etapeDate)), + [{ id: newDemarcheId() }], { id: etapeIdValidator.parse('1'), typeId: ETAPES_TYPES.demande, - date: caminoDateValidator.parse('2000-01-01'), + date: etapeDate, concurrence: { amIFirst: true }, hasTitreFrom: true, statutId: ETAPES_STATUTS.FAIT, isBrouillon: ETAPE_IS_NOT_BROUILLON, demarcheIdsConsentement: [], }, - demarcheId, - [] ) ).toMatchInlineSnapshot(` @@ -363,17 +333,15 @@ describe('titreDemarcheUpdatedEtatValidate', () => { } `) + const newEtapeDate = caminoDateValidator.parse('2025-01-01') expect( titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'arm', - demarches: [{ id: demarcheId }], - }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(newEtapeDate)), + [{ id: demarcheId }], { id: etapeIdValidator.parse('1'), typeId: ETAPES_TYPES.demande, - date: caminoDateValidator.parse('2025-01-01'), + date: newEtapeDate, concurrence: { amIFirst: true }, hasTitreFrom: false, statutId: ETAPES_STATUTS.FAIT, @@ -382,8 +350,6 @@ describe('titreDemarcheUpdatedEtatValidate', () => { communes: [{ id: toCommuneId('97300') }], surface: km2Validator.parse(12), }, - demarcheId, - [] ) ).toMatchInlineSnapshot(` @@ -396,12 +362,10 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('supprime une étape', () => { const demarcheId = newDemarcheId() + const machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2003-01-01')) const valid = titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'arm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { id: etapeIdValidator.parse('1'), typeId: 'mfr', @@ -412,7 +376,6 @@ describe('titreDemarcheUpdatedEtatValidate', () => { hasTitreFrom: true, demarcheIdsConsentement: [], }, - demarcheId, [ { id: etapeIdValidator.parse('1'), @@ -434,16 +397,10 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('ajoute une étape à une démarche sans machine', () => { const demarcheId = newDemarcheId() + const machineInfo = throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, null) const valid = titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'arm', - demarches: [ - { - id: demarcheId, - }, - ], - }, + machineInfo, + [{ id: demarcheId }], { id: etapeIdValidator.parse('1'), typeId: ETAPES_TYPES.demande, @@ -454,7 +411,7 @@ describe('titreDemarcheUpdatedEtatValidate', () => { isBrouillon: ETAPE_IS_NOT_BROUILLON, demarcheIdsConsentement: [], }, - demarcheId + [] ) expect(valid.valid).toBe(true) @@ -462,12 +419,10 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('ajoute une demande en construction à une démarche vide', () => { const demarcheId = newDemarcheId() + const machineInfo = throwableMachineInfoForTestsOnly('axm', DEMARCHES_TYPES_IDS.Octroi, demarcheId, null) const valid = titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'axm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { id: etapeIdValidator.parse('1'), typeId: ETAPES_TYPES.demande, @@ -480,7 +435,7 @@ describe('titreDemarcheUpdatedEtatValidate', () => { communes: [{ id: toCommuneId('97300') }], surface: km2Validator.parse(12), }, - demarcheId + [] ) expect(valid).toMatchInlineSnapshot(` @@ -493,12 +448,10 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('ajoute une demande en construction à une démarche qui contient déjà une étape', () => { const demarcheId = newDemarcheId() + const machineInfo = MachineInfo.withDate('axm', DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2020-01-01')) const valid = titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'axm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { typeId: 'mfr', statutId: 'fai', @@ -508,8 +461,6 @@ describe('titreDemarcheUpdatedEtatValidate', () => { demarcheIdsConsentement: [], hasTitreFrom: true, }, - demarcheId, - [ { id: etapeIdValidator.parse('1'), @@ -530,12 +481,10 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('modifie une demande en construction à une démarche', () => { const demarcheId = newDemarcheId() + const machineInfo = MachineInfo.withDate('axm', DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2020-01-01')) const valid = titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'axm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { id: etapeIdValidator.parse('1'), typeId: 'mfr', @@ -546,7 +495,6 @@ describe('titreDemarcheUpdatedEtatValidate', () => { hasTitreFrom: true, demarcheIdsConsentement: [], }, - demarcheId, [ { id: etapeIdValidator.parse('1'), @@ -578,13 +526,11 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('ne peut pas ajouter une 2ème demande en construction à une démarche', () => { const demarcheId = newDemarcheId() + const machineInfo = MachineInfo.withDate('axm', DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2024-01-01')) expect( titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'axm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { typeId: 'mfr', statutId: 'fai', @@ -594,8 +540,6 @@ describe('titreDemarcheUpdatedEtatValidate', () => { demarcheIdsConsentement: [], hasTitreFrom: true, }, - demarcheId, - [ { id: etapeIdValidator.parse('1'), @@ -613,7 +557,7 @@ describe('titreDemarcheUpdatedEtatValidate', () => { ).toMatchInlineSnapshot(` { "errors": [ - "les étapes de la démarche machine AXMOct ne sont pas valides", + "les étapes de la démarche machine AncienLogigrammeOctroiAXM ne sont pas valides", ], "valid": false, } @@ -622,13 +566,11 @@ describe('titreDemarcheUpdatedEtatValidate', () => { test('ne peut pas ajouter une étape de type inconnu sur une machine', () => { const demarcheId = newDemarcheId() + const machineInfo = MachineInfo.withDate('axm', DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2021-01-01')) expect( titreDemarcheUpdatedEtatValidate( - 'oct', - { - typeId: 'axm', - demarches: [{ id: demarcheId }], - }, + machineInfo, + [{ id: demarcheId }], { typeId: 'aaa' as EtapeTypeId, date: toCaminoDate('2022-01-01'), @@ -641,8 +583,6 @@ describe('titreDemarcheUpdatedEtatValidate', () => { hasTitreFrom: true, demarcheIdsConsentement: [], }, - demarcheId, - [ { id: newEtapeId('1'), @@ -663,7 +603,7 @@ describe('titreDemarcheUpdatedEtatValidate', () => { ).toMatchInlineSnapshot(` { "errors": [ - "les étapes de la démarche machine AXMOct ne sont pas valides", + "les étapes de la démarche machine AncienLogigrammeOctroiAXM ne sont pas valides", ], "valid": false, } @@ -710,14 +650,17 @@ describe('getPossiblesEtapesTypes', () => { { typeId: 'apd', date: toCaminoDate('2024-03-19'), isBrouillon: ETAPE_IS_NOT_BROUILLON, id: newEtapeId(), ordre: 16, statutId: 'fre', communes: [] }, { typeId: 'app', date: toCaminoDate('2024-04-08'), isBrouillon: ETAPE_IS_NOT_BROUILLON, id: newEtapeId(), ordre: 17, statutId: 'def', communes: [] }, ] + const demarcheId = newDemarcheId() + const machineInfo = new ApiMachineInfo( + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2019-06-06')) + ) const tested = getPossiblesEtapesTypes( - undefined, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + machineInfo, + ETAPES_TYPES.receptionDeComplements, rcoId, toCaminoDate('2019-06-06'), - etapes + etapes.map(etape => ({ ...etape, demarcheIdsConsentement: [] })) ) expect(tested.rco).toMatchInlineSnapshot(` @@ -817,9 +760,7 @@ describe('getPossiblesEtapesTypes', () => { expect( getPossiblesEtapesTypes( - new PrmOctMachine(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi), - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + new ApiMachineInfo(throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), 'AncienLogigrammeOctroiPRM')), ETAPES_TYPES.rapportEtAvisDeLaDREAL, apdId, toCaminoDate('2024-05-22'), @@ -921,9 +862,7 @@ describe('getPossiblesEtapesTypes', () => { expect( getPossiblesEtapesTypes( - new PrmOctMachine(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi), - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + new ApiMachineInfo(throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), 'AncienLogigrammeOctroiPRM')), ETAPES_TYPES.saisineDuPrefet, sppId, toCaminoDate('2023-05-03'), @@ -998,9 +937,7 @@ describe('getPossiblesEtapesTypes', () => { expect( getPossiblesEtapesTypes( - new PrmOctMachine(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi), - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + new ApiMachineInfo(throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), 'AncienLogigrammeOctroiPRM')), ETAPES_TYPES.enregistrementDeLaDemande, menId, toCaminoDate('2023-05-03'), @@ -1075,9 +1012,7 @@ describe('getPossiblesEtapesTypes', () => { expect( getPossiblesEtapesTypes( - new PrmOctMachine(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi), - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + new ApiMachineInfo(throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), 'AncienLogigrammeOctroiPRM')), ETAPES_TYPES.enregistrementDeLaDemande, menId, toCaminoDate('2023-06-01'), @@ -1089,7 +1024,15 @@ describe('getPossiblesEtapesTypes', () => { }) test('peut créer une étape sur une procédure spécifique vide', () => { - expect(getPossiblesEtapesTypes(new ProcedureSpecifiqueMachine('cxm', 'oct'), 'cxm', 'oct', undefined, undefined, toCaminoDate('4000-02-01'), [])).toMatchInlineSnapshot(` + expect( + getPossiblesEtapesTypes( + new ApiMachineInfo(throwableMachineInfoForTestsOnly('cxm', DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), 'ProcedureSpecifique')), + undefined, + undefined, + toCaminoDate('4000-02-01'), + [] + ) + ).toMatchInlineSnapshot(` { "mfr": { "etapeStatutIds": [ @@ -1375,9 +1318,11 @@ describe('getPossiblesEtapesTypes', () => { }, ] - const machine = new ArmOctMachine(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi) + const apiMachineInfoArmOct = new ApiMachineInfo( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), 'AncienLogigrammeOctroiARM') + ) test('modifie une étape existante', () => { - const tested = getPossiblesEtapesTypes(machine, 'arm', 'oct', undefined, etapeIdValidator.parse('etapeId3'), toCaminoDate('2019-10-11'), etapes) + const tested = getPossiblesEtapesTypes(apiMachineInfoArmOct, undefined, etapeIdValidator.parse('etapeId3'), toCaminoDate('2019-10-11'), etapes) expect(Object.keys(tested)).toHaveLength(1) expect(tested.dae).toMatchInlineSnapshot(` { @@ -1390,13 +1335,13 @@ describe('getPossiblesEtapesTypes', () => { }) test.each(etapes)("modifie l'étape %# existante à la même date devrait permettre de recréer la même étape", etape => { - const etapesTypesPossibles = getPossiblesEtapesTypes(machine, 'arm', 'oct', etape.typeId, etape.id, etape.date, etapes) + const etapesTypesPossibles = getPossiblesEtapesTypes(apiMachineInfoArmOct, etape.typeId, etape.id, etape.date, etapes) expect(Object.keys(etapesTypesPossibles).length, `pas d'étapes possibles à l'étape ${JSON.stringify(etape)}. Devrait contenir AU MOINS la même étape`).toBeGreaterThan(0) expect(etapesTypesPossibles[etape.typeId]).toHaveProperty('etapeStatutIds') }) test('ajoute une nouvelle étape à la fin', () => { - const tested = getPossiblesEtapesTypes(machine, 'arm', 'oct', undefined, undefined, toCaminoDate('2022-05-06'), etapes) + const tested = getPossiblesEtapesTypes(apiMachineInfoArmOct, undefined, undefined, toCaminoDate('2022-05-06'), etapes) expect(Object.keys(tested)).toHaveLength(1) expect(tested.mnv).toMatchInlineSnapshot(` { @@ -1409,7 +1354,7 @@ describe('getPossiblesEtapesTypes', () => { }) test('ajoute une nouvelle étape en plein milieu', () => { - const tested = getPossiblesEtapesTypes(machine, 'arm', 'oct', undefined, undefined, toCaminoDate('2019-12-04'), etapes) + const tested = getPossiblesEtapesTypes(apiMachineInfoArmOct, undefined, undefined, toCaminoDate('2019-12-04'), etapes) expect(Object.keys(tested).toSorted()).toStrictEqual(['mca', 'mim', 'mod']) }) @@ -1451,7 +1396,7 @@ describe('getPossiblesEtapesTypes', () => { }, ] - const tested = getPossiblesEtapesTypes(machine, 'arm', 'oct', undefined, undefined, toCaminoDate('2019-12-04'), etapes) + const tested = getPossiblesEtapesTypes(apiMachineInfoArmOct, undefined, undefined, toCaminoDate('2019-12-04'), etapes) expect(Object.keys(tested).toSorted()).toStrictEqual(['dae', 'pfd', 'rde']) }) @@ -1493,7 +1438,7 @@ describe('getPossiblesEtapesTypes', () => { }, ] - const tested = getPossiblesEtapesTypes(machine, 'arm', 'oct', undefined, undefined, toCaminoDate('2019-12-04'), etapes) + const tested = getPossiblesEtapesTypes(apiMachineInfoArmOct, undefined, undefined, toCaminoDate('2019-12-04'), etapes) expect(Object.keys(tested)).toStrictEqual(['pfd']) }) @@ -1718,7 +1663,7 @@ describe('getPossiblesEtapesTypes', () => { }, ] - const tested = getPossiblesEtapesTypes(machine, 'arm', 'oct', undefined, undefined, toCaminoDate('2022-07-01'), etapes) + const tested = getPossiblesEtapesTypes(apiMachineInfoArmOct, undefined, undefined, toCaminoDate('2022-07-01'), etapes) expect(Object.keys(tested).toSorted()).toStrictEqual(['asc', 'css', 'des', 'mcb', 'mod', 'rcb', 'rde']) vi.resetAllMocks() }) @@ -1801,7 +1746,7 @@ describe('getPossiblesEtapesTypes', () => { }, ] - const tested = getPossiblesEtapesTypes(machine, 'arm', 'oct', undefined, undefined, toCaminoDate('2022-07-01'), etapes) + const tested = getPossiblesEtapesTypes(apiMachineInfoArmOct, undefined, undefined, toCaminoDate('2022-07-01'), etapes) expect(Object.keys(tested).toSorted()).toStrictEqual(['css', 'des', 'mcb', 'mcp', 'mod', 'rde']) }) @@ -1813,8 +1758,10 @@ describe('getPossiblesEtapesTypes', () => { surface: null, demarcheIdsConsentement: [], } as const - const procedureSpecifiqueMachine = new ProcedureSpecifiqueMachine('arm', 'oct') - test("peut éditer une mfr sur la procédure spécifique d'une démarche bien avancée", () => { + const apiMachineInfoSpecifique = new ApiMachineInfo( + throwableMachineInfoForTestsOnly(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(), 'ProcedureSpecifique') + ) + test("peut éditer une demande sur la procédure spécifique d'une démarche bien avancée", () => { const demandeId = newEtapeId('idMfr') const dateDemande = toCaminoDate('2024-12-01') const etapes: TitreEtapeForMachine[] = [ @@ -1869,15 +1816,7 @@ describe('getPossiblesEtapesTypes', () => { }, ] - const tested = getPossiblesEtapesTypes( - procedureSpecifiqueMachine, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - ETAPES_TYPES.demande, - demandeId, - dateDemande, - etapes - ) + const tested = getPossiblesEtapesTypes(apiMachineInfoSpecifique, ETAPES_TYPES.demande, demandeId, dateDemande, etapes) expect(Object.keys(tested)).toStrictEqual([ETAPES_TYPES.demande]) }) diff --git a/packages/api/src/business/validations/titre-demarche-etat-validate.ts b/packages/api/src/business/validations/titre-demarche-etat-validate.ts index 74b86d705aee475355e3350e0bcb8dc795da34f1..c1cf09dce8c206747fd15a00ec5e63f284a3d7d5 100644 --- a/packages/api/src/business/validations/titre-demarche-etat-validate.ts +++ b/packages/api/src/business/validations/titre-demarche-etat-validate.ts @@ -1,19 +1,19 @@ // valide la date et la position de l'étape en fonction des autres étapes -import { NonEmptyArray, isNonEmptyArray, isNotNullNorUndefined, isNullOrUndefined, isNullOrUndefinedOrEmpty } from 'camino-common/src/typescript-tools' +import { NonEmptyArray, isNonEmptyArray, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefined, isNullOrUndefinedOrEmpty } from 'camino-common/src/typescript-tools' import type { ITitreEtape } from '../../types' import { Etape, TitreEtapeForMachine, titreEtapeForMachineValidator, toMachineEtapes } from '../rules-demarches/machine-common' -import { demarcheEnregistrementDemandeDateFind, DemarcheId } from 'camino-common/src/demarche' -import { DemarchesTypes, DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' import { ETAPE_IS_BROUILLON, ETAPE_IS_NOT_BROUILLON, EtapeId, EtapeTypeEtapeStatutWithMainStep } from 'camino-common/src/etape' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' -import { CaminoMachines, machineFind } from '../rules-demarches/machines' +import { DemarcheId } from 'camino-common/src/demarche' +import { ApiMachineInfo, CaminoMachines, demarcheEnregistrementDemandeDateFind } from '../rules-demarches/machines' import { CaminoDate } from 'camino-common/src/date' import { EtapesTypes, EtapeTypeId } from 'camino-common/src/static/etapesTypes' import { titreEtapesSortAscByOrdre } from '../utils/titre-etapes-sort' import { getEtapesTDE, isTDEExist } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/index' import { etapeTypeDateFinCheck } from '../../api/_format/etapes-types' import { getEtapesStatuts } from 'camino-common/src/static/etapesTypesEtapesStatuts' +import { MachineInfo } from 'camino-common/src/machines' +import { DemarchesTypes } from 'camino-common/src/static/demarchesTypes' const titreDemarcheEtapesBuild = <T extends Pick<Partial<ITitreEtape>, 'id'>>(titreEtape: T, suppression: boolean, titreDemarcheEtapes?: T[] | null): T[] => { if (isNullOrUndefinedOrEmpty(titreDemarcheEtapes)) { @@ -46,14 +46,13 @@ const titreDemarcheEtapesBuild = <T extends Pick<Partial<ITitreEtape>, 'id'>>(ti // vérifie que la modification de la démarche // est valide par rapport aux définitions des types d'étape export const titreDemarcheUpdatedEtatValidate = ( - demarcheTypeId: DemarcheTypeId, - titre: { typeId: TitreTypeId; demarches?: { id: DemarcheId }[] }, + machineInfo: MachineInfo, + demarches: { id: DemarcheId }[], titreEtape: Pick<Partial<ITitreEtape>, 'id'> & Pick< ITitreEtape, 'statutId' | 'typeId' | 'date' | 'contenu' | 'surface' | 'communes' | 'isBrouillon' | 'hasTitreFrom' | 'concurrence' | 'demarcheIdsConsentement' | 'dateDebut' | 'dateFin' | 'duree' >, - demarcheId: DemarcheId, titreDemarcheEtapes?: | Pick< ITitreEtape, @@ -77,29 +76,27 @@ export const titreDemarcheUpdatedEtatValidate = ( suppression = false ): { valid: true; errors: null } | { valid: false; errors: NonEmptyArray<string> } => { const titreDemarcheEtapesNew = titreDemarcheEtapesBuild(titreEtape, suppression, titreDemarcheEtapes) - let machine: CaminoMachines | undefined - if (isNullOrUndefinedOrEmpty(titreDemarcheEtapesNew)) { - return { valid: true, errors: null } - } else { + let machine: ApiMachineInfo + if (isNotNullNorUndefinedNorEmpty(titreDemarcheEtapesNew)) { const firstEtapeDate = demarcheEnregistrementDemandeDateFind(titreDemarcheEtapesNew) - if (isNotNullNorUndefined(firstEtapeDate)) { - machine = machineFind(titre.typeId, demarcheTypeId, demarcheId, firstEtapeDate) - } + machine = new ApiMachineInfo(MachineInfo.withDate(machineInfo.titreTypeId, machineInfo.demarcheTypeId, machineInfo.demarcheId, firstEtapeDate)) + } else { + return { valid: true, errors: null } } const titreDemarchesErrors: string[] = [] // vérifie que la démarche existe dans le titre - if (!(titre.demarches?.some(({ id }) => id === demarcheId) ?? false)) { + if (!demarches.some(({ id }) => id === machineInfo.demarcheId)) { titreDemarchesErrors.push('le titre ne contient pas la démarche en cours de modification') } // on récupère tous les type d'étapes et les statuts associés applicable à la date souhaitée try { - const etapeTypesWithStatusPossibles = getPossiblesEtapesTypes(machine, titre.typeId, demarcheTypeId, titreEtape.typeId, titreEtape.id, titreEtape.date, titreDemarcheEtapes ?? []) + const etapeTypesWithStatusPossibles = getPossiblesEtapesTypes(machine, titreEtape.typeId, titreEtape.id, titreEtape.date, titreDemarcheEtapes ?? []) const statutPossiblesPourCetteEtape = etapeTypesWithStatusPossibles[titreEtape.typeId] if (isNullOrUndefined(statutPossiblesPourCetteEtape) || !statutPossiblesPourCetteEtape.etapeStatutIds.includes(titreEtape.statutId)) { - if (isNotNullNorUndefined(machine)) { - return { valid: false, errors: [`les étapes de la démarche machine ${machine.machine.id} ne sont pas valides`] } + if (isNotNullNorUndefined(machine.machine)) { + return { valid: false, errors: [`les étapes de la démarche machine ${machine.machineId} ne sont pas valides`] } } else { return { valid: false, errors: ['les étapes de la démarche TDE ne sont pas valides'] } } @@ -109,11 +106,11 @@ export const titreDemarcheUpdatedEtatValidate = ( titreDemarchesErrors.push(e.message) } - if (isNotNullNorUndefined(machine)) { + if (isNotNullNorUndefined(machine.machine)) { // vérifie que toutes les étapes existent dans l’arbre try { - const ok = machine.isEtapesOk( - machine.orderMachine( + const ok = machine.machine.isEtapesOk( + machine.machine.orderMachine( toMachineEtapes( titreDemarcheEtapesNew.map(etape => ({ ...etape, @@ -143,30 +140,28 @@ export const titreDemarcheUpdatedEtatValidate = ( } export const getPossiblesEtapesTypes = ( - machine: CaminoMachines | undefined, - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, + machine: ApiMachineInfo, etapeTypeId: EtapeTypeId | undefined, etapeId: EtapeId | undefined, date: CaminoDate, demarcheEtapes: Pick<ITitreEtape, 'typeId' | 'date' | 'isBrouillon' | 'id' | 'ordre' | 'statutId' | 'communes'>[] ): EtapeTypeEtapeStatutWithMainStep => { let etapesTypes: EtapeTypeEtapeStatutWithMainStep = {} - if (isNotNullNorUndefined(machine)) { + if (isNotNullNorUndefined(machine.machine)) { const etapes = demarcheEtapes.map(etape => titreEtapeForMachineValidator.parse(etape)) - etapesTypes = etapesTypesPossibleACetteDateOuALaPlaceDeLEtape(machine, etapes, etapeId ?? null, date) + etapesTypes = etapesTypesPossibleACetteDateOuALaPlaceDeLEtape(machine.machine, etapes, etapeId ?? null, date) } else { // si on modifie une étape // vérifie que son type est possible sur la démarche if (isNotNullNorUndefined(etapeTypeId)) { - if (!isTDEExist(titreTypeId, demarcheTypeId, etapeTypeId)) { - const demarcheType = DemarchesTypes[demarcheTypeId] - throw new Error(`étape ${EtapesTypes[etapeTypeId].nom} inexistante pour une démarche ${demarcheType.nom} pour un titre ${titreTypeId}.`) + if (!isTDEExist(machine.titreTypeId, machine.demarcheTypeId, etapeTypeId)) { + const demarcheType = DemarchesTypes[machine.demarcheTypeId] + throw new Error(`étape ${EtapesTypes[etapeTypeId].nom} inexistante pour une démarche ${demarcheType.nom} pour un titre ${machine.titreTypeId}.`) } } // dans un premier temps on récupère toutes les étapes possibles pour cette démarche - let etapesTypesTDE = getEtapesTDE(titreTypeId, demarcheTypeId) + let etapesTypesTDE = getEtapesTDE(machine.titreTypeId, machine.demarcheTypeId) const etapeTypesExistants = demarcheEtapes.map(({ typeId }) => typeId) etapesTypesTDE = etapesTypesTDE diff --git a/packages/api/src/business/validations/titre-etape-updation-validate.test.ts b/packages/api/src/business/validations/titre-etape-updation-validate.test.ts index f6a04ad71e171f38d548bd5bd7bc5468528d55ed..89bbb7a3c423d4e459ef91a54b5d3ca318cb6f66 100644 --- a/packages/api/src/business/validations/titre-etape-updation-validate.test.ts +++ b/packages/api/src/business/validations/titre-etape-updation-validate.test.ts @@ -10,6 +10,7 @@ import { entrepriseIdValidator } from 'camino-common/src/entreprise' import { titreIdValidator } from 'camino-common/src/validators/titres' import { km2Validator } from 'camino-common/src/number' import { ApiFlattenEtape } from '../../api/_format/titres-etapes' +import { MachineInfo } from 'camino-common/src/machines' const etapeBrouillonValide: Omit<ApiFlattenEtape, 'id'> = { titulaires: { value: [], @@ -68,10 +69,13 @@ const etapeComplete: Omit<ApiFlattenEtape, 'id'> = { contenu: { arm: { mecanise: { value: true, heritee: true, etapeHeritee: { date: toCaminoDate('2022-01-01'), etapeTypeId: 'mfr', value: true } } } }, } const demarcheId = demarcheIdValidator.parse('demarcheId') +const machineInfoARM = MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse('2022-01-01')) +const machineInfoAXM = MachineInfo.withDate('axm', 'oct', demarcheId, firstEtapeDateValidator.parse('2022-01-01')) const titreDemarche: ITitreDemarche = { id: demarcheId, typeId: 'oct', titreId: titreIdValidator.parse('titreId'), + machineId: machineInfoARM.machineId ?? null, etapes: [ { date: toCaminoDate('2022-01-01'), @@ -149,7 +153,7 @@ describe('valide l’étape avant de l’enregistrer', () => { demarcheIdsConsentement: [], } - let errors = titreEtapeUpdationValidate(titreEtape, titreDemarche, titreARM, [], [], [], [], [], userSuper, firstEtapeDateValidator.parse('2022-01-01')) + let errors = titreEtapeUpdationValidate(titreEtape, titreDemarche.etapes ?? [], titreARM.demarches ?? [], [], [], [], [], [], userSuper, machineInfoARM) expect(errors).toMatchInlineSnapshot(` [ "une date peut-être spécifiée que sur une étape de décision", @@ -164,12 +168,8 @@ describe('valide l’étape avant de l’enregistrer', () => { "Il y a des documents d'entreprise obligatoires, mais il n'y a pas de titulaire", ] `) - // AXM - const titreAxm: Pick<ITitre, 'typeId'> = { - typeId: 'axm', - } - errors = titreEtapeUpdationValidate(titreEtape, titreDemarche, titreAxm, [], [], [], [], [], userSuper, firstEtapeDateValidator.parse('2022-01-01')) + errors = titreEtapeUpdationValidate(titreEtape, titreDemarche.etapes ?? [], [titreDemarche], [], [], [], [], [], userSuper, machineInfoAXM) expect(errors).toMatchInlineSnapshot(` [ "une date peut-être spécifiée que sur une étape de décision", @@ -190,11 +190,11 @@ describe('valide l’étape avant de l’enregistrer', () => { `) }) test('valide brouillon', () => { - const errors = titreEtapeUpdationValidate(etapeBrouillonValide, { ...titreDemarche, etapes: [] }, titreARM, [], [], [], [], [], userSuper, firstEtapeDateValidator.parse('2022-01-01')) + const errors = titreEtapeUpdationValidate(etapeBrouillonValide, [], [{ ...titreDemarche, etapes: [] }], [], [], [], [], [], userSuper, machineInfoARM) expect(errors).toStrictEqual([]) }) test('valide complète', () => { - const errors = titreEtapeUpdationValidate(etapeComplete, titreDemarche, titreARM, [{ etape_document_type_id: 'doe' }], [], [], [], [], userSuper, firstEtapeDateValidator.parse('2022-01-01')) + const errors = titreEtapeUpdationValidate(etapeComplete, titreDemarche.etapes ?? [], titreARM.demarches ?? [], [{ etape_document_type_id: 'doe' }], [], [], [], [], userSuper, machineInfoARM) expect(errors).toStrictEqual([]) }) test('invalide car on ne peut pas faire de mod sans men', () => { @@ -219,19 +219,19 @@ describe('valide l’étape avant de l’enregistrer', () => { etapeHeritee: null, }, }, - titreDemarche, - titreARM, + titreDemarche.etapes ?? [], + titreARM.demarches ?? [], [{ etape_document_type_id: 'doe' }], [], [], [], [], userSuper, - firstEtapeDateValidator.parse('2022-01-01') + machineInfoARM ) expect(errors).toMatchInlineSnapshot(` [ - "les étapes de la démarche machine octArm ne sont pas valides", + "les étapes de la démarche machine AncienLogigrammeOctroiARM ne sont pas valides", ] `) }) @@ -239,30 +239,30 @@ describe('valide l’étape avant de l’enregistrer', () => { test('valide complète avec héritage', () => { const errors = titreEtapeUpdationValidate( { ...etapeComplete, duree: { value: 12, heritee: true, etapeHeritee: { date: toCaminoDate('2022-01-01'), etapeTypeId: 'mfr', value: 12 } } }, - titreDemarche, - titreARM, + titreDemarche.etapes ?? [], + titreARM.demarches ?? [], [{ etape_document_type_id: 'doe' }], [], [], [], [], userSuper, - firstEtapeDateValidator.parse('2022-01-01') + machineInfoARM ) expect(errors).toStrictEqual([]) }) test('ne peut pas éditer les amodiataires sur une ARM', () => { const errors = titreEtapeUpdationValidate( { ...etapeComplete, amodiataires: { value: [entrepriseIdValidator.parse('entrepriseIdAmodiataire')], heritee: false, etapeHeritee: null } }, - titreDemarche, - titreARM, + titreDemarche.etapes ?? [], + titreARM.demarches ?? [], [{ etape_document_type_id: 'doe' }], [], [], [], [], userSuper, - firstEtapeDateValidator.parse('2022-01-01') + machineInfoARM ) expect(errors).toMatchInlineSnapshot(` [ diff --git a/packages/api/src/business/validations/titre-etape-updation-validate.ts b/packages/api/src/business/validations/titre-etape-updation-validate.ts index eba3f87162534e4550b4b8d1a222e6392fe1976c..2932ca06764d72c9d284b543d05e95523cb664b6 100644 --- a/packages/api/src/business/validations/titre-etape-updation-validate.ts +++ b/packages/api/src/business/validations/titre-etape-updation-validate.ts @@ -1,4 +1,4 @@ -import { ITitreEtape, ITitreDemarche, ITitre } from '../../types' +import { ITitreEtape, ITitreDemarche } from '../../types' import { titreDemarcheUpdatedEtatValidate } from './titre-demarche-etat-validate' import { contenuNumbersCheck } from './utils/contenu-numbers-check' @@ -14,32 +14,33 @@ import { isNotNullNorUndefined, isNullOrUndefined } from 'camino-common/src/type import { flattenContenuToSimpleContenu } from 'camino-common/src/sections' import { equalGeojson } from 'camino-common/src/perimetre' import { ApiFlattenEtape } from '../../api/_format/titres-etapes' -import { FirstEtapeDate } from 'camino-common/src/date' +import { MachineInfo } from 'camino-common/src/machines' +import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' export const titreEtapeUpdationValidate = ( etape: Pick<Partial<ApiFlattenEtape>, 'id'> & Omit<ApiFlattenEtape, 'id'>, - titreDemarche: ITitreDemarche, - titre: Pick<ITitre, 'typeId' | 'demarches'>, + etapes: ITitreEtape[], + demarches: ITitreDemarche[], documents: Pick<EtapeDocument, 'etape_document_type_id'>[], etapeAvis: Pick<EtapeAvis, 'avis_type_id'>[], entrepriseDocuments: Pick<EntrepriseDocument, 'entreprise_document_type_id' | 'entreprise_id'>[], sdomZones: SDOMZoneId[] | null | undefined, communes: CommuneId[] | null | undefined, user: User, - firstEtapeDate: FirstEtapeDate, + machineInfo: MachineInfo, titreEtapeOld?: ITitreEtape ): string[] => { const errors: string[] = [] - const sections = getSections(titre.typeId, titreDemarche.typeId, etape.typeId) + const sections = getSections(machineInfo, etape.typeId) if (!etape.duree.heritee) { - const editDuree = canEditDuree(titre.typeId, titreDemarche.typeId, user) + const editDuree = canEditDuree(machineInfo, user) if (editDuree.visibility === 'absent' && (etape.duree.value ?? 0) !== (titreEtapeOld?.duree ?? 0)) { errors.push(editDuree.message) } } - const editDates = canEditDates(titre.typeId, titreDemarche.typeId, etape.typeId, user) + const editDates = canEditDates(machineInfo, etape.typeId, user) if (editDates.visibility === 'absent') { if (!etape.dateDebut.heritee && (etape.dateDebut.value ?? '') !== (titreEtapeOld?.dateDebut ?? '')) { errors.push(editDates.message) @@ -49,21 +50,21 @@ export const titreEtapeUpdationValidate = ( } if (!etape.titulaires.heritee) { - const editTitulaires = canEditTitulaires(titre.typeId, titreDemarche.typeId, user) + const editTitulaires = canEditTitulaires(machineInfo, user) if (editTitulaires.visibility === 'absent' && entreprisesHaveChanged(etape.titulaires.value, titreEtapeOld?.titulaireIds ?? [])) { errors.push(editTitulaires.message) } } if (!etape.amodiataires.heritee) { - const editAmodiataires = canEditAmodiataires(titre.typeId, titreDemarche.typeId, user) + const editAmodiataires = canEditAmodiataires(machineInfo, user) if (editAmodiataires.visibility === 'absent' && entreprisesHaveChanged(etape.amodiataires.value, titreEtapeOld?.amodiataireIds ?? [])) { errors.push(editAmodiataires.message) } } if (!etape.perimetre.heritee) { - const editPerimetre = canEditPerimetre(titreDemarche.typeId, etape.typeId) + const editPerimetre = canEditPerimetre(machineInfo, etape.typeId) if (editPerimetre.visibility === 'absent' && !equalGeojson(etape.perimetre.value?.geojson4326Perimetre?.geometry ?? null, titreEtapeOld?.geojson4326Perimetre?.geometry)) { errors.push(editPerimetre.message) } @@ -85,7 +86,7 @@ export const titreEtapeUpdationValidate = ( } if ( - etape.typeId !== 'mfr' && + etape.typeId !== ETAPES_TYPES.demande && isNotNullNorUndefined(etape.contenu.arm?.mecanise) && etape.contenu.arm.mecanise.value === true && !etape.contenu.arm.mecanise.heritee && @@ -95,14 +96,14 @@ export const titreEtapeUpdationValidate = ( } } - const etapeValid = isEtapeValid(etape, titre.typeId, titreDemarche.typeId, titreDemarche.id, firstEtapeDate) + const etapeValid = isEtapeValid(etape, machineInfo) if (!etapeValid.valid) { errors.push(...etapeValid.errors) } // si l’étape n’est pas en cours de construction if (etape.isBrouillon === ETAPE_IS_NOT_BROUILLON) { - const etapeComplete = isEtapeComplete(etape, titre.typeId, titreDemarche.id, titreDemarche.typeId, documents, entrepriseDocuments, sdomZones, communes ?? [], etapeAvis, user, firstEtapeDate) + const etapeComplete = isEtapeComplete(etape, machineInfo, documents, entrepriseDocuments, sdomZones, communes ?? [], etapeAvis, user) if (!etapeComplete.valid) { errors.push(...etapeComplete.errors) } @@ -112,30 +113,30 @@ export const titreEtapeUpdationValidate = ( return errors } - return titreEtapeUpdationBusinessValidate(etape, titreDemarche, titre, isNotNullNorUndefined(communes) ? communes.map(communeId => ({ id: communeId })) : communes) + return titreEtapeUpdationBusinessValidate(etape, etapes, demarches, isNotNullNorUndefined(communes) ? communes.map(communeId => ({ id: communeId })) : communes, machineInfo) } const titreEtapeUpdationBusinessValidate = ( titreEtape: Pick<Partial<ApiFlattenEtape>, 'id'> & Pick<ApiFlattenEtape, 'statutId' | 'typeId' | 'date' | 'contenu' | 'perimetre' | 'isBrouillon' | 'concurrence' | 'demarcheIdsConsentement' | 'hasTitreFrom'>, - titreDemarche: ITitreDemarche, - titre: Pick<ITitre, 'typeId' | 'demarches'>, - communes: ITitreEtape['communes'] + etapes: ITitreEtape[], + demarches: ITitreDemarche[], + communes: ITitreEtape['communes'], + machineInfo: MachineInfo ) => { const errors = [] // 1. la date de l'étape est possible // en fonction de l'ordre des types d'étapes de la démarche const { valid, errors: demarcheUpdatedErrors } = titreDemarcheUpdatedEtatValidate( - titreDemarche.typeId, - titre, + machineInfo, + demarches, { ...titreEtape, contenu: flattenContenuToSimpleContenu(titreEtape.contenu), surface: titreEtape.perimetre.value?.surface ?? null, communes, }, - titreDemarche.id, - titreDemarche.etapes! + etapes ) if (!valid) { errors.push(...demarcheUpdatedErrors) diff --git a/packages/api/src/database/models/titres-demarches.ts b/packages/api/src/database/models/titres-demarches.ts index 7513cc7ef97aca0fce01098df69f3fa5bde31311..e8006319d538d7930ea047d49d2652fd284b1594 100644 --- a/packages/api/src/database/models/titres-demarches.ts +++ b/packages/api/src/database/models/titres-demarches.ts @@ -30,6 +30,7 @@ class TitresDemarches extends Model { description: { type: ['string', 'null'] }, demarcheDateDebut: { type: ['string', 'null'] }, demarcheDateFin: { type: ['string', 'null'] }, + machineId: { type: ['string', 'null'] }, archive: { type: 'boolean' }, }, } diff --git a/packages/api/src/database/queries/permissions/titres.test.integration.ts b/packages/api/src/database/queries/permissions/titres.test.integration.ts index f4622e57f12411d56b7b4de962d77c85ae0695be..b22bc06e4200eb27ac6ba6a61c9953bb72869a9b 100644 --- a/packages/api/src/database/queries/permissions/titres.test.integration.ts +++ b/packages/api/src/database/queries/permissions/titres.test.integration.ts @@ -13,11 +13,12 @@ import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' import { DemarcheStatutId } from 'camino-common/src/static/demarchesStatuts' import { EtapeStatutId } from 'camino-common/src/static/etapesStatuts' import { EtapeTypeId } from 'camino-common/src/static/etapesTypes' -import { toCaminoDate } from 'camino-common/src/date' +import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { entrepriseIdValidator } from 'camino-common/src/entreprise' import TitresDemarches from '../../models/titres-demarches' import TitresEtapes from '../../models/titres-etapes' import { ETAPE_IS_NOT_BROUILLON } from 'camino-common/src/etape' +import { MachineInfo } from 'camino-common/src/machines' console.info = vi.fn() console.error = vi.fn() @@ -58,6 +59,7 @@ describe('titresQueryModify', () => { { id: demarcheId, typeId: 'oct', + machineId: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse('2020-01-01')).machineId ?? null, }, { id: etapeId, @@ -99,6 +101,7 @@ describe('titresQueryModify', () => { { id: demarcheId, typeId: 'oct', + machineId: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse('2020-01-01')).machineId ?? null, }, { id: etapeId, @@ -154,6 +157,7 @@ describe('titresQueryModify', () => { id: demarcheId, typeId: demarcheTypeId, statutId: demarcheStatutId, + machineId: MachineInfo.withDate(titreTypeId, demarcheTypeId, demarcheId, firstEtapeDateValidator.parse('2020-01-01')).machineId ?? null, }, { id: etapeId, @@ -240,6 +244,7 @@ describe('titresQueryModify', () => { id: demarcheId, typeId: 'oct', statutId: 'ins', + machineId: MachineInfo.withDate(typeId, 'oct', demarcheId, firstEtapeDateValidator.parse('2020-01-01')).machineId ?? null, }, { id: etapeId, diff --git a/packages/api/src/database/queries/titres-demarches.ts b/packages/api/src/database/queries/titres-demarches.ts index b39e23155c3aabc4b7867ed615432a976e4fdb69..063976b4f05d85bcfa2eca71c97b3234d4d23814 100644 --- a/packages/api/src/database/queries/titres-demarches.ts +++ b/packages/api/src/database/queries/titres-demarches.ts @@ -314,13 +314,6 @@ export const titreDemarcheGet = async (titreDemarcheId: string, { fields }: { fi .first() } -/** - * Crée une nouvelle démarche - * @param titreDemarche - démarche à créer - * @returns la nouvelle démarche - */ -export const titreDemarcheCreate = async (titreDemarche: Omit<ITitreDemarche, 'id'>): Promise<ITitreDemarche> => TitresDemarches.query().insertAndFetch(titreDemarche) - export const titreDemarcheUpdate = async (id: DemarcheId, titreDemarche: Partial<DBTitresDemarches>): Promise<TitresDemarches> => { return TitresDemarches.query().patchAndFetchById(id, { ...titreDemarche, id }) } diff --git a/packages/api/src/database/queries/titres-etapes.queries.ts b/packages/api/src/database/queries/titres-etapes.queries.ts index ad17f27271fbf0d24b6d23df17fd93669cd6daa9..e4ca1e402973f76a5c0992d182c9fcd5d896afab 100644 --- a/packages/api/src/database/queries/titres-etapes.queries.ts +++ b/packages/api/src/database/queries/titres-etapes.queries.ts @@ -53,7 +53,7 @@ import { TitreTypeId, titreTypeIdValidator } from 'camino-common/src/static/titr import { isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, SimplePromiseFn } from 'camino-common/src/typescript-tools' import { CanReadDemarche } from '../../api/rest/permissions/demarches' import { newEtapeAvisId, newEtapeDocumentId } from '../models/_format/id-create' -import { caminoDateValidator, FirstEtapeDate, getCurrent } from 'camino-common/src/date' +import { caminoDateValidator, getCurrent } from 'camino-common/src/date' import { createLargeObject, CreateLargeObjectError, LargeObjectId, largeObjectIdValidator } from '../largeobjects' import { avisStatutIdValidator, avisVisibilityIdValidator } from 'camino-common/src/static/avisTypes' import { canReadAvis } from '../../api/rest/permissions/avis' @@ -62,13 +62,15 @@ import { etapeAvisStepIsComplete } from 'camino-common/src/permissions/etape-for import { CommuneId } from 'camino-common/src/static/communes' import { EtapeStatutId, etapeStatutIdValidator } from 'camino-common/src/static/etapesStatuts' import { contenuValidator, FlattenedContenu, heritageContenuValidator } from 'camino-common/src/etape-form' -import { DemarcheTypeId, demarcheTypeIdValidator } from 'camino-common/src/static/demarchesTypes' +import { demarcheTypeIdValidator } from 'camino-common/src/static/demarchesTypes' import { Effect, Option, pipe } from 'effect' import { CaminoError } from 'camino-common/src/zod-tools' import { callAndExit, shortCircuitError, zodParseEffectTyped } from '../../tools/fp-tools' import { TempDocumentName } from 'camino-common/src/document' -import { DemarcheId } from 'camino-common/src/demarche' import { autreDocumentTypeIdValidator, documentTypeIdValidator, isAutreDocument } from 'camino-common/src/static/documentsTypes' +import { MachineInfo } from 'camino-common/src/machines' +import { machineIdValidator } from 'camino-common/src/validators/machine' +import { demarcheIdValidator } from 'camino-common/src/demarche' export const insertTitreEtapeEntrepriseDocuments = ( pool: Pool, @@ -310,17 +312,12 @@ export const updateEtapeAvis = ( etapeAvis: EtapeAvisModification[], etapeTypeId: EtapeTypeId, etapeContenu: FlattenedContenu, - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - demarcheId: DemarcheId, - firstEtapeDate: FirstEtapeDate, + machineInfo: MachineInfo, communeIds: CommuneId[] ): Effect.Effect<Option.Option<never>, CaminoError<UpdateEtapeAvisErrors>> => { return Effect.Do.pipe( Effect.filterOrFail( - () => - isBrouillon === ETAPE_IS_BROUILLON || - etapeAvisStepIsComplete({ typeId: etapeTypeId, contenu: etapeContenu }, etapeAvis, titreTypeId, demarcheTypeId, demarcheId, firstEtapeDate, communeIds).valid, + () => isBrouillon === ETAPE_IS_BROUILLON || etapeAvisStepIsComplete({ typeId: etapeTypeId, contenu: etapeContenu }, etapeAvis, machineInfo, communeIds).valid, () => ({ message: avisIncomplets }) ), Effect.bind('avisInDb', () => effectDbQueryAndValidate(getAvisByEtapeIdQuery, { titre_etape_id }, pool, etapeAvisDbValidator)), @@ -595,6 +592,8 @@ const getEtapesWithAutomaticStatutValidator = z.object({ heritage_contenu: heritageContenuValidator, titre_type_id: titreTypeIdValidator, demarche_type_id: demarcheTypeIdValidator, + demarche_machine_id: machineIdValidator.nullable(), + demarche_id: demarcheIdValidator, }) type GetEtapesWithAutomaticStatutQuery = z.infer<typeof getEtapesWithAutomaticStatutValidator> @@ -611,7 +610,9 @@ const getEtapesWithAutomaticStatutDb = sql<Redefine<IGetEtapesWithAutomaticStatu te.statut_id as etape_statut_id, te.date, t.type_id as titre_type_id, - td.type_id as demarche_type_id + td.type_id as demarche_type_id, + td.machine_id as demarche_machine_id, + td.id as demarche_id from titres_etapes te join titres_demarches td on te.titre_demarche_id = td.id join titres t on td.titre_id = t.id diff --git a/packages/api/src/database/queries/titres-etapes.queries.types.ts b/packages/api/src/database/queries/titres-etapes.queries.types.ts index 80db6b69d4523b2da0744c909255061512136c84..cd3e4166cf66fe51b8ac22cd772284ab36924a61 100644 --- a/packages/api/src/database/queries/titres-etapes.queries.types.ts +++ b/packages/api/src/database/queries/titres-etapes.queries.types.ts @@ -276,6 +276,8 @@ export interface IGetEtapesWithAutomaticStatutDbParams { export interface IGetEtapesWithAutomaticStatutDbResult { contenu: Json | null; date: string; + demarche_id: string; + demarche_machine_id: string | null; demarche_type_id: string; etape_statut_id: string; heritage_contenu: Json | null; diff --git a/packages/api/src/database/queries/titres-utilisateurs.queries.ts b/packages/api/src/database/queries/titres-utilisateurs.queries.ts index 2f8d32faa6ddf4b9c79fcb5e8785112b09e4a0ca..fc828cbd9c8e35a11eebb696ba621f82ae3e8803 100644 --- a/packages/api/src/database/queries/titres-utilisateurs.queries.ts +++ b/packages/api/src/database/queries/titres-utilisateurs.queries.ts @@ -29,6 +29,7 @@ select t.titre_statut_id, td.type_id as demarche_type_id, td.slug as demarche_slug, + td.machine_id as machine_id, te.type_id as etape_type_id, te.slug as etape_slug, te.date as etape_date diff --git a/packages/api/src/database/queries/titres-utilisateurs.queries.types.ts b/packages/api/src/database/queries/titres-utilisateurs.queries.types.ts index 991b82f340b50510e770cb0b6b54e80d741de452..b6e8f64fc34c7b929a874f692490eb9e7ade59e4 100644 --- a/packages/api/src/database/queries/titres-utilisateurs.queries.types.ts +++ b/packages/api/src/database/queries/titres-utilisateurs.queries.types.ts @@ -10,6 +10,7 @@ export interface IGetTitresWithBrouillonsDbResult { etape_date: string; etape_slug: string | null; etape_type_id: string; + machine_id: string | null; titre_nom: string; titre_slug: string; titre_statut_id: string; diff --git a/packages/api/src/knex/migrations/20250325135645_add-column-machine-to-demarches.ts b/packages/api/src/knex/migrations/20250325135645_add-column-machine-to-demarches.ts new file mode 100644 index 0000000000000000000000000000000000000000..7c5203c78c70be5ce19e865e7a2c3eb379aeacce --- /dev/null +++ b/packages/api/src/knex/migrations/20250325135645_add-column-machine-to-demarches.ts @@ -0,0 +1,49 @@ +import { Knex } from 'knex' +import type { DemarcheId } from 'camino-common/src/demarche' +import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' +import type { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' +import type { TitreTypeId } from 'camino-common/src/static/titresTypes' +import type { FirstEtapeDate } from 'camino-common/src/date' +import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools' +import { MachineInfo } from 'camino-common/src/machines' + +export const up = async (knex: Knex): Promise<void> => { + await knex.raw('ALTER TABLE titres_demarches ADD COLUMN machine_id VARCHAR') + await knex.raw('CREATE INDEX titres_demarches_machine_id_index ON titres_demarches USING btree (machine_id)') + + const demarches: { rows: { id: DemarcheId; demarche_type_id: DemarcheTypeId; titre_type_id: TitreTypeId }[] } = await knex.raw( + `select td.id, td.type_id as demarche_type_id, t.type_id as titre_type_id from titres_demarches td join titres t on t.id = td.titre_id where td.archive is false` + ) + for (const demarche of demarches.rows) { + const firstEtapeDate: { + rows: { first_etape_date: FirstEtapeDate }[] + } = await knex.raw( + ` + select + te.date as first_etape_date + from + titres_demarches td + left join titres_etapes te on te.titre_demarche_id = td.id AND (te.type_id = :enregistrementDeLaDemandeId OR te.ordre = 1) AND te.archive IS FALSE + where (td.id = :idOrSlug + or td.slug = :idOrSlug) + and td.archive is false + order by te.ordre desc + LIMIT 1 + `, + { + enregistrementDeLaDemandeId: ETAPES_TYPES.enregistrementDeLaDemande, + idOrSlug: demarche.id, + } + ) + + if (firstEtapeDate.rows.length === 1 && isNotNullNorUndefined(firstEtapeDate.rows[0].first_etape_date)) { + const machineId = MachineInfo.withDate(demarche.titre_type_id, demarche.demarche_type_id, demarche.id, firstEtapeDate.rows[0].first_etape_date) + await knex.raw('UPDATE titres_demarches SET machine_id = :machineId WHERE id = :id', { + id: demarche.id, + machineId: isNotNullNorUndefined(machineId.machineId) ? machineId.machineId : null, + }) + } + } +} + +export const down = (): void => {} diff --git a/packages/api/src/pg-database.ts b/packages/api/src/pg-database.ts index 2767a32169ae7eb2385a6cce52d1b09dbb4f2af3..bc655a7507b5ab964b0c25693a3243e018e7e618 100644 --- a/packages/api/src/pg-database.ts +++ b/packages/api/src/pg-database.ts @@ -4,8 +4,8 @@ import type { Pool } from 'pg' import { z } from 'zod' import type { ZodType, ZodTypeDef } from 'zod' import { CaminoError } from 'camino-common/src/zod-tools' -import { zodParseEffect } from './tools/fp-tools' -import { Effect, Match, pipe } from 'effect' +import { zodParseEffectTyped } from './tools/fp-tools' +import { Effect, pipe } from 'effect' export type Redefine<T, P, O> = T extends { params: infer A; result: infer B } ? { inputs: keyof A; outputs: keyof B } extends { inputs: keyof P; outputs: keyof O } ? { inputs: keyof P; outputs: keyof O } extends { inputs: keyof A; outputs: keyof B } @@ -15,7 +15,7 @@ export type Redefine<T, P, O> = T extends { params: infer A; result: infer B } : { __camino_error: 'on a pas params et result' } /** - * @deprecated use newDbQueryAndValidate + * @deprecated use effectDbQueryAndValidate */ export const dbQueryAndValidate = async <Params, Result, T extends ZodType<Result, ZodTypeDef, unknown>>( query: TaggedQuery<{ params: Params; result: Result }>, @@ -53,15 +53,6 @@ export const effectDbQueryAndValidate = <Params, Result, T extends ZodType<Resul return { message: "Impossible d'exécuter la requête dans la base de données" as const, extra } }, }), - Effect.flatMap(result => - zodParseEffect(z.array(validator), result).pipe( - Effect.mapError(caminoError => - Match.value(caminoError.message).pipe( - Match.when('Problème de validation de données', () => ({ ...caminoError, message: 'Les données en base ne correspondent pas à ce qui est attendu' as const })), - Match.exhaustive - ) - ) - ) - ) + Effect.flatMap(result => zodParseEffectTyped(z.array(validator), result, 'Les données en base ne correspondent pas à ce qui est attendu' as const)) ) } diff --git a/packages/api/src/tools/demarches/definitions-check.ts b/packages/api/src/tools/demarches/definitions-check.ts index 384407292c6082bfe568b00fb6442a1a61119257..93087d64f41b4cc20d06b15e463a15f3700c9cfd 100644 --- a/packages/api/src/tools/demarches/definitions-check.ts +++ b/packages/api/src/tools/demarches/definitions-check.ts @@ -4,7 +4,7 @@ import { userSuper } from '../../database/user-super' import { getTitreTypeType, getDomaineId } from 'camino-common/src/static/titresTypes' import { isNotNullNorUndefinedNorEmpty, onlyUnique } from 'camino-common/src/typescript-tools' import { DemarcheId } from 'camino-common/src/demarche' -import { demarchesDefinitions } from 'camino-common/src/machines' +import { demarchesDefinitions, MachineInfo } from 'camino-common/src/machines' const demarchesValidate = async () => { const demarchesIdsAlreadyChecked: Set<DemarcheId> = new Set() @@ -32,7 +32,12 @@ const demarchesValidate = async () => { if (isNotNullNorUndefinedNorEmpty(demarche.etapes)) { try { const sortedEtapes = demarche.etapes!.toSorted((a, b) => (a.ordre ?? 0) - (b.ordre ?? 0)) - const { valid, errors } = titreDemarcheUpdatedEtatValidate(demarche.typeId, demarche.titre!, sortedEtapes![0], demarche.id, sortedEtapes!) + const machineInfo = MachineInfo.withMachineId(demarche.titre!.typeId, demarche.typeId, demarche.id, demarche.machineId) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente : ${machineInfo.error}`) + } + + const { valid, errors } = titreDemarcheUpdatedEtatValidate(machineInfo.value, demarche.titre!.demarches!, sortedEtapes![0], sortedEtapes!) if (!valid) { errorsTotal.push(`https://camino.beta.gouv.fr/demarches/${demarche.slug} => démarche "${demarche.typeId}" : ${errors}`) diff --git a/packages/api/src/tools/demarches/tde-check.ts b/packages/api/src/tools/demarches/tde-check.ts index 5dc63a8832b45f6e8081d5a4f915099ab4e8ba78..7b710da23e0c697fdbf873bf99c528284b860577 100644 --- a/packages/api/src/tools/demarches/tde-check.ts +++ b/packages/api/src/tools/demarches/tde-check.ts @@ -2,9 +2,7 @@ import { EtapesTypes } from 'camino-common/src/static/etapesTypes' import { isTDEExist } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/index' import { titresDemarchesGet } from '../../database/queries/titres-demarches' import { userSuper } from '../../database/user-super' -import { isNotNullNorUndefined, isNullOrUndefined } from 'camino-common/src/typescript-tools' -import { CaminoMachineId, machineIdFind } from 'camino-common/src/machines' -import { demarcheEnregistrementDemandeDateFind } from 'camino-common/src/demarche' +import { isNullOrUndefined } from 'camino-common/src/typescript-tools' export const titreTypeDemarcheTypeEtapeTypeCheck = async (): Promise<number> => { console.info() @@ -26,13 +24,7 @@ export const titreTypeDemarcheTypeEtapeTypeCheck = async (): Promise<number> => let errorsNb = 0 demarches.forEach(d => { - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(d.etapes) - let machineId: CaminoMachineId | undefined - if (isNotNullNorUndefined(firstEtapeDate)) { - machineId = machineIdFind(d.titre!.typeId, d.typeId, d.id, firstEtapeDate) - } - - if (isNullOrUndefined(machineId)) { + if (isNullOrUndefined(d.machineId)) { d.etapes?.forEach(({ typeId }) => { if (!isTDEExist(d.titre!.typeId, d.typeId, typeId)) { console.info(`erreur sur le titre https://camino.beta.gouv.fr/titres/${d.titre!.id}, TDE inconnu ${d.titre!.typeId} ${d.typeId} ${typeId} (${EtapesTypes[typeId].nom})`) diff --git a/packages/api/src/tools/demarches/tests-creation.ts b/packages/api/src/tools/demarches/tests-creation.ts index eee632cb287b3d3bf455270a0a7c8e3b214cb260..6bcdc650f6a98e8ed3216dcb5ccba35578e44628 100644 --- a/packages/api/src/tools/demarches/tests-creation.ts +++ b/packages/api/src/tools/demarches/tests-creation.ts @@ -9,11 +9,12 @@ import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' import { toCommuneId } from 'camino-common/src/static/communes' import { isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefined, isNullOrUndefinedOrEmpty } from 'camino-common/src/typescript-tools' import { getDomaineId, getTitreTypeType, TitreTypeId } from 'camino-common/src/static/titresTypes' -import { CaminoMachineId, demarchesDefinitions, machineIdFind } from 'camino-common/src/machines' -import { getMachineFromId } from '../../business/rules-demarches/machines' -import { demarcheEnregistrementDemandeDateFind, DemarcheId, demarcheIdValidator } from 'camino-common/src/demarche' +import { demarchesDefinitions, MachineInfo } from 'camino-common/src/machines' +import { DemarcheId, demarcheIdValidator } from 'camino-common/src/demarche' import { DemarcheStatus, getPhase } from '../../business/rules-demarches/machine-helper' import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' +import { ApiMachineInfo, demarcheEnregistrementDemandeDateFind } from '../../business/rules-demarches/machines' +import { CaminoMachineId } from 'camino-common/src/validators/machine' export type DemarcheWithEtapeForMachinesTest = { id: DemarcheId @@ -48,14 +49,7 @@ const writeEtapesForTest = async () => { const lesDemarchesFiltres = demarches .filter(demarche => isNotNullNorUndefinedNorEmpty(demarche.etapes)) - .filter(demarche => { - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(demarche.etapes) - let machineId: CaminoMachineId | undefined - if (isNotNullNorUndefined(firstEtapeDate)) { - machineId = machineIdFind(demarche.titre!.typeId, demarche.typeId, demarche.id, firstEtapeDate) - } - return machineId === demarcheDefinition.machineId - }) + .filter(demarche => demarche.machineId === demarcheDefinition.machineId) .toSorted((a, b) => a.titreId.localeCompare(b.titreId)) toutesLesEtapes.push( @@ -89,20 +83,25 @@ const writeEtapesForTest = async () => { const firstSaisineDate = etapes.find(etape => etape.etapeTypeId === ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives)?.date ?? etapes[0].date const decalageJour = daysBetween(firstSaisineDate, setDayInMonth(firstSaisineDate, Math.floor(Math.random() * 28))) let statut - const machine = getMachineFromId({ machineId: demarcheDefinition.machineId, titreTypeId: demarche.titre!.typeId, demarcheTypeId: demarche.typeId }) + const machineInfo = MachineInfo.withMachineId(demarche.titre!.typeId, demarche.typeId, demarche.id, demarche.machineId) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente : ${machineInfo.error}`) + } + + const machine = new ApiMachineInfo(machineInfo.value) try { - if (isNullOrUndefined(machine)) { + if (isNullOrUndefined(machine.machine)) { console.warn('machine non trouvée') } else { - if (!machine.isEtapesOk(etapes)) { - etapes.splice(0, etapes.length, ...machine.orderMachine(etapes)) - if (!machine.isEtapesOk(etapes)) { + if (!machine.machine.isEtapesOk(etapes)) { + etapes.splice(0, etapes.length, ...machine.machine.orderMachine(etapes)) + if (!machine.machine.isEtapesOk(etapes)) { console.warn(`https://camino.beta.gouv.fr/demarches/${demarche.slug} => démarche N*${index} "${demarcheDefinition.titreTypeIds.join(' ou ')}/${demarche.typeId}"`) - console.warn(machine.interpretMachine(etapes)) + console.warn(machine.machine.interpretMachine(etapes)) return null } } - statut = machine.demarcheStatut(etapes) + statut = machine.machine.demarcheStatut(etapes) const phase = getPhase(statut) if ((phase?.debut ?? null) !== demarche.demarcheDateDebut || (phase?.fin ?? null) !== demarche.demarcheDateFin) { @@ -127,12 +126,12 @@ const writeEtapesForTest = async () => { console.warn('pas de date de début, on ignore') return null } - if (machineIdFind(demarche.titre!.typeId, demarche.typeId, demarche.id, demarcheDebut) !== demarcheDefinition.machineId) { + if (MachineInfo.withDate(demarche.titre!.typeId, demarche.typeId, demarche.id, demarcheDebut).machineId !== demarcheDefinition.machineId) { console.warn('le décalage de jour fait sortir de la machine, on ignore') return null } - return isNullOrUndefined(machine) + return isNullOrUndefined(machine.machine) ? null : { id: demarcheIdValidator.parse(`${index}`), @@ -140,7 +139,7 @@ const writeEtapesForTest = async () => { demarcheTypeId: demarche.typeId, etapes: etapesAnonymes, machineId: demarcheDefinition.machineId, - statut: machine.demarcheStatut(etapesAnonymes), + statut: machine.machine.demarcheStatut(etapesAnonymes), } }) )) diff --git a/packages/api/src/tools/etapes/etapes-complete-check.ts b/packages/api/src/tools/etapes/etapes-complete-check.ts index da926780940e537f398ad206ab606e503841faa4..298417dd55617cbe54f01859c7c987b9b15e85fb 100644 --- a/packages/api/src/tools/etapes/etapes-complete-check.ts +++ b/packages/api/src/tools/etapes/etapes-complete-check.ts @@ -1,7 +1,7 @@ import { titresDemarchesGet } from '../../database/queries/titres-demarches' import { userSuper } from '../../database/user-super' import { isNotNullNorUndefinedNorEmpty, isNullOrUndefined } from 'camino-common/src/typescript-tools' -import { demarcheEnregistrementDemandeDateFind, DemarcheId } from 'camino-common/src/demarche' +import { DemarcheId } from 'camino-common/src/demarche' import { isEtapeComplete } from 'camino-common/src/permissions/titres-etapes' import { iTitreEtapeToFlattenEtape } from '../../api/_format/titres-etapes' import { callAndExit } from '../fp-tools' @@ -13,6 +13,7 @@ import { titreEtapeGet } from '../../database/queries/titres-etapes' import { EtapesTypes } from 'camino-common/src/static/etapesTypes' import { ETAPE_HERITAGE_PROPS } from 'camino-common/src/heritage' import { dateAddMonths, getCurrent, isBefore, setDayInMonth } from 'camino-common/src/date' +import { MachineInfo } from 'camino-common/src/machines' const dateEtapeRecente = setDayInMonth(dateAddMonths(getCurrent(), -8), 1) const etapesValidate = async (pool: Pool, demarcheIds?: DemarcheId[]) => { @@ -35,7 +36,11 @@ const etapesValidate = async (pool: Pool, demarcheIds?: DemarcheId[]) => { if (isNotNullNorUndefinedNorEmpty(demarche.etapes)) { try { const sortedEtapes = demarche.etapes!.toSorted((a, b) => (a.ordre ?? 0) - (b.ordre ?? 0)) - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(demarche.etapes) + const machineInfo = MachineInfo.withMachineId(titreTypeId, demarche.typeId, demarche.id, demarche.machineId) + if (!machineInfo.valid) { + throw new Error(`La machine associée à la démarche est incohérente : ${machineInfo.error}`) + } + for (const etapeSansHeritage of sortedEtapes) { let etape = etapeSansHeritage if (EtapesTypes[etapeSansHeritage.typeId].fondamentale) { @@ -49,7 +54,7 @@ const etapesValidate = async (pool: Pool, demarcheIds?: DemarcheId[]) => { } } if (etape.isBrouillon === ETAPE_IS_NOT_BROUILLON) { - const flattenEtape = await callAndExit(iTitreEtapeToFlattenEtape(etape)) + const flattenEtape = await callAndExit(iTitreEtapeToFlattenEtape(machineInfo.value, etape)) const documents = await callAndExit( getDocumentsByEtapeId( etape.id, @@ -86,19 +91,7 @@ const etapesValidate = async (pool: Pool, demarcheIds?: DemarcheId[]) => { } ) ) - const { valid, errors } = isEtapeComplete( - flattenEtape, - titreTypeId, - demarche.id, - demarche.typeId, - documents, - entrepriseDocuments, - etape.sdomZones, - etape.communes?.map(({ id }) => id) ?? [], - etapeAvis, - userSuper, - firstEtapeDate - ) + const { valid, errors } = isEtapeComplete(flattenEtape, machineInfo.value, documents, entrepriseDocuments, etape.sdomZones, etape.communes?.map(({ id }) => id) ?? [], etapeAvis, userSuper) if (!valid) { const errorMessage = `https://camino.beta.gouv.fr/etapes/${etape.slug} => etape "${etape.typeId}" : ${errors}` diff --git a/packages/api/src/types.ts b/packages/api/src/types.ts index daa20429336353f9121301bc8c2a2b5103dc74f8..41d0de0a475510e0287df9eca84a6b433b8505d9 100644 --- a/packages/api/src/types.ts +++ b/packages/api/src/types.ts @@ -32,6 +32,7 @@ import { KM2 } from 'camino-common/src/number' import { HttpStatus } from 'camino-common/src/http' import { CaminoError } from 'camino-common/src/zod-tools' import { TitreEtapeForMachine } from './business/rules-demarches/machine-common' +import { CaminoMachineId } from 'camino-common/src/validators/machine' export const TitreEtapesTravauxTypes = { AvisDesServicesEtCommissionsConsultatives: 'asc', @@ -216,6 +217,7 @@ export interface ITitreDemarche { demarcheDateFin?: CaminoDate | null publicLecture?: boolean | null entreprisesLecture?: boolean | null + machineId: CaminoMachineId | null etapes?: ITitreEtape[] } diff --git a/packages/api/tests/_utils/administrations-permissions.ts b/packages/api/tests/_utils/administrations-permissions.ts index 2d6264f300ba4b075a9dbdb53d649e2cb2455c60..678cccfc868b63d96dfdfa9a6d6dfc25c317d71a 100644 --- a/packages/api/tests/_utils/administrations-permissions.ts +++ b/packages/api/tests/_utils/administrations-permissions.ts @@ -8,7 +8,7 @@ import options from '../../src/database/queries/_options' import { newDemarcheId, newTitreId, newEtapeId, idGenerate } from '../../src/database/models/_format/id-create' import { TitreTypeId } from 'camino-common/src/static/titresTypes' import { getDocuments } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/documents' -import { EtapeTypeId } from 'camino-common/src/static/etapesTypes' +import { ETAPES_TYPES, EtapeTypeId } from 'camino-common/src/static/etapesTypes' import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { expect } from 'vitest' import { AdministrationId, sortedAdministrations } from 'camino-common/src/static/administrations' @@ -28,6 +28,9 @@ import { exhaustiveCheck, isNotNullNorUndefined, isNullOrUndefined } from 'camin import { HTTP_STATUS } from 'camino-common/src/http' import { insertTitreGraph } from '../integration-test-helper' import { IS_ARM_NON_MECANISE } from 'camino-common/src/static/mecanise' +import { MachineInfo } from 'camino-common/src/machines' +import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' +import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' const dir = `${process.cwd()}/files/tmp/` @@ -178,9 +181,13 @@ export const creationCheck = async (pool: Pool, administrationId: string, creer: throw new Error('pour typescript') } - const etapeTypeId = 'mfr' + const etapeTypeId = ETAPES_TYPES.demande - const sections = getSections(titreTypeId, demarche.typeId, etapeTypeId) + const machineInfo = MachineInfo.withMachineId(titreTypeId, demarche.typeId, demarche.id, demarche.machineId) + if (!machineInfo.valid) { + throw new Error(machineInfo.error) + } + const sections = getSections(machineInfo.value, etapeTypeId) const heritageContenu = sections.reduce((acc, section) => { if (!acc[section.id]) { @@ -215,9 +222,9 @@ export const creationCheck = async (pool: Pool, administrationId: string, creer: return acc }, {} as any) - const etapeDate = toCaminoDate('2022-01-01') - const documentTypesIds = getDocuments(titreTypeId, demarche.typeId, etapeTypeId, firstEtapeDateValidator.parse(etapeDate), demarche.id, [], IS_ARM_NON_MECANISE) + + const documentTypesIds = getDocuments(machineInfo.value, etapeTypeId, [], IS_ARM_NON_MECANISE) .filter(({ optionnel }) => !optionnel) .map(({ id }) => id) const etapeDocuments = [] @@ -321,14 +328,15 @@ const titreBuild = ( { id: newDemarcheId(`${titreId}-demarche-id`), titreId, - typeId: 'oct', + typeId: DEMARCHES_TYPES_IDS.Octroi, + machineId: MachineInfo.withDate(titreTypeId, DEMARCHES_TYPES_IDS.Octroi, newDemarcheId(`${titreId}-demarche-id`), firstEtapeDateValidator.parse('2020-01-01')).machineId ?? null, etapes: [ { id: newEtapeId(`${titreId}-demarche-id-etape-id`), - typeId: etapeTypeId || 'mcr', + typeId: etapeTypeId || ETAPES_TYPES.recevabiliteDeLaDemande, ordre: 0, titreDemarcheId: newDemarcheId(`${titreId}-demarche-id`), - statutId: 'enc', + statutId: ETAPES_STATUTS.EN_COURS, isBrouillon: ETAPE_IS_NOT_BROUILLON, date: toCaminoDate('2020-01-01'), administrationsLocales: administrationIdLocale ? [administrationIdLocale] : [], diff --git a/packages/api/tests/_utils/index.ts b/packages/api/tests/_utils/index.ts index 702a8a7f4a4ab8a00f8b550e7c889c0db3179d56..2fd0eb99613049a51924ee93e0402c1b99884eb4 100644 --- a/packages/api/tests/_utils/index.ts +++ b/packages/api/tests/_utils/index.ts @@ -28,6 +28,11 @@ import { idUserKeycloakRecognised } from '../keycloak' import { isNotNullNorUndefined, isNullOrUndefined } from 'camino-common/src/typescript-tools' import { config } from '../../src/config/index' import { createUtilisateur, getUtilisateurById } from '../../src/database/queries/utilisateurs.queries' +import { MachineInfo } from 'camino-common/src/machines' +import { DemarcheId } from 'camino-common/src/demarche' +import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' +import { TitreTypeId } from 'camino-common/src/static/titresTypes' +import { CaminoMachineId } from 'camino-common/src/validators/machine' export const queryImport = (nom: string): string => fs @@ -132,6 +137,14 @@ const jwtSet = async (pool: Pool, req: request.Test, user: TestUser | undefined) return req } +export const throwableMachineInfoForTestsOnly = (titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId, demarcheId: DemarcheId, machineId: CaminoMachineId | null): MachineInfo => { + const value = MachineInfo.withMachineId(titreTypeId, demarcheTypeId, demarcheId, machineId) + if (!value.valid) { + throw new Error(value.error) + } + return value.value +} + export const userGenerate = async (pool: Pool, user: TestUser): Promise<UserNotNull> => { let idToBuild = 'super' diff --git a/packages/api/vitest.integration.config.ts b/packages/api/vitest.integration.config.ts index 8ddfe9ba1f14e4658d4d325ce7d948e323881d65..e661c3e418ebf69aeec81a84ae5aea4bfeb20efe 100644 --- a/packages/api/vitest.integration.config.ts +++ b/packages/api/vitest.integration.config.ts @@ -20,8 +20,8 @@ export default defineConfig({ name: 'integration', include: ['**/*.test.integration.ts'], setupFiles: path.resolve(__dirname, './tests/vitestSetup.ts'), - testTimeout: 10000, - hookTimeout: 45000, + testTimeout: 20_000, + hookTimeout: 60_000, env: testEnv, pool: 'threads', ...poolOptions, diff --git a/packages/common/src/avisTypes.test.ts b/packages/common/src/avisTypes.test.ts index 66f3d0d0f6020970901709e8d28b96b76750b7cb..dfb6a7b5a134440ca65e6de15e8a89bdc83ed052 100644 --- a/packages/common/src/avisTypes.test.ts +++ b/packages/common/src/avisTypes.test.ts @@ -7,21 +7,15 @@ import { DEMARCHES_TYPES_IDS } from './static/demarchesTypes' import { ETAPES_TYPES } from './static/etapesTypes' import { IS_ARM_MECANISE } from './static/mecanise' import { TITRES_TYPES_IDS } from './static/titresTypes' +import { MachineInfo } from './machines' describe('getAvisType', () => { const demarcheId = demarcheIdValidator.parse('demarcheId') const firstEtapeDate = firstEtapeDateValidator.parse('2022-01-01') test("les avis obligatoires deviennent optionnels si on n'a pas de machine", () => { - const avis = getAvisTypes( - ETAPES_TYPES.demande, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheId, - firstEtapeDateValidator.parse('1980-11-01'), - [], - IS_ARM_MECANISE - ) + const machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('1980-11-01')) + const avis = getAvisTypes(ETAPES_TYPES.demande, machineInfo, [], IS_ARM_MECANISE) expect(avis).toMatchInlineSnapshot(` { "avisDeLaMissionAutoriteEnvironnementale": { @@ -37,23 +31,21 @@ describe('getAvisType', () => { }) test("avis de l'office national des forêts est optionnel pour la procédure spécifique", () => { - const avis = getAvisTypes( - ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheId, - firstEtapeDateValidator.parse('2024-11-01'), - [], - IS_ARM_MECANISE - ) + const machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2024-11-01')) + expect(machineInfo.machineId).toBe('ProcedureSpecifique') + const avis = getAvisTypes(ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, machineInfo, [], IS_ARM_MECANISE) expect(avis.avisOfficeNationalDesForets?.optionnel).toBe(true) }) test("avis au cas par cas et avis du propriétaire du sol sont obligatoires pour les demandes d'ARM mécanisée de la procédure spécifique", () => { - expect(getAvisTypes(ETAPES_TYPES.demande, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate, [], IS_ARM_MECANISE)).toMatchInlineSnapshot( - `{}` - ) + const machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate) + expect(getAvisTypes(ETAPES_TYPES.demande, machineInfo, [], IS_ARM_MECANISE)).toMatchInlineSnapshot(`{}`) expect( - getAvisTypes(ETAPES_TYPES.demande, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2025-01-01'), [], IS_ARM_MECANISE) + getAvisTypes( + ETAPES_TYPES.demande, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2025-01-01')), + [], + IS_ARM_MECANISE + ) ).toMatchInlineSnapshot(` { "avisCasParCas": { @@ -68,8 +60,8 @@ describe('getAvisType', () => { `) }) test('les avis CGE et AE sont obligatoires pour la machine spécifique', () => { - expect(getAvisTypes(ETAPES_TYPES.saisinesEtAvisCGE_AE, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate, [], IS_ARM_MECANISE)) - .toMatchInlineSnapshot(` + let machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate) + expect(getAvisTypes(ETAPES_TYPES.saisinesEtAvisCGE_AE, machineInfo, [], IS_ARM_MECANISE)).toMatchInlineSnapshot(` { "autreAvis": { "id": "autreAvis", @@ -85,17 +77,8 @@ describe('getAvisType', () => { }, } `) - expect( - getAvisTypes( - ETAPES_TYPES.saisinesEtAvisCGE_AE, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheId, - firstEtapeDateValidator.parse('2025-01-01'), - [], - IS_ARM_MECANISE - ) - ).toMatchInlineSnapshot(` + machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2025-01-01')) + expect(getAvisTypes(ETAPES_TYPES.saisinesEtAvisCGE_AE, machineInfo, [], IS_ARM_MECANISE)).toMatchInlineSnapshot(` { "autreAvis": { "id": "autreAvis", @@ -113,8 +96,8 @@ describe('getAvisType', () => { `) }) test('getAvisType', () => { - expect(getAvisTypes(ETAPES_TYPES.avisDesCollectivites, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate, [], IS_ARM_MECANISE)) - .toMatchInlineSnapshot(` + let machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate) + expect(getAvisTypes(ETAPES_TYPES.avisDesCollectivites, machineInfo, [], IS_ARM_MECANISE)).toMatchInlineSnapshot(` { "avisDUneCollectivite": { "id": "avisDUneCollectivite", @@ -122,20 +105,8 @@ describe('getAvisType', () => { }, } `) - expect(getAvisTypes(ETAPES_TYPES.demande, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate, [], IS_ARM_MECANISE)).toMatchInlineSnapshot( - `{}` - ) - expect( - getAvisTypes( - ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheId, - firstEtapeDate, - [], - IS_ARM_MECANISE - ) - ).toMatchInlineSnapshot(` + expect(getAvisTypes(ETAPES_TYPES.demande, machineInfo, [], IS_ARM_MECANISE)).toMatchInlineSnapshot(`{}`) + expect(getAvisTypes(ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, machineInfo, [], IS_ARM_MECANISE)).toMatchInlineSnapshot(` { "autreAvis": { "id": "autreAvis", @@ -207,17 +178,7 @@ describe('getAvisType', () => { }, } `) - expect( - getAvisTypes( - ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheId, - firstEtapeDate, - [communeIdValidator.parse('97302')], - IS_ARM_MECANISE - ) - ).toMatchInlineSnapshot(` + expect(getAvisTypes(ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, machineInfo, [communeIdValidator.parse('97302')], IS_ARM_MECANISE)).toMatchInlineSnapshot(` { "autreAvis": { "id": "autreAvis", @@ -297,17 +258,8 @@ describe('getAvisType', () => { }, } `) - expect( - getAvisTypes( - ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheId, - firstEtapeDate, - [communeIdValidator.parse('97302')], - IS_ARM_MECANISE - ) - ).toMatchInlineSnapshot(` + machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate) + expect(getAvisTypes(ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, machineInfo, [communeIdValidator.parse('97302')], IS_ARM_MECANISE)).toMatchInlineSnapshot(` { "autreAvis": { "id": "autreAvis", @@ -391,17 +343,9 @@ describe('getAvisType', () => { }, } `) - expect( - getAvisTypes( - ETAPES_TYPES.consultationDesAdministrationsCentrales, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS, - DEMARCHES_TYPES_IDS.Octroi, - demarcheId, - firstEtapeDate, - [], - IS_ARM_MECANISE - ) - ).toMatchInlineSnapshot(` + machineInfo = MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_GRANULATS_MARINS, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate) + + expect(getAvisTypes(ETAPES_TYPES.consultationDesAdministrationsCentrales, machineInfo, [], IS_ARM_MECANISE)).toMatchInlineSnapshot(` { "autreAvis": { "id": "autreAvis", diff --git a/packages/common/src/avisTypes.ts b/packages/common/src/avisTypes.ts index 6365eff4e5b47f723dc68c5ad09711e045c5c362..983aeb04e41dd84e54fd1ae94476bfe474b18490 100644 --- a/packages/common/src/avisTypes.ts +++ b/packages/common/src/avisTypes.ts @@ -1,34 +1,22 @@ -import { FirstEtapeDate } from './date' -import { DemarcheId } from './demarche' -import { isProcedureOuverte, machineIdFind } from './machines' +import { isProcedureOuverte, MachineInfo } from './machines' import { AvisTypeId, AVIS_TYPES, isAvisTypeId } from './static/avisTypes' import { CommuneId } from './static/communes' -import { DemarcheTypeId } from './static/demarchesTypes' import { toDepartementId, DEPARTEMENT_IDS } from './static/departement' import { ETAPES_TYPES, EtapeTypeId } from './static/etapesTypes' import { IsArmMecanise, IS_ARM_NON_MECANISE } from './static/mecanise' -import { TitreTypeId, TITRES_TYPES_IDS, TitresTypes } from './static/titresTypes' +import { TITRES_TYPES_IDS, TitresTypes } from './static/titresTypes' import { TITRES_TYPES_TYPES_IDS } from './static/titresTypesTypes' import { isNotNullNorUndefined } from './typescript-tools' type GetAvisType = Partial<{ [key in AvisTypeId]: { id: key; optionnel: boolean } }> -export const getAvisTypes = ( - etapeTypeId: EtapeTypeId, - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - demarcheId: DemarcheId, - firstEtapeDate: FirstEtapeDate, - communeIds: CommuneId[], - isArmMecanise: IsArmMecanise -): GetAvisType => { +export const getAvisTypes = (etapeTypeId: EtapeTypeId, machineInfo: MachineInfo, communeIds: CommuneId[], isArmMecanise: IsArmMecanise): GetAvisType => { const avis: GetAvisType = {} - const machineId = machineIdFind(titreTypeId, demarcheTypeId, demarcheId, firstEtapeDate) if (etapeTypeId === ETAPES_TYPES.demande) { - if (titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX) { + if (machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX) { avis[AVIS_TYPES.avisProprietaireDuSol] = { id: AVIS_TYPES.avisProprietaireDuSol, optionnel: false } avis[AVIS_TYPES.avisDeLaMissionAutoriteEnvironnementale] = { id: AVIS_TYPES.avisDeLaMissionAutoriteEnvironnementale, optionnel: false } - } else if (titreTypeId === TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX && machineId === 'ProcedureSpecifique') { + } else if (machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX && machineInfo.machineId === 'ProcedureSpecifique') { avis[AVIS_TYPES.avisCasParCas] = { id: AVIS_TYPES.avisCasParCas, optionnel: isArmMecanise === IS_ARM_NON_MECANISE } avis[AVIS_TYPES.avisProprietaireDuSol] = { id: AVIS_TYPES.avisProprietaireDuSol, optionnel: false } } @@ -52,7 +40,7 @@ export const getAvisTypes = ( avis[AVIS_TYPES.avisCaisseGeneraleSecuriteSociale] = { id: AVIS_TYPES.avisCaisseGeneraleSecuriteSociale, optionnel: true } avis[AVIS_TYPES.autreAvis] = { id: AVIS_TYPES.autreAvis, optionnel: true } // L'avis de l'onf est obligatoire que pour les ARM - avis[AVIS_TYPES.avisOfficeNationalDesForets] = { id: AVIS_TYPES.avisOfficeNationalDesForets, optionnel: machineId === 'ProcedureSpecifique' || titreTypeId !== 'arm' } + avis[AVIS_TYPES.avisOfficeNationalDesForets] = { id: AVIS_TYPES.avisOfficeNationalDesForets, optionnel: machineInfo.machineId === 'ProcedureSpecifique' || machineInfo.titreTypeId !== 'arm' } avis[AVIS_TYPES.expertiseOfficeNationalDesForets] = { id: AVIS_TYPES.expertiseOfficeNationalDesForets, optionnel: true } // TODO 2024-05-14: rendre obligatoire pour les PNMs quand ces derniers seront implémentés avis[AVIS_TYPES.avisParcNaturelMarin] = { id: AVIS_TYPES.avisParcNaturelMarin, optionnel: true } @@ -63,18 +51,18 @@ export const getAvisTypes = ( } // TODO 2024-06-18 Normalement c'est obligatoire si avis propriétaire du sol est favorable avec réserve, optionnel pour le moment - if (TitresTypes[titreTypeId].typeId === TITRES_TYPES_TYPES_IDS.AUTORISATION_D_EXPLOITATION) { + if (TitresTypes[machineInfo.titreTypeId].typeId === TITRES_TYPES_TYPES_IDS.AUTORISATION_D_EXPLOITATION) { avis[AVIS_TYPES.confirmationAccordProprietaireDuSol] = { id: AVIS_TYPES.confirmationAccordProprietaireDuSol, optionnel: true } } } else if (etapeTypeId === ETAPES_TYPES.saisinesEtAvisCGE_AE) { - avis[AVIS_TYPES.avisDuConseilGeneralDeLEconomie] = { id: AVIS_TYPES.avisDuConseilGeneralDeLEconomie, optionnel: machineId !== 'ProcedureSpecifique' } - avis[AVIS_TYPES.avisDeLaMissionAutoriteEnvironnementale] = { id: AVIS_TYPES.avisDeLaMissionAutoriteEnvironnementale, optionnel: machineId !== 'ProcedureSpecifique' } + avis[AVIS_TYPES.avisDuConseilGeneralDeLEconomie] = { id: AVIS_TYPES.avisDuConseilGeneralDeLEconomie, optionnel: machineInfo.machineId !== 'ProcedureSpecifique' } + avis[AVIS_TYPES.avisDeLaMissionAutoriteEnvironnementale] = { id: AVIS_TYPES.avisDeLaMissionAutoriteEnvironnementale, optionnel: machineInfo.machineId !== 'ProcedureSpecifique' } avis[AVIS_TYPES.autreAvis] = { id: AVIS_TYPES.autreAvis, optionnel: true } } else if ([ETAPES_TYPES.consultationDesAdministrationsCentrales, ETAPES_TYPES.expertises].includes(etapeTypeId)) { avis[AVIS_TYPES.autreAvis] = { id: AVIS_TYPES.autreAvis, optionnel: true } } - if (isProcedureOuverte(machineId)) { + if (isProcedureOuverte(machineInfo.machineId)) { for (const avisType in avis) { if (isAvisTypeId(avisType) && isNotNullNorUndefined(avis[avisType])) { avis[avisType].optionnel = true diff --git a/packages/common/src/demarche.test.ts b/packages/common/src/demarche.test.ts index 10280fbdc3dc44e5520a6dd771633063d963f0ea..112300bd97d55d1c51a11831bf490b2cdb732a14 100644 --- a/packages/common/src/demarche.test.ts +++ b/packages/common/src/demarche.test.ts @@ -1,9 +1,7 @@ /* eslint-disable no-irregular-whitespace */ -import { test, expect, describe } from 'vitest' -import { canHaveMiseEnConcurrence, demarcheEnregistrementDemandeDateFind, getDemarcheContenu } from './demarche' +import { test, expect } from 'vitest' +import { canHaveMiseEnConcurrence, getDemarcheContenu } from './demarche' import { proprietesGeothermieForagesElementIds } from './static/titresTypes_demarchesTypes_etapesTypes/sections' -import { ETAPES_TYPES } from './static/etapesTypes' -import { toCaminoDate } from './date' import { DEMARCHES_TYPES_IDS } from './static/demarchesTypes' import { TITRES_TYPES_IDS, TitreTypeId } from './static/titresTypes' @@ -473,28 +471,6 @@ test('getDemarcheContenu pxg', () => { `) }) -describe('demarcheDepotDemandeDateFind', () => { - test("pas d'étapes", () => { - expect(demarcheEnregistrementDemandeDateFind([])).toBe(null) - }) - - test('un enregistrement de la demande', () => { - expect( - demarcheEnregistrementDemandeDateFind([ - { typeId: ETAPES_TYPES.demande, date: toCaminoDate('2020-01-01') }, - { typeId: ETAPES_TYPES.enregistrementDeLaDemande, date: toCaminoDate('2024-01-01') }, - ]) - ).toBe(toCaminoDate('2024-01-01')) - }) - test('sans enregistrement de la demande', () => { - expect( - demarcheEnregistrementDemandeDateFind([ - { typeId: ETAPES_TYPES.demande, date: toCaminoDate('2020-01-01') }, - { typeId: ETAPES_TYPES.abrogationDeLaDecision, date: toCaminoDate('2024-01-01') }, - ]) - ).toBe(toCaminoDate('2020-01-01')) - }) -}) test('canHaveMiseEnConcurrence', () => { expect(canHaveMiseEnConcurrence(DEMARCHES_TYPES_IDS.ResiliationAnticipeeDAmodiation, false)).toBe(false) expect(canHaveMiseEnConcurrence(DEMARCHES_TYPES_IDS.ExtensionDePerimetre, false)).toBe(true) diff --git a/packages/common/src/demarche.ts b/packages/common/src/demarche.ts index c41f71590649c10dba54cc40402a777d2be3cc96..9bb20b9a0beb5bd88175aa72d43a459115360317 100644 --- a/packages/common/src/demarche.ts +++ b/packages/common/src/demarche.ts @@ -1,11 +1,11 @@ import { z } from 'zod' import { TITRES_TYPES_IDS, TitreTypeId, getTitreTypeType, titreTypeIdValidator } from './static/titresTypes' -import { CaminoDate, caminoDateValidator, FirstEtapeDate, firstEtapeDateValidator } from './date' +import { caminoDateValidator } from './date' import { communeIdValidator } from './static/communes' import { secteurMaritimeValidator } from './static/facades' import { substanceLegaleIdValidator } from './static/substancesLegales' import { entrepriseIdValidator, etapeEntrepriseDocumentValidator } from './entreprise' -import { ETAPE_TYPE_FOR_CONCURRENCY_DATA, ETAPES_TYPES, EtapeTypeId, etapeTypeIdFondamentaleValidator, etapeTypeIdNonFondamentaleValidator } from './static/etapesTypes' +import { ETAPE_TYPE_FOR_CONCURRENCY_DATA, EtapeTypeId, etapeTypeIdFondamentaleValidator, etapeTypeIdNonFondamentaleValidator } from './static/etapesTypes' import { etapeStatutIdValidator } from './static/etapesStatuts' import { sectionWithValueValidator } from './sections' import { etapeAvisValidator, etapeBrouillonValidator, etapeDocumentValidator, etapeIdValidator, etapeNoteValidator, etapeSlugValidator } from './etape' @@ -18,10 +18,11 @@ import { capitalize } from './strings' import { foretIdValidator } from './static/forets' import { featureCollectionForagesValidator, featureCollectionPointsValidator, featureMultiPolygonValidator } from './perimetre' import { geoSystemeIdValidator } from './static/geoSystemes' -import { isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefinedOrEmpty, NonEmptyArray, toSorted } from './typescript-tools' +import { isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty } from './typescript-tools' import { proprietesGeothermieForagesElementIds } from './static/titresTypes_demarchesTypes_etapesTypes/sections' import { titreIdValidator, titreSlugValidator } from './validators/titres' import { DEMARCHES_TYPES_IDS, DemarcheTypeId, demarcheTypeIdValidator } from './static/demarchesTypes' +import { machineIdValidator } from './validators/machine' export const demarcheIdValidator = z.string().brand<'DemarcheId'>() export type DemarcheId = z.infer<typeof demarcheIdValidator> @@ -144,7 +145,7 @@ export const getDemarcheContenu = (etapes: (Pick<DemarcheEtapeCommon, 'sections_ titreTypeId === TITRES_TYPES_IDS.CONCESSION_GRANULATS_MARINS || titreTypeId === TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_GRANULATS_MARINS ) { - // TODO 2023-11-07 à voir avec Pierre-Olivier, les sections VOLUME ne sont jamais utilisées pour les PXW + // TODO 2023-11-07 à voir avec Pierre-Olivier (rip), les sections VOLUME ne sont jamais utilisées pour les PXW const getVolume = (sectionName: 'cxx' | 'pxx'): Record<string, string> => { let volume: number | null = null let volumeUniteId: UniteId | null = null @@ -286,24 +287,6 @@ export const demarcheCreationOutputValidator = z.object({ export type DemarcheCreationOutput = z.infer<typeof demarcheCreationOutputValidator> -type DemarcheEnregistrementDemandeDateFindEtape = { date: CaminoDate; typeId: EtapeTypeId } -export function demarcheEnregistrementDemandeDateFind<T extends DemarcheEnregistrementDemandeDateFindEtape[] | NonEmptyArray<DemarcheEnregistrementDemandeDateFindEtape>>( - titreEtapes: T | undefined -): T extends [DemarcheEnregistrementDemandeDateFindEtape, ...DemarcheEnregistrementDemandeDateFindEtape[]] ? FirstEtapeDate : FirstEtapeDate | null -export function demarcheEnregistrementDemandeDateFind(titreEtapes: DemarcheEnregistrementDemandeDateFindEtape[] | undefined): null | FirstEtapeDate { - if (isNullOrUndefinedOrEmpty(titreEtapes)) { - return null - } - - const titreEtapeDemande = titreEtapes.find(te => te.typeId === ETAPES_TYPES.enregistrementDeLaDemande) - - if (isNotNullNorUndefined(titreEtapeDemande)) { - return firstEtapeDateValidator.parse(titreEtapeDemande.date) - } - - return firstEtapeDateValidator.parse(toSorted(titreEtapes.map(te => te.date))[0]) -} - export const getDemarcheMiseEnConcurrenceValidator = z.object({ demarcheId: demarcheIdValidator, titreNom: z.string(), @@ -323,11 +306,11 @@ export const canHaveMiseEnConcurrence = (demarcheTypeId: DemarcheTypeId, hasTitr export const commonTitreEnConcurrenceValidator = z.object({ demarcheId: demarcheIdValidator, demarcheTypeId: demarcheTypeIdValidator, + machineId: machineIdValidator.nullable(), titreNom: z.string(), titreSlug: titreSlugValidator, titreTypeId: titreTypeIdValidator, titulaireId: entrepriseIdValidator, - firstEtapeDate: firstEtapeDateValidator, }) const commonPerimetreValidator = z.object({ geojson4326_perimetre: featureMultiPolygonValidator, surface: km2Validator }) diff --git a/packages/common/src/machines.test.ts b/packages/common/src/machines.test.ts index b4daa20d7110a91a0a28457959b40b4169c3f3a8..3cbadf087a18a2ed997776c60b900a1e8cf8f5ed 100644 --- a/packages/common/src/machines.test.ts +++ b/packages/common/src/machines.test.ts @@ -1,27 +1,125 @@ import { describe, expect, test } from 'vitest' -import { firstEtapeDateValidator } from './date' -import { DATE_DEBUT_PROCEDURE_SPECIFIQUE, isMachineWithConsentement, machineIdFind, isDemarcheIdException } from './machines' +import { dateAddDays, firstEtapeDateValidator } from './date' +import { DATE_DEBUT_PROCEDURE_SPECIFIQUE, isMachineWithConsentement, isDemarcheIdException, MachineInfo, DATE_DEBUT_PROCEDURE_SPECIFIQUE_AXM_ARM } from './machines' import { demarcheIdValidator } from './demarche' +import { DEMARCHES_TYPES_IDS } from './static/demarchesTypes' +import { TITRES_TYPES_IDS } from './static/titresTypes' -describe('machineFind', () => { - test('demarcheDefinitionFind retourne une machine', () => { - expect(machineIdFind('prm', 'oct', demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2023-06-07'))).toStrictEqual('PrmOct') +describe('MachineInfo', () => { + test('MachineInfo.withDate() retourne une machine', () => { + expect( + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2023-06-07')) + .machineId + ).toStrictEqual('AncienLogigrammeOctroiPRM') }) - test('demarcheDefinitionFind ne retourne pas une machine quand la démarche fait partie des exceptions', () => { - expect(machineIdFind('prm', 'oct', demarcheIdValidator.parse('FfJTtP9EEfvf3VZy81hpF7ms'), firstEtapeDateValidator.parse('2023-06-07'))).toBe(undefined) + test('MachineInfo.withDate() ne retourne pas de machine quand la démarche fait partie des exceptions', () => { + expect( + MachineInfo.withDate( + TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheIdValidator.parse('FfJTtP9EEfvf3VZy81hpF7ms'), + firstEtapeDateValidator.parse('2023-06-07') + ).machineId + ).toBe(undefined) }) - test('demarcheDefinitionFind ne retourne pas une machine quand les étapes sont trop anciennes', () => { - expect(machineIdFind('prm', 'oct', demarcheIdValidator.parse('FfJTtP9EEfvf3VZy81hpF7ms'), firstEtapeDateValidator.parse('2010-06-07'))).toBe(undefined) + test('MachineInfo.withDate() fallback sur une autre machine quand elle est exclue', () => { + expect( + MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheIdValidator.parse('demarcheIdForUnitTests'), + firstEtapeDateValidator.parse(dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE_AXM_ARM, 20)) + ).machineId + ).toBe('AncienLogigrammeOctroiARM') }) - test('arm pro undef', () => { - expect(machineIdFind('arm', 'pro', demarcheIdValidator.parse('Anything'), firstEtapeDateValidator.parse('2018-10-22'))).toBe(undefined) + test('MachineInfo.withDate() ne retourne pas de machine quand les étapes sont trop anciennes', () => { + expect( + MachineInfo.withDate( + TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheIdValidator.parse('FfJTtP9EEfvf3VZy81hpF7ms'), + firstEtapeDateValidator.parse('2010-06-07') + ).machineId + ).toBe(undefined) }) - test('demarcheDefinitionFind retourne ProcedureSpecfique dès sa date de début', () => { - expect(machineIdFind('arm', 'oct', demarcheIdValidator.parse('Anything'), firstEtapeDateValidator.parse(DATE_DEBUT_PROCEDURE_SPECIFIQUE))).toBe('ProcedureSpecifique') + test(`MachineInfo.withDate() ne retourne pas de machine pour une prolongation d'Autorisation Recherche Métaux`, () => { + expect( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheIdValidator.parse('Anything'), firstEtapeDateValidator.parse('2018-10-22')) + .machineId + ).toBe(undefined) + }) + + test('MachineInfo.withDate() retourne ProcedureSpecifique dès sa date de début', () => { + const demarcheId = demarcheIdValidator.parse('Anything') + const value = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(DATE_DEBUT_PROCEDURE_SPECIFIQUE)) + expect(value.machineId).toBe('ProcedureSpecifique') + expect(value.demarcheId).toBe(demarcheId) + }) + + test('MachineInfo.withMachineId() retourne une machine', () => { + const demarcheId = demarcheIdValidator.parse('Anything') + const machineInfo = MachineInfo.withMachineId(TITRES_TYPES_IDS.CONCESSION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Mutation, demarcheId, 'ProcedureSimplifiee') + expect(machineInfo).toMatchInlineSnapshot(` + { + "valid": true, + "value": MachineInfo { + "_demarcheId": "Anything", + "_demarcheTypeId": "mut", + "_machineId": "ProcedureSimplifiee", + "_titreTypeId": "cxg", + }, + } + `) + }) + + test('MachineInfo.withMachineId() ne retourne pas de machine si le machineId est null', () => { + const machineInfo = MachineInfo.withMachineId(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.AutorisationDOuvertureDeTravaux, demarcheIdValidator.parse('Anything'), null) + expect(machineInfo).toMatchInlineSnapshot(` + { + "valid": true, + "value": MachineInfo { + "_demarcheId": "Anything", + "_demarcheTypeId": "aom", + "_machineId": undefined, + "_titreTypeId": "arm", + }, + } + `) + }) + test("MachineInfo.withMachineId() retourne une erreur en cas d'inconsistence", () => { + expect(MachineInfo.withMachineId(TITRES_TYPES_IDS.CONCESSION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Mutation, demarcheIdValidator.parse('Anything'), null)).toMatchInlineSnapshot( + ` + { + "error": "la machine n'est pas renseignée alors qu'il existe un logigramme potentiel : ProcedureSimplifiee", + "valid": false, + } + ` + ) + + expect(MachineInfo.withMachineId(TITRES_TYPES_IDS.CONCESSION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Mutation, demarcheIdValidator.parse('Anything'), 'AncienLogigrammeOctroiPRM')).toMatchInlineSnapshot(` + { + "error": "INCONSISTENCE, aurait du être ProcedureSimplifiee mais est AncienLogigrammeOctroiPRM", + "valid": false, + } + `) + }) + test('MachineInfo.withMachineId() prend en compte les exceptions', () => { + expect(MachineInfo.withMachineId(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('FfJTtP9EEfvf3VZy81hpF7ms'), null)) + .toMatchInlineSnapshot(` + { + "valid": true, + "value": MachineInfo { + "_demarcheId": "FfJTtP9EEfvf3VZy81hpF7ms", + "_demarcheTypeId": "oct", + "_machineId": undefined, + "_titreTypeId": "prm", + }, + } + `) }) }) describe('isMachineWithConsentement', () => { @@ -29,7 +127,7 @@ describe('isMachineWithConsentement', () => { expect(isMachineWithConsentement('ProcedureSpecifique')).toBe(true) }) test('autre machines', () => { - expect(isMachineWithConsentement('ArmOct')).toBe(false) + expect(isMachineWithConsentement('AncienLogigrammeOctroiARM')).toBe(false) }) }) diff --git a/packages/common/src/machines.ts b/packages/common/src/machines.ts index 3fd7d1f8823ba6eb82100ee2cd80d27e2e4706cc..f5fd5691cbe7b57346fee46581b4b0eca1c660d2 100644 --- a/packages/common/src/machines.ts +++ b/packages/common/src/machines.ts @@ -2,12 +2,14 @@ import { toCaminoDate, CaminoDate, FirstEtapeDate } from './date' import { DemarcheId, demarcheIdValidator } from './demarche' import { DemarcheTypeId, DEMARCHES_TYPES_IDS, DemarchesTypes } from './static/demarchesTypes' import { TitreTypeId } from './static/titresTypes' -import { NonEmptyArray, isNullOrUndefinedOrEmpty, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, toSorted } from './typescript-tools' +import { NonEmptyArray, isNullOrUndefinedOrEmpty, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, toSorted, isNullOrUndefined } from './typescript-tools' +import { CaminoMachineId } from './validators/machine' // TODO 2025-01-29 attention le jour où on met à jour la date de début de la procédure spécifique // TODO 2025-01-29 pour le consentement, il faudrait que l'on calcule le consentement pour toutes les étapes avec un périmètre, et qu'on aille chercher le consentement lié au titre.props_etape_id export const DATE_DEBUT_PROCEDURE_SPECIFIQUE = toCaminoDate('2400-01-01') export const DATE_DEBUT_PROCEDURE_SPECIFIQUE_AXM_ARM = toCaminoDate('2024-07-01') +export const DATE_DEBUT_PRM_OCT = toCaminoDate('2019-10-31') interface DemarcheDefinition { titreTypeIds: NonEmptyArray<TitreTypeId> @@ -32,27 +34,26 @@ const demarcheTypeIdsCxPr_G: DemarcheTypeId[] = [ DEMARCHES_TYPES_IDS.Retrait, ] const plusVieilleDateEnBase = toCaminoDate('1717-01-09') -const CAMINO_MACHINES = ['ArmOct', 'ArmRenPro', 'PrmOct', 'AxmOct', 'AxmPro', 'ProcedureSimplifiee', 'ProcedureSpecifique'] as const -export type CaminoMachineId = (typeof CAMINO_MACHINES)[number] + export const demarchesDefinitions = [ { titreTypeIds: ['arm'], demarcheTypeIds: ['oct'], dateDebut: toCaminoDate('2019-10-31'), demarcheIdExceptions: [demarcheIdValidator.parse('QauHUIPuv1a5neW3JqVEWh8n'), demarcheIdValidator.parse('XrNwRcLK39y6JZKcsJTV7nju')], - machineId: 'ArmOct', + machineId: 'AncienLogigrammeOctroiARM', }, { titreTypeIds: ['arm'], demarcheTypeIds: [DEMARCHES_TYPES_IDS.RenonciationTotale, DEMARCHES_TYPES_IDS.RenonciationPartielle, DEMARCHES_TYPES_IDS.Prolongation], dateDebut: toCaminoDate('2019-10-31'), demarcheIdExceptions: [], - machineId: 'ArmRenPro', + machineId: 'AncienLogigrammeRenonciationEtProlongationARM', }, { titreTypeIds: ['prm'], demarcheTypeIds: ['oct'], - dateDebut: toCaminoDate('2019-10-31'), + dateDebut: DATE_DEBUT_PRM_OCT, demarcheIdExceptions: [ demarcheIdValidator.parse('FfJTtP9EEfvf3VZy81hpF7ms'), demarcheIdValidator.parse('lynG9hx3x05LaqpySr0qxeca'), @@ -72,7 +73,7 @@ export const demarchesDefinitions = [ demarcheIdValidator.parse('pHJIIJFZpgEccJNt6zTOegzh'), demarcheIdValidator.parse('61af4c6a62b8e477e4b3f43a'), ], - machineId: 'PrmOct', + machineId: 'AncienLogigrammeOctroiPRM', }, { titreTypeIds: ['axm'], @@ -89,7 +90,7 @@ export const demarchesDefinitions = [ demarcheIdValidator.parse('TUI2aBCJRv7Fc1torDlVu8HB'), demarcheIdValidator.parse('FPcbrdR79tjerabHbxtLkMZa'), ], - machineId: 'AxmOct', + machineId: 'AncienLogigrammeOctroiAXM', }, { titreTypeIds: ['axm'], @@ -115,7 +116,7 @@ export const demarchesDefinitions = [ demarcheIdValidator.parse('08eC26bUf4PCr6qj9Rl4Qa1F'), demarcheIdValidator.parse('OBKZ23yRO6e4VP7MyXwgCp6U'), ], - machineId: 'AxmPro', + machineId: 'AncienLogigrammeProlongationAXM', }, { titreTypeIds: ['pxg', 'arg', 'cxr', 'inr', 'prr', 'pxr', 'cxf', 'prf', 'pxf', 'arc', 'apc', 'pcc'], @@ -160,7 +161,7 @@ export const demarchesDefinitions = [ DEMARCHES_TYPES_IDS.Prorogation, ], dateDebut: DATE_DEBUT_PROCEDURE_SPECIFIQUE_AXM_ARM, - demarcheIdExceptions: [], + demarcheIdExceptions: [demarcheIdValidator.parse('demarcheIdForUnitTests')], machineId: 'ProcedureSpecifique', }, ] as const satisfies readonly DemarcheDefinition[] @@ -169,17 +170,88 @@ export const isDemarcheIdException = (id: DemarcheId): boolean => { return demarchesDefinitions.some(definitions => isNotNullNorUndefinedNorEmpty(definitions.demarcheIdExceptions) && definitions.demarcheIdExceptions.includes(id)) } -export const machineIdFind = (titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId, demarcheId: DemarcheId, date: FirstEtapeDate): CaminoMachineId | undefined => { - const definition = toSorted(demarchesDefinitions, (a, b) => b.dateDebut.localeCompare(a.dateDebut)).find( - d => (isNullOrUndefinedOrEmpty(date) || d.dateDebut <= date) && d.titreTypeIds.includes(titreTypeId) && d.demarcheTypeIds.includes(demarcheTypeId) - ) - if (isNotNullNorUndefined(definition) && isNotNullNorUndefinedNorEmpty(definition.demarcheIdExceptions) && definition.demarcheIdExceptions.includes(demarcheId)) { - return undefined +export class MachineInfo { + private _machineId: CaminoMachineId | undefined + private _titreTypeId: TitreTypeId + private _demarcheTypeId: DemarcheTypeId + private _demarcheId: DemarcheId + + private constructor( + titreTypeId: TitreTypeId, + demarcheTypeId: DemarcheTypeId, + demarcheId: DemarcheId, + dateOrMachineId: { type: 'date'; value: FirstEtapeDate } | { type: 'machine'; value: CaminoMachineId | null } + ) { + if (dateOrMachineId.type === 'machine') { + this._machineId = dateOrMachineId.value ?? undefined + } else { + this._machineId = MachineInfo.machineIdFind(titreTypeId, demarcheTypeId, demarcheId, dateOrMachineId.value) + } + + this._titreTypeId = titreTypeId + this._demarcheTypeId = demarcheTypeId + this._demarcheId = demarcheId + } + + static withDate(titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId, demarcheId: DemarcheId, date: FirstEtapeDate): MachineInfo { + return new MachineInfo(titreTypeId, demarcheTypeId, demarcheId, { type: 'date', value: date }) + } + + static withMachineId( + titreTypeId: TitreTypeId, + demarcheTypeId: DemarcheTypeId, + demarcheId: DemarcheId, + machineId: CaminoMachineId | null + ): { valid: true; value: MachineInfo } | { valid: false; error: string } { + const demarcheDefinitionMatching = demarchesDefinitions.filter( + value => + value.titreTypeIds.includes(titreTypeId) && + value.demarcheTypeIds.includes(demarcheTypeId) && + (!isNotNullNorUndefinedNorEmpty(value.demarcheIdExceptions) || !value.demarcheIdExceptions.includes(demarcheId)) + ) + + const logigrammesPotentiels = demarcheDefinitionMatching.map(({ machineId }) => machineId).join(', ') + let found = false + for (const value of demarcheDefinitionMatching) { + if (isNullOrUndefined(machineId) && value.dateDebut === plusVieilleDateEnBase) { + return { valid: false, error: `la machine n'est pas renseignée alors qu'il existe un logigramme potentiel : ${logigrammesPotentiels}` } + } + if (value.machineId === machineId) { + found = true + } + } + if (isNotNullNorUndefined(machineId) && !found) { + return { valid: false, error: `INCONSISTENCE, aurait du être ${logigrammesPotentiels} mais est ${machineId}` } + } + + return { valid: true, value: new MachineInfo(titreTypeId, demarcheTypeId, demarcheId, { type: 'machine', value: machineId }) } } - return definition?.machineId + get machineId(): CaminoMachineId | undefined { + return this._machineId + } + get titreTypeId(): TitreTypeId { + return this._titreTypeId + } + get demarcheTypeId(): DemarcheTypeId { + return this._demarcheTypeId + } + get demarcheId(): DemarcheId { + return this._demarcheId + } + + private static machineIdFind(titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId, demarcheId: DemarcheId, date: FirstEtapeDate | null): CaminoMachineId | undefined { + const definitions = toSorted(demarchesDefinitions, (a, b) => b.dateDebut.localeCompare(a.dateDebut)).filter( + d => (isNullOrUndefinedOrEmpty(date) || d.dateDebut <= date) && d.titreTypeIds.includes(titreTypeId) && d.demarcheTypeIds.includes(demarcheTypeId) + ) + + return definitions.find( + definition => + isNullOrUndefinedOrEmpty(definition.demarcheIdExceptions) || (isNotNullNorUndefinedNorEmpty(definition.demarcheIdExceptions) && !definition.demarcheIdExceptions.includes(demarcheId)) + )?.machineId + } } export const isProcedureOuverte = (machineId: CaminoMachineId | undefined): boolean => machineId === undefined -export const isMachineWithConsentement = (machineId: CaminoMachineId | undefined): boolean => machineId === 'ProcedureSpecifique' +export const isMachineWithConsentement = (machineId: CaminoMachineId | undefined | null): boolean => machineId === 'ProcedureSpecifique' diff --git a/packages/common/src/permissions/etape-form.test.ts b/packages/common/src/permissions/etape-form.test.ts index aa14daaf6c006cc456831d96d955a37cfd5e56e9..e14ddd39b7f63163b1c1cfcef4baa517e523eb6b 100644 --- a/packages/common/src/permissions/etape-form.test.ts +++ b/packages/common/src/permissions/etape-form.test.ts @@ -27,6 +27,7 @@ import { ETAPES_TYPES } from '../static/etapesTypes' import { demarcheIdValidator } from '../demarche' import { DOCUMENTS_TYPES_IDS } from '../static/documentsTypes' import { ETAPES_STATUTS } from '../static/etapesStatuts' +import { MachineInfo } from '../machines' describe('dateTypeStepIsComplete', () => { test.each<User>([ @@ -99,6 +100,8 @@ test('fondamentaleStepIsVisible', () => { expect(fondamentaleStepIsVisible(ETAPES_TYPES.saisinesEtAvisCGE_AE)).toBe(false) }) +const demarcheId = demarcheIdValidator.parse('demarcheId') +const firstEtapeDateFondamentaleStepIsComplete = firstEtapeDateValidator.parse('1000-01-01') test('fondamentaleStepIsComplete', () => { expect( fondamentaleStepIsComplete( @@ -109,8 +112,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Amodiation, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, DEMARCHES_TYPES_IDS.Amodiation, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ).valid ).toBe(true) @@ -124,8 +126,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Amodiation, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, DEMARCHES_TYPES_IDS.Amodiation, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -147,8 +148,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Amodiation, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, DEMARCHES_TYPES_IDS.Amodiation, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -171,8 +171,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -193,8 +192,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [entreprise1Id], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -214,8 +212,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -235,8 +232,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -257,8 +253,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -280,8 +275,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [entreprise1Id], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Mutation, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Mutation, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -298,8 +292,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Mutation, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Mutation, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -320,8 +313,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [entreprise1Id], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'entreprise', entrepriseIds: [entreprise1Id] } ) ).toMatchInlineSnapshot(` @@ -338,8 +330,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [entreprise1Id], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Amodiation, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Amodiation, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -356,8 +347,7 @@ test('fondamentaleStepIsComplete', () => { titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, }, - DEMARCHES_TYPES_IDS.Amodiation, - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Amodiation, demarcheId, firstEtapeDateFondamentaleStepIsComplete), { ...testBlankUser, role: 'super' } ) ).toMatchInlineSnapshot(` @@ -371,29 +361,61 @@ test('fondamentaleStepIsComplete', () => { `) }) test('sectionsStepIsVisible', () => { - expect(sectionsStepIsVisible({ typeId: ETAPES_TYPES.demande }, DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX)).toBe(true) expect( - sectionsStepIsVisible({ typeId: ETAPES_TYPES.avisDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_ }, DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX) + sectionsStepIsVisible( + { typeId: ETAPES_TYPES.demande }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) + ) + ).toBe(true) + expect( + sectionsStepIsVisible( + { typeId: ETAPES_TYPES.avisDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_ }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) + ) ).toBe(false) }) test('sectionsStepIsComplete', () => { - expect(sectionsStepIsComplete({ typeId: ETAPES_TYPES.demande, contenu: {} }, DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX).valid).toBe(false) + expect( + sectionsStepIsComplete( + { typeId: ETAPES_TYPES.demande, contenu: {} }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) + ).valid + ).toBe(false) expect( sectionsStepIsComplete( { typeId: ETAPES_TYPES.demande, contenu: { arm: { mecanise: { value: true, heritee: false, etapeHeritee: null } } } }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) ).valid ).toBe(true) }) test('perimetreStepIsVisible', () => { - expect(perimetreStepIsVisible({ typeId: ETAPES_TYPES.demande }, DEMARCHES_TYPES_IDS.Octroi)).toBe(true) - expect(perimetreStepIsVisible({ typeId: ETAPES_TYPES.saisinesEtAvisCGE_AE }, DEMARCHES_TYPES_IDS.Octroi)).toBe(false) + expect( + perimetreStepIsVisible( + { typeId: ETAPES_TYPES.demande }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) + ) + ).toBe(true) + expect( + perimetreStepIsVisible( + { typeId: ETAPES_TYPES.saisinesEtAvisCGE_AE }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) + ) + ).toBe(false) - expect(perimetreStepIsVisible({ typeId: ETAPES_TYPES.demande }, DEMARCHES_TYPES_IDS.Mutation)).toBe(false) - expect(perimetreStepIsVisible({ typeId: ETAPES_TYPES.saisinesEtAvisCGE_AE }, DEMARCHES_TYPES_IDS.Mutation)).toBe(false) + expect( + perimetreStepIsVisible( + { typeId: ETAPES_TYPES.demande }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Mutation, demarcheId, firstEtapeDateFondamentaleStepIsComplete) + ) + ).toBe(false) + expect( + perimetreStepIsVisible( + { typeId: ETAPES_TYPES.saisinesEtAvisCGE_AE }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Mutation, demarcheId, firstEtapeDateFondamentaleStepIsComplete) + ) + ).toBe(false) }) test('perimetreStepIsComplete', () => { @@ -416,7 +438,7 @@ test('perimetreStepIsComplete', () => { etapeHeritee: null, }, }, - DEMARCHES_TYPES_IDS.Octroi + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) ) ).toMatchInlineSnapshot(` { @@ -445,7 +467,7 @@ test('perimetreStepIsComplete', () => { etapeHeritee: null, }, }, - DEMARCHES_TYPES_IDS.Octroi + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) ).valid ).toBe(true) expect( @@ -467,7 +489,7 @@ test('perimetreStepIsComplete', () => { etapeHeritee: null, }, }, - DEMARCHES_TYPES_IDS.Octroi + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) ).valid ).toBe(true) expect( @@ -489,7 +511,7 @@ test('perimetreStepIsComplete', () => { etapeHeritee: null, }, }, - DEMARCHES_TYPES_IDS.Octroi + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) ) ).toMatchInlineSnapshot(` { @@ -518,7 +540,7 @@ test('perimetreStepIsComplete', () => { etapeHeritee: null, }, }, - DEMARCHES_TYPES_IDS.Octroi + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) ).valid ).toBe(true) }) @@ -563,12 +585,9 @@ test('etapeDocumentsStepIsComplete avec mecanisation', () => { expect( etapeDocumentsStepIsComplete( { typeId: ETAPES_TYPES.demande, contenu: { arm: { mecanise: { value: true, etapeHeritee: null, heritee: false } } }, isBrouillon: ETAPE_IS_NOT_BROUILLON }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - demarcheIdValidator.parse('demarcheId'), + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), [{ etape_document_type_id: DOCUMENTS_TYPES_IDS.decret }], - [], - firstEtapeDateValidator.parse('2022-01-01') + [] ) ).toMatchInlineSnapshot(` { @@ -586,12 +605,9 @@ test('etapeDocumentsStepIsComplete avec mecanisation', () => { expect( etapeDocumentsStepIsComplete( { typeId: ETAPES_TYPES.demande, contenu: { arm: { mecanise: { value: false, etapeHeritee: null, heritee: false } } }, isBrouillon: ETAPE_IS_NOT_BROUILLON }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - demarcheIdValidator.parse('demarcheId'), + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), [{ etape_document_type_id: DOCUMENTS_TYPES_IDS.decret }], - [], - firstEtapeDateValidator.parse('2022-01-01') + [] ) ).toMatchInlineSnapshot(` { @@ -609,12 +625,9 @@ test('etapeDocumentsStepIsComplete', () => { expect( etapeDocumentsStepIsComplete( { typeId: ETAPES_TYPES.consultationDesAdministrationsCentrales, contenu: {}, isBrouillon: ETAPE_IS_NOT_BROUILLON }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - demarcheIdValidator.parse('demarcheId'), + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), [{ etape_document_type_id: DOCUMENTS_TYPES_IDS.decret }], - [], - firstEtapeDateValidator.parse('2022-01-01') + [] ) ).toMatchInlineSnapshot(` { @@ -628,12 +641,9 @@ test('etapeDocumentsStepIsComplete', () => { expect( etapeDocumentsStepIsComplete( { typeId: ETAPES_TYPES.demande, contenu: {}, isBrouillon: ETAPE_IS_BROUILLON }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - demarcheIdValidator.parse('demarcheId'), + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), axmDocumentsComplete, - [], - firstEtapeDateValidator.parse('2022-01-01') + [] ) ).toMatchInlineSnapshot(` { @@ -644,12 +654,9 @@ test('etapeDocumentsStepIsComplete', () => { expect( etapeDocumentsStepIsComplete( { typeId: ETAPES_TYPES.publicationDansUnJournalLocalOuNational, contenu: {}, isBrouillon: ETAPE_IS_BROUILLON }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - demarcheIdValidator.parse('demarcheId'), + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), [], - [], - firstEtapeDateValidator.parse('2022-01-01') + [] ) ).toMatchInlineSnapshot(` { @@ -659,13 +666,24 @@ test('etapeDocumentsStepIsComplete', () => { }) test('entrepriseDocumentsStepIsVisible', () => { - expect(entrepriseDocumentsStepIsVisible({ typeId: ETAPES_TYPES.consultationDesAdministrationsCentrales }, DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX)).toBe( - false - ) - expect(entrepriseDocumentsStepIsVisible({ typeId: ETAPES_TYPES.demande }, DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX)).toBe(true) - expect(entrepriseDocumentsStepIsVisible({ typeId: ETAPES_TYPES.publicationDansUnJournalLocalOuNational }, DEMARCHES_TYPES_IDS.Octroi, TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX)).toBe( - false - ) + expect( + entrepriseDocumentsStepIsVisible( + { typeId: ETAPES_TYPES.consultationDesAdministrationsCentrales }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) + ) + ).toBe(false) + expect( + entrepriseDocumentsStepIsVisible( + { typeId: ETAPES_TYPES.demande }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) + ) + ).toBe(true) + expect( + entrepriseDocumentsStepIsVisible( + { typeId: ETAPES_TYPES.publicationDansUnJournalLocalOuNational }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete) + ) + ).toBe(false) }) test('entrepriseDocumentsStepIsComplete', () => { expect( @@ -676,16 +694,14 @@ test('entrepriseDocumentsStepIsComplete', () => { amodiataires: { value: [], heritee: false, etapeHeritee: null }, contenu: {}, }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), [] ).valid ).toBe(true) expect( entrepriseDocumentsStepIsComplete( { typeId: ETAPES_TYPES.demande, titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, contenu: {} }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), [] ).valid ).toBe(false) @@ -693,16 +709,14 @@ test('entrepriseDocumentsStepIsComplete', () => { expect( entrepriseDocumentsStepIsComplete( { typeId: ETAPES_TYPES.demande, titulaires: { value: [entreprise1Id], heritee: false, etapeHeritee: null }, amodiataires: { value: [], heritee: false, etapeHeritee: null }, contenu: {} }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), [] ).valid ).toBe(false) expect( entrepriseDocumentsStepIsComplete( { typeId: ETAPES_TYPES.demande, titulaires: { value: [], heritee: false, etapeHeritee: null }, amodiataires: { value: [entreprise1Id], heritee: false, etapeHeritee: null }, contenu: {} }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), [] ).valid ).toBe(false) @@ -715,8 +729,7 @@ test('entrepriseDocumentsStepIsComplete', () => { amodiataires: { value: [entreprise1Id], heritee: false, etapeHeritee: null }, contenu: { arm: { mecanise: { value: false, heritee: false, etapeHeritee: null } } }, }, - DEMARCHES_TYPES_IDS.Octroi, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateFondamentaleStepIsComplete), [ { documentTypeId: DOCUMENTS_TYPES_IDS.attestationFiscale, @@ -748,20 +761,20 @@ test('entrepriseDocumentsStepIsComplete', () => { ).toBe(true) }) -const demarcheId = demarcheIdValidator.parse('demarcheId') const firstEtapeDate = firstEtapeDateValidator.parse('2022-01-01') test('etapeAvisStepIsVisible', () => { - expect(etapeAvisStepIsVisible({ typeId: ETAPES_TYPES.demande, contenu: {} }, TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate, [])).toBe( - false - ) + expect( + etapeAvisStepIsVisible( + { typeId: ETAPES_TYPES.demande, contenu: {} }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), + [] + ) + ).toBe(false) expect( etapeAvisStepIsVisible( { typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, contenu: {} }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheId, - firstEtapeDate, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), [] ) ).toBe(true) @@ -772,10 +785,7 @@ test('etapeAvisStepIsComplete', () => { etapeAvisStepIsComplete( { typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, contenu: {} }, [{ avis_type_id: 'autreAvis' }], - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheId, - firstEtapeDate, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), [] ).valid ).toBe(false) @@ -783,10 +793,7 @@ test('etapeAvisStepIsComplete', () => { etapeAvisStepIsComplete( { typeId: ETAPES_TYPES.avisDesCollectivites, contenu: {} }, [{ avis_type_id: 'autreAvis' }], - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheId, - firstEtapeDate, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), [] ).valid ).toBe(true) diff --git a/packages/common/src/permissions/etape-form.ts b/packages/common/src/permissions/etape-form.ts index fe5cb4238b10d4c6e864f4b3c731f63fd7ad497d..5e29bfc0111fc29498370d7f0947823a6ce85a36 100644 --- a/packages/common/src/permissions/etape-form.ts +++ b/packages/common/src/permissions/etape-form.ts @@ -1,23 +1,20 @@ import { EntrepriseDocumentId, EntrepriseId } from '../entreprise' import { User, isAdministrationAdmin, isAdministrationEditeur, isSuper } from '../roles' import { CommuneId } from '../static/communes' -import { DemarcheTypeId } from '../static/demarchesTypes' import { DocumentsTypes, EntrepriseDocumentTypeId } from '../static/documentsTypes' import { EtapeTypeId, EtapesTypes } from '../static/etapesTypes' import { SDOMZoneId } from '../static/sdom' -import { TitreTypeId } from '../static/titresTypes' import { getDocuments } from '../static/titresTypes_demarchesTypes_etapesTypes/documents' import { getEntrepriseDocuments } from '../static/titresTypes_demarchesTypes_etapesTypes/entrepriseDocuments' import { getSections, getSectionsWithValue } from '../static/titresTypes_demarchesTypes_etapesTypes/sections' import { onlyUnique, NonEmptyArray, isNonEmptyArray, isNullOrUndefinedOrEmpty, isNullOrUndefined, Nullable } from '../typescript-tools' import { sectionsWithValueCompleteValidate } from './sections' import { canEditAmodiataires, canEditDuree, canEditPerimetre, canEditTitulaires } from './titres-etapes' -import { DemarcheId } from '../demarche' -import { FirstEtapeDate } from '../date' import { isArmMecanise } from '../static/mecanise' import { getAvisTypes } from '../avisTypes' import { EtapeDocument, TempEtapeDocument, EtapeAvis, TempEtapeAvis } from '../etape' import { FlattenEtape } from '../etape-form' +import { MachineInfo } from '../machines' type ValidReturn = { valid: true } | { valid: false; errors: NonEmptyArray<string> } @@ -53,12 +50,7 @@ export const fondamentaleStepIsVisible = (etapeTypeId: EtapeTypeId): boolean => return EtapesTypes[etapeTypeId].fondamentale } -export const fondamentaleStepIsComplete = ( - flattened: Pick<FlattenEtape, 'typeId' | 'duree' | 'substances' | 'titulaires' | 'amodiataires'>, - demarcheTypeId: DemarcheTypeId, - titreTypeId: TitreTypeId, - user: User -): ValidReturn => { +export const fondamentaleStepIsComplete = (flattened: Pick<FlattenEtape, 'typeId' | 'duree' | 'substances' | 'titulaires' | 'amodiataires'>, machineInfo: MachineInfo, user: User): ValidReturn => { if (!fondamentaleStepIsVisible(flattened.typeId)) { return { valid: true } } @@ -68,17 +60,17 @@ export const fondamentaleStepIsComplete = ( errors.push('Les substances sont obligatoires') } - const editDuree = canEditDuree(titreTypeId, demarcheTypeId, user) + const editDuree = canEditDuree(machineInfo, user) if (editDuree.visibility === 'present' && editDuree.required && (isNullOrUndefined(flattened.duree.value) || flattened.duree.value === 0)) { errors.push(editDuree.message) } - const editTitulaires = canEditTitulaires(titreTypeId, demarcheTypeId, user) + const editTitulaires = canEditTitulaires(machineInfo, user) if (editTitulaires.visibility === 'present' && editTitulaires.required && isNullOrUndefinedOrEmpty(flattened.titulaires.value)) { errors.push(editTitulaires.message) } - const editAmodiataires = canEditAmodiataires(titreTypeId, demarcheTypeId, user) + const editAmodiataires = canEditAmodiataires(machineInfo, user) if (editAmodiataires.visibility === 'present' && editAmodiataires.required && isNullOrUndefinedOrEmpty(flattened.amodiataires.value)) { errors.push(editAmodiataires.message) } @@ -90,15 +82,15 @@ export const fondamentaleStepIsComplete = ( return { valid: true } } -export const sectionsStepIsVisible = (etape: Pick<FlattenEtape, 'typeId'>, demarcheTypeId: DemarcheTypeId, titreTypeId: TitreTypeId): boolean => { - return getSections(titreTypeId, demarcheTypeId, etape.typeId).length > 0 +export const sectionsStepIsVisible = (etape: Pick<FlattenEtape, 'typeId'>, machineInfo: MachineInfo): boolean => { + return getSections(machineInfo, etape.typeId).length > 0 } -export const sectionsStepIsComplete = (etape: Pick<FlattenEtape, 'typeId' | 'contenu'>, demarcheTypeId: DemarcheTypeId, titreTypeId: TitreTypeId): ValidReturn => { - if (!sectionsStepIsVisible(etape, demarcheTypeId, titreTypeId)) { +export const sectionsStepIsComplete = (etape: Pick<FlattenEtape, 'typeId' | 'contenu'>, machineInfo: MachineInfo): ValidReturn => { + if (!sectionsStepIsVisible(etape, machineInfo)) { return { valid: true } } - const sections = getSections(titreTypeId, demarcheTypeId, etape.typeId) + const sections = getSections(machineInfo, etape.typeId) const sectionsWithValue = getSectionsWithValue(sections, etape.contenu) const errors: string[] = sectionsWithValueCompleteValidate(sectionsWithValue) @@ -109,18 +101,18 @@ export const sectionsStepIsComplete = (etape: Pick<FlattenEtape, 'typeId' | 'con return { valid: true } } -export const perimetreStepIsVisible = (etape: Pick<FlattenEtape, 'typeId'>, demarcheTypeId: DemarcheTypeId): boolean => { - const editPerimetre = canEditPerimetre(demarcheTypeId, etape.typeId) +export const perimetreStepIsVisible = (etape: Pick<FlattenEtape, 'typeId'>, machineInfo: MachineInfo): boolean => { + const editPerimetre = canEditPerimetre(machineInfo, etape.typeId) return editPerimetre.visibility === 'present' } -export const perimetreStepIsComplete = (etape: Pick<FlattenEtape, 'typeId' | 'perimetre'>, demarcheTypeId: DemarcheTypeId): ValidReturn => { - if (!perimetreStepIsVisible(etape, demarcheTypeId)) { +export const perimetreStepIsComplete = (etape: Pick<FlattenEtape, 'typeId' | 'perimetre'>, machineInfo: MachineInfo): ValidReturn => { + if (!perimetreStepIsVisible(etape, machineInfo)) { return { valid: true } } const errors: string[] = [] - const editPerimetre = canEditPerimetre(demarcheTypeId, etape.typeId) + const editPerimetre = canEditPerimetre(machineInfo, etape.typeId) if (editPerimetre.visibility === 'present' && editPerimetre.required && isNullOrUndefined(etape.perimetre.value?.geojson4326Perimetre)) { errors.push(editPerimetre.message) } @@ -138,15 +130,12 @@ export const etapeDocumentsStepIsVisible = (): boolean => { export const etapeDocumentsStepIsComplete = ( etape: Pick<FlattenEtape, 'typeId' | 'contenu' | 'isBrouillon'>, - demarcheTypeId: DemarcheTypeId, - titreTypeId: TitreTypeId, - demarcheId: DemarcheId, + machineInfo: MachineInfo, etapeDocuments: Pick<EtapeDocument | TempEtapeDocument, 'etape_document_type_id'>[], - sdomZoneIds: SDOMZoneId[], - firstEtapeDate: FirstEtapeDate + sdomZoneIds: SDOMZoneId[] ): ValidReturn => { const errors: string[] = [] - const documentTypes = getDocuments(titreTypeId, demarcheTypeId, etape.typeId, firstEtapeDate, demarcheId, sdomZoneIds, isArmMecanise(etape.contenu)) + const documentTypes = getDocuments(machineInfo, etape.typeId, sdomZoneIds, isArmMecanise(etape.contenu)) errors.push( ...documentTypes @@ -161,31 +150,21 @@ export const etapeDocumentsStepIsComplete = ( return { valid: true } } -export const etapeAvisStepIsVisible = ( - etape: Pick<FlattenEtape, 'typeId' | 'contenu'>, - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - demarcheId: DemarcheId, - firstEtapeDate: FirstEtapeDate, - communeIds: CommuneId[] -): boolean => { - return Object.keys(getAvisTypes(etape.typeId, titreTypeId, demarcheTypeId, demarcheId, firstEtapeDate, communeIds, isArmMecanise(etape.contenu))).length > 0 +export const etapeAvisStepIsVisible = (etape: Pick<FlattenEtape, 'typeId' | 'contenu'>, machineInfo: MachineInfo, communeIds: CommuneId[]): boolean => { + return Object.keys(getAvisTypes(etape.typeId, machineInfo, communeIds, isArmMecanise(etape.contenu))).length > 0 } export const etapeAvisStepIsComplete = ( etape: Pick<FlattenEtape, 'typeId' | 'contenu'>, etapeAvis: Pick<EtapeAvis | TempEtapeAvis, 'avis_type_id'>[], - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - demarcheId: DemarcheId, - firstEtapeDate: FirstEtapeDate, + machineInfo: MachineInfo, communeIds: CommuneId[] ): ValidReturn => { - if (!etapeAvisStepIsVisible(etape, titreTypeId, demarcheTypeId, demarcheId, firstEtapeDate, communeIds)) { + if (!etapeAvisStepIsVisible(etape, machineInfo, communeIds)) { return { valid: true } } - const avisTypes = getAvisTypes(etape.typeId, titreTypeId, demarcheTypeId, demarcheId, firstEtapeDate, communeIds, isArmMecanise(etape.contenu)) + const avisTypes = getAvisTypes(etape.typeId, machineInfo, communeIds, isArmMecanise(etape.contenu)) if (Object.values(avisTypes).some(avisType => !avisType.optionnel && etapeAvis.every(avis => avis.avis_type_id !== avisType.id))) { return { valid: false, errors: ['Il manque des avis obligatoires'] } } @@ -193,24 +172,23 @@ export const etapeAvisStepIsComplete = ( return { valid: true } } -export const entrepriseDocumentsStepIsVisible = (etape: Pick<FlattenEtape, 'typeId'>, demarcheTypeId: DemarcheTypeId, titreTypeId: TitreTypeId): boolean => { - return getEntrepriseDocuments(titreTypeId, demarcheTypeId, etape.typeId).length > 0 +export const entrepriseDocumentsStepIsVisible = (etape: Pick<FlattenEtape, 'typeId'>, machineInfo: MachineInfo): boolean => { + return getEntrepriseDocuments(machineInfo, etape.typeId).length > 0 } export const entrepriseDocumentsStepIsComplete = ( etape: Pick<FlattenEtape, 'typeId' | 'contenu' | 'titulaires' | 'amodiataires'>, - demarcheTypeId: DemarcheTypeId, - titreTypeId: TitreTypeId, + machineInfo: MachineInfo, entreprisesDocuments: Pick<SelectedEntrepriseDocument, 'documentTypeId' | 'entrepriseId'>[] ): ValidReturn => { - if (!entrepriseDocumentsStepIsVisible(etape, demarcheTypeId, titreTypeId)) { + if (!entrepriseDocumentsStepIsVisible(etape, machineInfo)) { return { valid: true } } - const documentTypes = getEntrepriseDocuments(titreTypeId, demarcheTypeId, etape.typeId) + const documentTypes = getEntrepriseDocuments(machineInfo, etape.typeId) const entrepriseIds = [...etape.titulaires.value, ...etape.amodiataires.value].filter(onlyUnique) - if (isNullOrUndefinedOrEmpty(entrepriseIds) && getEntrepriseDocuments(titreTypeId, demarcheTypeId, etape.typeId).some(({ optionnel }) => !optionnel)) { + if (isNullOrUndefinedOrEmpty(entrepriseIds) && getEntrepriseDocuments(machineInfo, etape.typeId).some(({ optionnel }) => !optionnel)) { return { valid: false, errors: ["Il y a des documents d'entreprise obligatoires, mais il n'y a pas de titulaire"] } } diff --git a/packages/common/src/permissions/titres-demarches.test.ts b/packages/common/src/permissions/titres-demarches.test.ts index 38749f47d24194052d9e4148101070c729fccc0a..ac5d29d9db774707d41226073e95db8e506d0765 100644 --- a/packages/common/src/permissions/titres-demarches.test.ts +++ b/packages/common/src/permissions/titres-demarches.test.ts @@ -3,11 +3,13 @@ import { AdministrationId } from '../static/administrations' import { canEditDemarche, canCreateTravaux, canDeleteDemarche, canCreateDemarche, canPublishResultatMiseEnConcurrence, canCreateEtapeByDemarche } from './titres-demarches' import { testBlankUser, TestUser } from '../tests-utils' import { TitresStatutIds } from '../static/titresStatuts' -import { caminoDateValidator, dateAddDays, toCaminoDate } from '../date' +import { caminoDateValidator, dateAddDays, firstEtapeDateValidator } from '../date' import { demarcheIdValidator } from '../demarche' import { ETAPES_TYPES } from '../static/etapesTypes' import { EtapesTypesEtapesStatuts } from '../static/etapesTypesEtapesStatuts' -import { DATE_DEBUT_PROCEDURE_SPECIFIQUE } from '../machines' +import { DATE_DEBUT_PROCEDURE_SPECIFIQUE, MachineInfo } from '../machines' +import { TITRES_TYPES_IDS } from '../static/titresTypes' +import { DEMARCHES_TYPES_IDS } from '../static/demarchesTypes' describe('canEditDemarche', () => { test.each<[AdministrationId, boolean]>([ @@ -116,24 +118,32 @@ describe('canCreateTravaux', () => { describe('canPublishResultatMiseEnConcurrence', () => { const demarcheId = demarcheIdValidator.parse('demarcheId') test('machine non procédure spécifique', () => { - expect(canPublishResultatMiseEnConcurrence({ ...testBlankUser, role: 'super' }, 'arm', 'oct', [{ date: toCaminoDate('2020-01-01'), etape_statut_id: 'fai', etape_type_id: 'mfr' }], demarcheId)) - .toMatchInlineSnapshot(` - { - "errors": [ - "Cette démarche n'est pas une procédure spécifique", - ], - "valid": false, - } - `) + expect( + canPublishResultatMiseEnConcurrence( + { ...testBlankUser, role: 'super' }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse('2020-01-01')), + [{ etape_statut_id: 'fai', etape_type_id: 'mfr' }] + ) + ).toMatchInlineSnapshot(` + { + "errors": [ + "Cette démarche n'est pas une procédure spécifique", + ], + "valid": false, + } + `) }) test('mise en concurrence non terminée', () => { expect( canPublishResultatMiseEnConcurrence( { ...testBlankUser, role: 'super' }, - 'arm', - 'oct', - [{ date: dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE, 12), etape_statut_id: 'fai', etape_type_id: 'mfr' }], - demarcheId + MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheId, + firstEtapeDateValidator.parse(dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE, 12)) + ), + [{ etape_statut_id: 'fai', etape_type_id: 'mfr' }] ) ).toMatchInlineSnapshot(` { @@ -148,17 +158,18 @@ describe('canPublishResultatMiseEnConcurrence', () => { expect( canPublishResultatMiseEnConcurrence( { ...testBlankUser, role: 'defaut' }, - 'arm', - 'oct', + MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheId, + firstEtapeDateValidator.parse(dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE, 10)) + ), [ { etape_type_id: ETAPES_TYPES.avisDeMiseEnConcurrenceAuJORF, etape_statut_id: EtapesTypesEtapesStatuts.avisDeMiseEnConcurrenceAuJORF.TERMINE.etapeStatutId, - demarche_id_en_concurrence: null, - date: dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE, 10), }, - ], - demarcheId + ] ) ).toMatchInlineSnapshot(` { @@ -171,7 +182,18 @@ describe('canPublishResultatMiseEnConcurrence', () => { }) test("pas d'étapes", () => { - expect(canPublishResultatMiseEnConcurrence({ ...testBlankUser, role: 'super' }, 'arm', 'oct', [], demarcheId)).toMatchInlineSnapshot(` + expect( + canPublishResultatMiseEnConcurrence( + { ...testBlankUser, role: 'super' }, + MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheId, + firstEtapeDateValidator.parse(dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE, 10)) + ), + [] + ) + ).toMatchInlineSnapshot(` { "errors": [ "Au moins une étape est nécessaire", @@ -185,17 +207,18 @@ describe('canPublishResultatMiseEnConcurrence', () => { expect( canPublishResultatMiseEnConcurrence( { ...testBlankUser, role: 'admin', administrationId: 'aut-mrae-guyane-01' }, - 'arm', - 'oct', + MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheId, + firstEtapeDateValidator.parse(dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE, 10)) + ), [ { etape_type_id: ETAPES_TYPES.avisDeMiseEnConcurrenceAuJORF, etape_statut_id: EtapesTypesEtapesStatuts.avisDeMiseEnConcurrenceAuJORF.TERMINE.etapeStatutId, - demarche_id_en_concurrence: null, - date: dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE, 10), }, - ], - demarcheId + ] ) ).toMatchInlineSnapshot(` { @@ -209,23 +232,22 @@ describe('canPublishResultatMiseEnConcurrence', () => { expect( canPublishResultatMiseEnConcurrence( { ...testBlankUser, role: 'editeur', administrationId: 'aut-mrae-guyane-01' }, - 'arm', - 'oct', + MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheId, + firstEtapeDateValidator.parse(dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE, 10)) + ), [ { etape_type_id: ETAPES_TYPES.avisDeMiseEnConcurrenceAuJORF, etape_statut_id: EtapesTypesEtapesStatuts.avisDeMiseEnConcurrenceAuJORF.TERMINE.etapeStatutId, - demarche_id_en_concurrence: null, - date: dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE, 10), }, { etape_type_id: ETAPES_TYPES.resultatMiseEnConcurrence, etape_statut_id: EtapesTypesEtapesStatuts.resultatMiseEnConcurrence.ACCEPTE.etapeStatutId, - demarche_id_en_concurrence: null, - date: dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE, 11), }, - ], - demarcheId + ] ) ).toMatchInlineSnapshot(` { diff --git a/packages/common/src/permissions/titres-demarches.ts b/packages/common/src/permissions/titres-demarches.ts index 9e1c332345e77f5ee967a6730e58d13037d626ec..4e2703a5285146bc0369317759409f65dbd9b3df 100644 --- a/packages/common/src/permissions/titres-demarches.ts +++ b/packages/common/src/permissions/titres-demarches.ts @@ -10,10 +10,10 @@ import { canCreateEtape } from './titres-etapes' import { TitreGetDemarche } from '../titres' import { CaminoValid, isNotNullNorUndefinedNorEmpty, isNullOrUndefined } from '../typescript-tools' import { ETAPE_IS_BROUILLON } from '../etape' -import { demarcheEnregistrementDemandeDateFind, DemarcheEtape, DemarcheId } from '../demarche' -import { machineIdFind } from '../machines' +import { DemarcheEtape } from '../demarche' import { ETAPES_TYPES, EtapesTypes } from '../static/etapesTypes' import { EtapesTypesEtapesStatuts } from '../static/etapesTypesEtapesStatuts' +import { MachineInfo } from '../machines' const hasOneDemarcheWithoutPhase = (demarches: Pick<TitreGetDemarche, 'demarche_date_debut'>[]): boolean => { // Si il y a une seule démarche et qu'elle n'a pas encore créée de phase, alors on ne peut pas créer une deuxième démarche @@ -90,22 +90,19 @@ export const canCreateEtapeByDemarche = ( export const canPublishResultatMiseEnConcurrence = ( user: User, - titre_type_id: TitreTypeId, - demarche_type_id: DemarcheTypeId, - etapes: Pick<DemarcheEtape, 'etape_type_id' | 'demarche_id_en_concurrence' | 'date' | 'etape_statut_id'>[], - id: DemarcheId + + machineInfo: MachineInfo, + etapes: Pick<DemarcheEtape, 'etape_type_id' | 'etape_statut_id'>[] ): CaminoValid<string> => { if (!isSuper(user) && !isAdministrationAdmin(user) && !isAdministrationEditeur(user)) { return { valid: false, errors: ["L'utilisateur ne dispose pas des droits suffisants"] } } - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(etapes.map(etape => ({ ...etape, typeId: etape.etape_type_id }))) - if (isNullOrUndefined(firstEtapeDate)) { + if (etapes.length === 0) { return { valid: false, errors: ['Au moins une étape est nécessaire'] } } - const machineId = machineIdFind(titre_type_id, demarche_type_id, id, firstEtapeDate) - if (machineId !== 'ProcedureSpecifique') { + if (machineInfo.machineId !== 'ProcedureSpecifique') { return { valid: false, errors: ["Cette démarche n'est pas une procédure spécifique"] } } diff --git a/packages/common/src/permissions/titres-etapes.test.ts b/packages/common/src/permissions/titres-etapes.test.ts index 80ec0cb387d6605969c545ff4615df8997da1e78..070cd7223eecfb83b274015de41ed150c0848550 100644 --- a/packages/common/src/permissions/titres-etapes.test.ts +++ b/packages/common/src/permissions/titres-etapes.test.ts @@ -38,7 +38,7 @@ import { SDOMZoneIds } from '../static/sdom' import { PartialRecord } from '../typescript-tools' import { Hectare, hectareToKm2, hectareValidator, KM2, km2toHectare, km2Validator } from '../number' import { demarcheIdValidator } from '../demarche' -import { DATE_DEBUT_PROCEDURE_SPECIFIQUE, DATE_DEBUT_PROCEDURE_SPECIFIQUE_AXM_ARM } from '../machines' +import { DATE_DEBUT_PROCEDURE_SPECIFIQUE, DATE_DEBUT_PROCEDURE_SPECIFIQUE_AXM_ARM, MachineInfo } from '../machines' console.warn = vi.fn() @@ -52,18 +52,34 @@ test.each<{ titreTypeId: TitreTypeId; demarcheTypeId: DemarcheTypeId; canEdit: b { titreTypeId: 'prm', demarcheTypeId: 'exp', canEdit: false }, { titreTypeId: 'prm', demarcheTypeId: 'mut', canEdit: false }, ])('canEditDuree $titreTypeId | $demarcheTypeId | $canEdit', ({ titreTypeId, demarcheTypeId, canEdit }) => - expect(canEditDuree(titreTypeId, demarcheTypeId, { ...testBlankUser, role: 'entreprise', entrepriseIds: [newEntrepriseId('entrepriseId')] }).visibility === 'present').toEqual(canEdit) + expect( + canEditDuree(MachineInfo.withDate(titreTypeId, demarcheTypeId, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), { + ...testBlankUser, + role: 'entreprise', + entrepriseIds: [newEntrepriseId('entrepriseId')], + }).visibility === 'present' + ).toEqual(canEdit) ) test('un super ou une admininstration peut éditer la durée d un octroi d ARM', () => { - expect(canEditDuree('arm', 'oct', { ...testBlankUser, role: 'super' })).toMatchInlineSnapshot(` + expect( + canEditDuree( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), + { ...testBlankUser, role: 'super' } + ) + ).toMatchInlineSnapshot(` { "message": "la durée est obligatoire pour une démarche octroi", "required": true, "visibility": "present", } `) - expect(canEditDuree('arm', 'oct', { ...testBlankUser, role: 'admin', administrationId: 'dea-guyane-01' })).toMatchInlineSnapshot(` + expect( + canEditDuree( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), + { ...testBlankUser, role: 'admin', administrationId: 'dea-guyane-01' } + ) + ).toMatchInlineSnapshot(` { "message": "la durée est obligatoire pour une démarche octroi", "required": true, @@ -89,7 +105,10 @@ test.each<{ titreTypeId: TitreTypeId; demarcheTypeId: DemarcheTypeId; etapeTypeI { titreTypeId: 'prm', etapeTypeId: 'mfr', demarcheTypeId: 'mut', user: { role: 'super' }, canEdit: false }, { titreTypeId: 'prm', etapeTypeId: 'dpu', demarcheTypeId: 'dec', user: { role: 'defaut' }, canEdit: false }, ])('canEditDate $titreTypeId | $demarcheTypeId | $etapeTypeId | $user | $canEdit', ({ titreTypeId, demarcheTypeId, etapeTypeId, user, canEdit }) => { - expect(canEditDates(titreTypeId, demarcheTypeId, etapeTypeId, { ...user, ...testBlankUser }).visibility === 'present').toEqual(canEdit) + expect( + canEditDates(MachineInfo.withDate(titreTypeId, demarcheTypeId, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), etapeTypeId, { ...user, ...testBlankUser }) + .visibility === 'present' + ).toEqual(canEdit) }) test.each<{ titreTypeId: TitreTypeId; user: TestUser; canEdit: boolean }>([ @@ -101,13 +120,19 @@ test.each<{ titreTypeId: TitreTypeId; user: TestUser; canEdit: boolean }>([ { titreTypeId: 'prm', user: { role: 'lecteur', administrationId: ADMINISTRATION_IDS.BRGM }, canEdit: false }, { titreTypeId: 'prm', user: { role: 'defaut' }, canEdit: false }, ])('canEditAmodiataires $titreTypeId | $user | $canEdit', ({ titreTypeId, user, canEdit }) => { - const editAmodiataires = canEditAmodiataires(titreTypeId, DEMARCHES_TYPES_IDS.Octroi, { ...user, ...testBlankUser }) + const editAmodiataires = canEditAmodiataires(MachineInfo.withDate(titreTypeId, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), { + ...user, + ...testBlankUser, + }) expect(editAmodiataires.visibility === 'present').toEqual(canEdit) }) test('canEditAmodiataires by demarcheTypeId', () => { const result = Object.entries(DEMARCHES_TYPES_IDS).reduce<PartialRecord<string, InputPresence>>((acc, [key, value]) => { - acc[key] = canEditAmodiataires(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, value, { ...testBlankUser, role: 'super' }) + acc[key] = canEditAmodiataires(MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, value, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), { + ...testBlankUser, + role: 'super', + }) return acc }, {}) @@ -132,13 +157,19 @@ test.each<{ titreTypeId: TitreTypeId; user: TestUser; canEdit: boolean }>([ { titreTypeId: 'arm', user: { role: 'lecteur', administrationId: ADMINISTRATION_IDS.BRGM }, canEdit: false }, { titreTypeId: 'arm', user: { role: 'defaut' }, canEdit: false }, ])('canEditTitulaires $titreTypeId | $user | $canEdit', ({ titreTypeId, user, canEdit }) => { - const editTitulaires = canEditTitulaires(titreTypeId, DEMARCHES_TYPES_IDS.Octroi, { ...user, ...testBlankUser }) + const editTitulaires = canEditTitulaires(MachineInfo.withDate(titreTypeId, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), { + ...user, + ...testBlankUser, + }) expect(editTitulaires.visibility === 'present').toEqual(canEdit) }) test('canEditTitulaires by demarcheTypeId', () => { const result = Object.entries(DEMARCHES_TYPES_IDS).reduce<PartialRecord<string, ReturnType<typeof canEditTitulaires>>>((acc, [key, value]) => { - acc[key] = canEditTitulaires(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, value, { ...testBlankUser, role: 'super' }) + acc[key] = canEditTitulaires(MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, value, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), { + ...testBlankUser, + role: 'super', + }) return acc }, {}) @@ -148,7 +179,10 @@ test('canEditTitulaires by demarcheTypeId', () => { test('canEditPerimetre by demarcheTypeId', () => { const result = Object.entries(DEMARCHES_TYPES_IDS).reduce<PartialRecord<string, ReturnType<typeof canEditPerimetre>>>((acc, [key, value]) => { - acc[key] = canEditPerimetre(value, ETAPES_TYPES.demande) + acc[key] = canEditPerimetre( + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, value, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), + ETAPES_TYPES.demande + ) return acc }, {}) @@ -157,14 +191,24 @@ test('canEditPerimetre by demarcheTypeId', () => { }) test('canEditPerimetre fondamentale', () => { - expect(canEditPerimetre(DEMARCHES_TYPES_IDS.Octroi, ETAPES_TYPES.demande)).toMatchInlineSnapshot(` + expect( + canEditPerimetre( + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), + ETAPES_TYPES.demande + ) + ).toMatchInlineSnapshot(` { "message": "le périmètre est obligatoire pour une démarche octroi", "required": true, "visibility": "present", } `) - expect(canEditPerimetre(DEMARCHES_TYPES_IDS.Octroi, ETAPES_TYPES.avisDeDemandeConcurrente)).toMatchInlineSnapshot(` + expect( + canEditPerimetre( + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), + ETAPES_TYPES.avisDeDemandeConcurrente + ) + ).toMatchInlineSnapshot(` { "message": "une étape avis de demande concurrente ne peut pas inclure de périmètre", "visibility": "absent", @@ -419,9 +463,7 @@ test("teste la complétude d'une demande d'AXM faite par un utilisateur entrepri expect( isEtapeComplete( { ...etapeComplete, isBrouillon: ETAPE_IS_BROUILLON }, - 'axm', - demarcheIdValidator.parse('demarcheId'), - 'oct', + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), axmDocuments, axmEntrepriseDocuments, [SDOMZoneIds.Zone1], @@ -431,8 +473,7 @@ test("teste la complétude d'une demande d'AXM faite par un utilisateur entrepri ...testBlankUser, role: 'entreprise', entrepriseIds: [entrepriseIdValidator.parse('id1')], - }, - firstEtapeDateValidator.parse('2022-01-01') + } ) ).toMatchInlineSnapshot(` { @@ -448,9 +489,7 @@ test("teste la complétude d'une demande d'AXM faite par un utilisateur entrepri expect( isEtapeComplete( { ...etapeComplete, isBrouillon: ETAPE_IS_BROUILLON }, - 'axm', - demarcheIdValidator.parse('demarcheId'), - 'oct', + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), axmDocuments, axmEntrepriseDocuments, [], @@ -460,8 +499,7 @@ test("teste la complétude d'une demande d'AXM faite par un utilisateur entrepri ...testBlankUser, role: 'entreprise', entrepriseIds: [entrepriseIdValidator.parse('id1')], - }, - firstEtapeDateValidator.parse('2022-01-01') + } ) ).toStrictEqual({ valid: true, errors: null }) }) @@ -470,9 +508,7 @@ test("teste la complétude d'une demande d'ARM", () => { expect( isEtapeComplete( { ...etapeComplete, contenu: { arm: { mecanise: { value: false, etapeHeritee: null, heritee: false } } } }, - 'arm', - demarcheIdValidator.parse('demarcheId'), - 'oct', + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), armDocuments, armEntrepriseDocuments, [], @@ -481,8 +517,7 @@ test("teste la complétude d'une demande d'ARM", () => { { ...testBlankUser, role: 'super', - }, - firstEtapeDateValidator.parse('2022-01-01') + } ) ).toStrictEqual({ valid: true, errors: null }) }) @@ -501,16 +536,13 @@ test.each<[SubstanceLegaleId[], EtapeTypeId, TitreTypeId, IsEtapeCompleteDocumen const result = isEtapeComplete( titreEtape, - titreType, - demarcheIdValidator.parse('demarcheId'), - 'oct', + MachineInfo.withDate(titreType, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), testDocuments, entrepriseDocuments, [], [], axmDemandeAvis, - { ...testBlankUser, role: 'super' }, - firstEtapeDateValidator.parse('2022-01-01') + { ...testBlankUser, role: 'super' } ) expect(result.valid, JSON.stringify(result)).toBe(true) @@ -530,16 +562,13 @@ test.each<[SubstanceLegaleId[], EtapeTypeId, TitreTypeId, IsEtapeCompleteDocumen const result = isEtapeComplete( titreEtape, - titreType, - demarcheIdValidator.parse('demarcheId'), - 'oct', + MachineInfo.withDate(titreType, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), testDocuments, entrepriseDocuments, [], [], [], - { ...testBlankUser, role: 'super' }, - firstEtapeDateValidator.parse('2022-01-01') + { ...testBlankUser, role: 'super' } ) const errorLabel = 'Les substances sont obligatoires' @@ -577,16 +606,13 @@ test.each<[FeatureMultiPolygon | null, EtapeTypeId, TitreTypeId, IsEtapeComplete const result = isEtapeComplete( titreEtape, - titreType, - demarcheIdValidator.parse('demarcheId'), - 'oct', + MachineInfo.withDate(titreType, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), documents, entrepriseDocuments, [], [], [], - { ...testBlankUser, role: 'super' }, - firstEtapeDateValidator.parse('2022-01-01') + { ...testBlankUser, role: 'super' } ) const errorLabel = 'le périmètre est obligatoire pour une démarche octroi' @@ -624,16 +650,13 @@ test.each<[FeatureMultiPolygon | null, EtapeTypeId, TitreTypeId, IsEtapeComplete const result = isEtapeComplete( titreEtape, - titreType, - demarcheIdValidator.parse('demarcheId'), - 'oct', + MachineInfo.withDate(titreType, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), documents, entrepriseDocuments, [], [], axmDemandeAvis, - { ...testBlankUser, role: 'super' }, - firstEtapeDateValidator.parse('2022-01-01') + { ...testBlankUser, role: 'super' } ) expect(result).toStrictEqual({ valid: true, errors: null }) @@ -642,16 +665,13 @@ test.each<[FeatureMultiPolygon | null, EtapeTypeId, TitreTypeId, IsEtapeComplete test("une demande d'ARM mécanisée a des documents obligatoires supplémentaires", () => { const errors = isEtapeComplete( { ...etapeComplete, contenu: { arm: { mecanise: { value: true, heritee: false, etapeHeritee: null } } } }, - 'arm', - demarcheIdValidator.parse('demarcheId'), - 'oct', + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), armDocuments, armEntrepriseDocuments, null, [], [], - { ...testBlankUser, role: 'super' }, - firstEtapeDateValidator.parse('2022-01-01') + { ...testBlankUser, role: 'super' } ) expect(errors).toMatchInlineSnapshot(` { @@ -668,10 +688,7 @@ test('isEtapeValide', () => { expect( isEtapeValid( { ...etapeComplete }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheIdValidator.parse('fakeId'), - firstEtapeDateValidator.parse(etapeComplete.date) + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('fakeId'), firstEtapeDateValidator.parse(etapeComplete.date)) ) ).toMatchInlineSnapshot(` { @@ -682,10 +699,12 @@ test('isEtapeValide', () => { expect( isEtapeValid( { ...etapeComplete, date: DATE_DEBUT_PROCEDURE_SPECIFIQUE, typeId: ETAPES_TYPES.demande, duree: { value: 10 * 10, heritee: false, etapeHeritee: null } }, - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, - demarcheIdValidator.parse('fakeId'), - firstEtapeDateValidator.parse(DATE_DEBUT_PROCEDURE_SPECIFIQUE) + MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheIdValidator.parse('fakeId'), + firstEtapeDateValidator.parse(DATE_DEBUT_PROCEDURE_SPECIFIQUE) + ) ) ).toMatchInlineSnapshot(` { @@ -715,16 +734,13 @@ test.each<[number | null, EtapeTypeId, TitreTypeId, IsEtapeCompleteDocuments, Is const result = isEtapeComplete( titreEtape, - titreType, - demarcheIdValidator.parse('demarcheId'), - 'oct', + MachineInfo.withDate(titreType, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), documents, entreprisedocuments, [], [], avis, - { ...testBlankUser, role: 'super' }, - firstEtapeDateValidator.parse('2022-01-01') + { ...testBlankUser, role: 'super' } ) const errorLabel = 'la durée est obligatoire pour une démarche octroi' @@ -744,40 +760,40 @@ describe('canDeposeEtape', () => { expect( canDeposeEtape( { ...testBlankUser, role: 'super' }, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), { - typeId: 'arm', titreStatutId: 'dmi', titulaires: [], administrationsLocales: [], }, - demarcheIdValidator.parse('demarcheId'), - 'oct', { ...etapeComplete, isBrouillon: ETAPE_IS_BROUILLON, contenu: { arm: { mecanise: { value: false, etapeHeritee: null, heritee: false } } } }, [...armDocuments], [...armEntrepriseDocuments], [], [], - [], - firstEtapeDateValidator.parse('2022-01-01') + [] ) ).toStrictEqual(true) }) }) describe('isEtapeDeposable', () => { + const machineInfo = MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheIdValidator.parse('demarcheId'), + firstEtapeDateValidator.parse('2022-01-01') + ) test("Une demande d'ARM complète brouillon", () => { expect( isEtapeDeposable( { ...testBlankUser, role: 'super' }, - 'arm', - demarcheIdValidator.parse('demarcheId'), - 'oct', + machineInfo, { ...etapeComplete, isBrouillon: ETAPE_IS_BROUILLON, contenu: { arm: { mecanise: { value: false, etapeHeritee: null, heritee: false } } } }, armDocuments, armEntrepriseDocuments, [], [], - [], - firstEtapeDateValidator.parse('2022-01-01') + [] ) ).toStrictEqual(true) }) @@ -786,36 +802,21 @@ describe('isEtapeDeposable', () => { expect( isEtapeDeposable( { ...testBlankUser, role: 'super' }, - 'arm', - demarcheIdValidator.parse('demarcheId'), - 'oct', + machineInfo, { ...etapeComplete, isBrouillon: ETAPE_IS_NOT_BROUILLON, contenu: { arm: { mecanise: { value: false, etapeHeritee: null, heritee: false } } } }, armDocuments, armEntrepriseDocuments, [], [], - [], - firstEtapeDateValidator.parse('2022-01-01') + [] ) ).toStrictEqual(false) }) test("Une demande d'ARM incomplète", () => { - expect( - isEtapeDeposable( - { ...testBlankUser, role: 'super' }, - 'arm', - demarcheIdValidator.parse('demarcheId'), - 'oct', - { ...etapeComplete, isBrouillon: ETAPE_IS_BROUILLON }, - armDocuments, - armEntrepriseDocuments, - [], - [], - [], - firstEtapeDateValidator.parse('2022-01-01') - ) - ).toStrictEqual(false) + expect(isEtapeDeposable({ ...testBlankUser, role: 'super' }, machineInfo, { ...etapeComplete, isBrouillon: ETAPE_IS_BROUILLON }, armDocuments, armEntrepriseDocuments, [], [], [])).toStrictEqual( + false + ) }) }) @@ -838,13 +839,10 @@ describe('dureeIsValide', () => { demarcheTypeId, duree: dureeAnnees, dureeIsValide: dureeIsValide( - titreTypeId, - demarcheTypeId, + MachineInfo.withDate(titreTypeId, demarcheTypeId, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, { value: dureeAnnees !== null ? dureeAnnees * 12 : dureeAnnees }, - surface, - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + surface ), }) }) @@ -941,7 +939,12 @@ describe('dureeIsValide', () => { result.push({ surface: km2toHectare(surface), duree: dureeAnnees, - dureeIsValide: dureeIsValide(titreTypeId, demarcheTypeId, ETAPES_TYPES.demande, { value: dureeAnnees * 12 }, surface, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), + dureeIsValide: dureeIsValide( + MachineInfo.withDate(titreTypeId, demarcheTypeId, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), + ETAPES_TYPES.demande, + { value: dureeAnnees * 12 }, + surface + ), }) }) }) @@ -963,7 +966,12 @@ describe('dureeIsValide', () => { result.push({ surface: km2toHectare(surface), duree: dureeAnnees, - dureeIsValide: dureeIsValide(titreTypeId, demarcheTypeId, ETAPES_TYPES.demande, { value: dureeAnnees * 12 }, surface, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), + dureeIsValide: dureeIsValide( + MachineInfo.withDate(titreTypeId, demarcheTypeId, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), + ETAPES_TYPES.demande, + { value: dureeAnnees * 12 }, + surface + ), }) }) }) @@ -1047,9 +1055,14 @@ describe('dureeIsValide', () => { surfaces.forEach(surface => { dureesAnnees.forEach(dureeAnnees => { - expect(dureeIsValide(titreTypeId, demarcheTypeId, ETAPES_TYPES.demande, { value: dureeAnnees * 12 }, surface, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)).valid).toBe( - true - ) + expect( + dureeIsValide( + MachineInfo.withDate(titreTypeId, demarcheTypeId, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), + ETAPES_TYPES.demande, + { value: dureeAnnees * 12 }, + surface + ).valid + ).toBe(true) }) }) }) @@ -1059,12 +1072,9 @@ describe('perimetreIsValide', () => { test('arm', () => { expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - km2Validator.parse(1), - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + km2Validator.parse(1) ) ).toMatchInlineSnapshot(` { @@ -1073,12 +1083,9 @@ describe('perimetreIsValide', () => { `) expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - km2Validator.parse(3), - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + km2Validator.parse(3) ) ).toMatchInlineSnapshot(` { @@ -1087,12 +1094,9 @@ describe('perimetreIsValide', () => { `) expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - km2Validator.parse(4), - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + km2Validator.parse(4) ) ).toMatchInlineSnapshot(` { @@ -1102,12 +1106,9 @@ describe('perimetreIsValide', () => { `) expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Prolongation, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - km2Validator.parse(4), - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + km2Validator.parse(4) ) ).toMatchInlineSnapshot(` { @@ -1118,12 +1119,9 @@ describe('perimetreIsValide', () => { expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Prolongation, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheId, firstEtapeDateValidator.parse(beforeProcedureSpecifiqueAxmArm)), ETAPES_TYPES.demande, - km2Validator.parse(4), - demarcheId, - firstEtapeDateValidator.parse(beforeProcedureSpecifiqueAxmArm) + km2Validator.parse(4) ) ).toMatchInlineSnapshot(` { @@ -1132,12 +1130,9 @@ describe('perimetreIsValide', () => { `) expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Prolongation, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.decisionDeLAutoriteAdministrative, - km2Validator.parse(4), - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + km2Validator.parse(4) ) ).toMatchInlineSnapshot(` { @@ -1155,12 +1150,9 @@ describe('perimetreIsValide', () => { expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - hectares_20, - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + hectares_20 ) ).toMatchInlineSnapshot(` { @@ -1169,12 +1161,9 @@ describe('perimetreIsValide', () => { `) expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - hectares_100, - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + hectares_100 ) ).toMatchInlineSnapshot(` { @@ -1183,12 +1172,9 @@ describe('perimetreIsValide', () => { `) expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - hectares_101, - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + hectares_101 ) ).toMatchInlineSnapshot(` { @@ -1198,12 +1184,9 @@ describe('perimetreIsValide', () => { `) expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Prolongation, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - hectares_20, - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + hectares_20 ) ).toMatchInlineSnapshot(` { @@ -1212,12 +1195,9 @@ describe('perimetreIsValide', () => { `) expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Prolongation, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - hectares_25, - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + hectares_25 ) ).toMatchInlineSnapshot(` { @@ -1226,12 +1206,9 @@ describe('perimetreIsValide', () => { `) expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Prolongation, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - hectares_26, - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + hectares_26 ) ).toMatchInlineSnapshot(` { @@ -1242,12 +1219,9 @@ describe('perimetreIsValide', () => { expect( perimetreIsValide( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.RenonciationTotale, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.RenonciationTotale, demarcheId, firstEtapeDateValidator.parse(duringProcedureSpecifique)), ETAPES_TYPES.demande, - hectares_100, - demarcheId, - firstEtapeDateValidator.parse(duringProcedureSpecifique) + hectares_100 ) ).toMatchInlineSnapshot(` { diff --git a/packages/common/src/permissions/titres-etapes.ts b/packages/common/src/permissions/titres-etapes.ts index 243d465120f63a1a4920d2ff8d3fa16764dc1e2f..370e14de4a101a51ddab0340d75f51b1ade06801 100644 --- a/packages/common/src/permissions/titres-etapes.ts +++ b/packages/common/src/permissions/titres-etapes.ts @@ -25,18 +25,16 @@ import { DemarcheTypeId, DEMARCHES_TYPES_IDS, DemarchesTypes, isDemarcheTypeProl import { EtapeTypeId, ETAPES_TYPES, EtapesTypes, isEtapeDecision } from '../static/etapesTypes' import { TITRES_TYPES_IDS_DEMAT } from './titres' import { KM2, km2toHectare, ZERO_KM2 } from '../number' -import { machineIdFind } from '../machines' -import { DemarcheId } from '../demarche' -import { FirstEtapeDate } from '../date' +import { MachineInfo } from '../machines' export type InputAbsent = { visibility: 'absent'; message: string } type InputPresentRequired = { visibility: 'present'; required: true; message: string } export type InputPresentOptional = { visibility: 'present'; required: false } export type InputPresence = InputAbsent | InputPresentRequired | InputPresentOptional -export const canEditAmodiataires = (titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId, user: User): InputPresence => { - if (titreTypeId === TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX || titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX) { - return { visibility: 'absent', message: `une autorisation ${titreTypeId === 'arm' ? 'de recherche' : "d'exploitation"} ne peut pas inclure d'amodiataires` } +export const canEditAmodiataires = (machineInfo: MachineInfo, user: User): InputPresence => { + if (machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX || machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX) { + return { visibility: 'absent', message: `une autorisation ${machineInfo.titreTypeId === 'arm' ? 'de recherche' : "d'exploitation"} ne peut pas inclure d'amodiataires` } } if ( @@ -49,14 +47,14 @@ export const canEditAmodiataires = (titreTypeId: TitreTypeId, demarcheTypeId: De DEMARCHES_TYPES_IDS.Conversion, DEMARCHES_TYPES_IDS.ExtensionDePerimetre, DEMARCHES_TYPES_IDS.ResiliationAnticipeeDAmodiation, - ].includes(demarcheTypeId) + ].includes(machineInfo.demarcheTypeId) ) { - return { visibility: 'absent', message: `une démarche ${DemarchesTypes[demarcheTypeId].nom} ne peut pas inclure d'amodiataire` } + return { visibility: 'absent', message: `une démarche ${DemarchesTypes[machineInfo.demarcheTypeId].nom} ne peut pas inclure d'amodiataire` } } // seuls les supers et les administrations peuvent éditer les amodiataires if (isSuper(user) || isAdministrationAdmin(user) || isAdministrationEditeur(user)) { - if (demarcheTypeId === DEMARCHES_TYPES_IDS.Amodiation) { + if (machineInfo.demarcheTypeId === DEMARCHES_TYPES_IDS.Amodiation) { return { visibility: 'present', required: true, message: "les amodiataires sont obligatoires pour les démarches d'Amodiation" } } @@ -69,9 +67,9 @@ export const canEditAmodiataires = (titreTypeId: TitreTypeId, demarcheTypeId: De const demarchesSansDatesNiDureePourLesEtapes = [DEMARCHES_TYPES_IDS.Mutation, DEMARCHES_TYPES_IDS.ExtensionDePerimetre] as const // Attention les champs dates ne sont jamais obligatoires, si ils le deviennent il faudra faire des modifs dans la validation et dans l'ui -export const canEditDates = (_titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId, etapeTypeId: EtapeTypeId, user: User): InputAbsent | InputPresentOptional => { - if (demarchesSansDatesNiDureePourLesEtapes.includes(demarcheTypeId)) { - return { visibility: 'absent', message: `une démarche ${DemarchesTypes[demarcheTypeId].nom} ne peut pas inclure de date` } +export const canEditDates = (machineInfo: MachineInfo, etapeTypeId: EtapeTypeId, user: User): InputAbsent | InputPresentOptional => { + if (demarchesSansDatesNiDureePourLesEtapes.includes(machineInfo.demarcheTypeId)) { + return { visibility: 'absent', message: `une démarche ${DemarchesTypes[machineInfo.demarcheTypeId].nom} ne peut pas inclure de date` } } if (!isEtapeDecision(etapeTypeId)) { @@ -85,7 +83,7 @@ export const canEditDates = (_titreTypeId: TitreTypeId, demarcheTypeId: Demarche return { visibility: 'absent', message: 'droits insuffisants pour éditer les dates' } } -export const canEditTitulaires = (_titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId, user: User): InputPresence => { +export const canEditTitulaires = (machineInfo: MachineInfo, user: User): InputPresence => { if ( [ DEMARCHES_TYPES_IDS.Fusion, @@ -95,39 +93,35 @@ export const canEditTitulaires = (_titreTypeId: TitreTypeId, demarcheTypeId: Dem DEMARCHES_TYPES_IDS.Conversion, DEMARCHES_TYPES_IDS.ExtensionDePerimetre, DEMARCHES_TYPES_IDS.ResiliationAnticipeeDAmodiation, - ].includes(demarcheTypeId) + ].includes(machineInfo.demarcheTypeId) ) { - return { visibility: 'absent', message: `une démarche ${DemarchesTypes[demarcheTypeId].nom} ne peut pas inclure de titulaire` } + return { visibility: 'absent', message: `une démarche ${DemarchesTypes[machineInfo.demarcheTypeId].nom} ne peut pas inclure de titulaire` } } // seuls les supers et les administrations peuvent éditer les titulaires if (isSuper(user) || isAdministrationAdmin(user) || isAdministrationEditeur(user)) { - return { visibility: 'present', required: true, message: `les titulaires sont obligatoires pour les démarches ${DemarchesTypes[demarcheTypeId].nom}` } + return { visibility: 'present', required: true, message: `les titulaires sont obligatoires pour les démarches ${DemarchesTypes[machineInfo.demarcheTypeId].nom}` } } return { visibility: 'absent', message: 'droits insuffisants pour éditer les titulaires' } } export const dureeIsValide = ( - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, + machineInfo: MachineInfo, etapeTypeId: EtapeTypeId, dureeValue: Pick<FlattenEtape['duree'], 'value'>, - surfaceKm2: KM2, - demarcheId: DemarcheId, - date: FirstEtapeDate + surfaceKm2: KM2 ): { valid: true } | { valid: false; message: string } => { - const machineId = machineIdFind(titreTypeId, demarcheTypeId, demarcheId, date) - if (etapeTypeId === ETAPES_TYPES.demande && machineId === 'ProcedureSpecifique') { + if (etapeTypeId === ETAPES_TYPES.demande && machineInfo.machineId === 'ProcedureSpecifique') { const duree = dureeValue.value ?? 0 const surface = km2toHectare(surfaceKm2) - if (titreTypeId === TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX && demarcheTypeId === DEMARCHES_TYPES_IDS.Octroi && duree > 2 * 12) { + if (machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX && machineInfo.demarcheTypeId === DEMARCHES_TYPES_IDS.Octroi && duree > 2 * 12) { return { valid: false, message: `Un octroi d'ARM ne peut pas dépasser 2 ans` } } - if (titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX) { - if (demarcheTypeId === DEMARCHES_TYPES_IDS.Octroi) { + if (machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX) { + if (machineInfo.demarcheTypeId === DEMARCHES_TYPES_IDS.Octroi) { if (surface <= 25 && duree > 4 * 12) { return { valid: false, message: `Un octroi d'AEX inférieur ou égal à 25 hectares ne peut pas dépasser 4 ans` } } @@ -135,7 +129,7 @@ export const dureeIsValide = ( return { valid: false, message: `Un octroi d'AEX supérieur à 25 hectares et inférieur ou égal à 100 hectares ne peut pas dépasser 10 ans` } } } - if (isDemarcheTypeProlongations(demarcheTypeId)) { + if (isDemarcheTypeProlongations(machineInfo.demarcheTypeId)) { if (surface <= 25 && duree > 4 * 12) { return { valid: false, message: `Une prolongation d'AEX inférieure ou égale à 25 hectares ne peut pas dépasser 4 ans` } } @@ -146,39 +140,31 @@ export const dureeIsValide = ( return { valid: true } } -export const canEditDuree = (_titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId, _user: User): InputPresence => { +export const canEditDuree = (machineInfo: MachineInfo, _user: User): InputPresence => { // par exemple, ne peut pas ajouter de durée à la démarche déplacement de périmètre - if (demarchesSansDatesNiDureePourLesEtapes.includes(demarcheTypeId)) { - return { visibility: 'absent', message: `une démarche ${DemarchesTypes[demarcheTypeId].nom} ne peut pas inclure de durée` } + if (demarchesSansDatesNiDureePourLesEtapes.includes(machineInfo.demarcheTypeId)) { + return { visibility: 'absent', message: `une démarche ${DemarchesTypes[machineInfo.demarcheTypeId].nom} ne peut pas inclure de durée` } } - return { visibility: 'present', required: true, message: `la durée est obligatoire pour une démarche ${DemarchesTypes[demarcheTypeId].nom}` } + return { visibility: 'present', required: true, message: `la durée est obligatoire pour une démarche ${DemarchesTypes[machineInfo.demarcheTypeId].nom}` } } -export const perimetreIsValide = ( - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - etapeTypeId: EtapeTypeId, - surfaceKm2: KM2, - demarcheId: DemarcheId, - date: FirstEtapeDate -): { valid: true } | { valid: false; message: string } => { - const machineId = machineIdFind(titreTypeId, demarcheTypeId, demarcheId, date) - if (etapeTypeId === ETAPES_TYPES.demande && machineId === 'ProcedureSpecifique') { +export const perimetreIsValide = (machineInfo: MachineInfo, etapeTypeId: EtapeTypeId, surfaceKm2: KM2): { valid: true } | { valid: false; message: string } => { + if (etapeTypeId === ETAPES_TYPES.demande && machineInfo.machineId === 'ProcedureSpecifique') { const surface = km2toHectare(surfaceKm2) - if (titreTypeId === TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX) { + if (machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX) { if (surfaceKm2 > 3) { return { valid: false, message: `Une ARM supérieure à 3km² est interdit` } } } - if (titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX) { - if (demarcheTypeId === DEMARCHES_TYPES_IDS.Octroi) { + if (machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX) { + if (machineInfo.demarcheTypeId === DEMARCHES_TYPES_IDS.Octroi) { if (surface > 100) { return { valid: false, message: `Un octroi d'AEX supérieur à 100 hectares est interdit` } } } - if (isDemarcheTypeProlongations(demarcheTypeId)) { + if (isDemarcheTypeProlongations(machineInfo.demarcheTypeId)) { if (surface > 25) { return { valid: false, message: `Une prolongation d'AEX supérieure à 25 hectares est interdit` } } @@ -188,7 +174,7 @@ export const perimetreIsValide = ( return { valid: true } } -export const canEditPerimetre = (demarcheTypeId: DemarcheTypeId, etapeTypeId: EtapeTypeId): InputPresence => { +export const canEditPerimetre = (machineInfo: MachineInfo, etapeTypeId: EtapeTypeId): InputPresence => { if (!EtapesTypes[etapeTypeId].fondamentale) { return { visibility: 'absent', message: `une étape ${EtapesTypes[etapeTypeId].nom} ne peut pas inclure de périmètre` } } @@ -201,12 +187,12 @@ export const canEditPerimetre = (demarcheTypeId: DemarcheTypeId, etapeTypeId: Et DEMARCHES_TYPES_IDS.Amodiation, DEMARCHES_TYPES_IDS.Conversion, DEMARCHES_TYPES_IDS.ResiliationAnticipeeDAmodiation, - ].includes(demarcheTypeId) + ].includes(machineInfo.demarcheTypeId) ) { - return { visibility: 'absent', message: `une démarche ${DemarchesTypes[demarcheTypeId].nom} ne peut pas inclure de périmètre` } + return { visibility: 'absent', message: `une démarche ${DemarchesTypes[machineInfo.demarcheTypeId].nom} ne peut pas inclure de périmètre` } } - return { visibility: 'present', required: true, message: `le périmètre est obligatoire pour une démarche ${DemarchesTypes[demarcheTypeId].nom}` } + return { visibility: 'present', required: true, message: `le périmètre est obligatoire pour une démarche ${DemarchesTypes[machineInfo.demarcheTypeId].nom}` } } export const canCreateEtape = ( @@ -283,18 +269,9 @@ type IsEtapeCompleteSdomZones = SDOMZoneId[] | null | undefined type IsEtapeCompleteCommunes = CommuneId[] export type IsEtapeCompleteEtapeAvis = Pick<EtapeAvis, 'avis_type_id'>[] -export const isEtapeValid = ( - etape: IsEtapeCompleteEtape, - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - demarcheId: DemarcheId, - firstEtapeDate: FirstEtapeDate -): { valid: true } | { valid: false; errors: NonEmptyArray<string> } => { +export const isEtapeValid = (etape: IsEtapeCompleteEtape, machineInfo: MachineInfo): { valid: true } | { valid: false; errors: NonEmptyArray<string> } => { const surface = etape.perimetre.value?.surface ?? ZERO_KM2 - const isValidChecks = [ - dureeIsValide(titreTypeId, demarcheTypeId, etape.typeId, etape.duree, surface, demarcheId, firstEtapeDate), - perimetreIsValide(titreTypeId, demarcheTypeId, etape.typeId, surface, demarcheId, firstEtapeDate), - ] + const isValidChecks = [dureeIsValide(machineInfo, etape.typeId, etape.duree, surface), perimetreIsValide(machineInfo, etape.typeId, surface)] const errors: string[] = isValidChecks.reduce<string[]>((acc, c) => { if (!c.valid) { acc.push(c.message) @@ -312,30 +289,26 @@ export const isEtapeValid = ( export const isEtapeComplete = ( etape: IsEtapeCompleteEtape, - titreTypeId: TitreTypeId, - demarcheId: DemarcheId, - demarcheTypeId: DemarcheTypeId, + machineInfo: MachineInfo, documents: IsEtapeCompleteDocuments, entrepriseDocuments: IsEtapeCompleteEntrepriseDocuments, sdomZones: IsEtapeCompleteSdomZones, communes: IsEtapeCompleteCommunes, etapeAvis: IsEtapeCompleteEtapeAvis, - user: User, - firstEtapeDate: FirstEtapeDate + user: User ): { valid: true; errors: null } | { valid: false; errors: NonEmptyArray<string> } => { const isCompleteChecks = [ dateTypeStepIsComplete(etape, user), - fondamentaleStepIsComplete(etape, demarcheTypeId, titreTypeId, user), - sectionsStepIsComplete(etape, demarcheTypeId, titreTypeId), - perimetreStepIsComplete(etape, demarcheTypeId), - etapeDocumentsStepIsComplete(etape, demarcheTypeId, titreTypeId, demarcheId, documents, sdomZones ?? [], firstEtapeDate), + fondamentaleStepIsComplete(etape, machineInfo, user), + sectionsStepIsComplete(etape, machineInfo), + perimetreStepIsComplete(etape, machineInfo), + etapeDocumentsStepIsComplete(etape, machineInfo, documents, sdomZones ?? []), entrepriseDocumentsStepIsComplete( etape, - demarcheTypeId, - titreTypeId, + machineInfo, entrepriseDocuments.map(ed => ({ documentTypeId: ed.entreprise_document_type_id, entrepriseId: ed.entreprise_id })) ), - etapeAvisStepIsComplete(etape, etapeAvis, titreTypeId, demarcheTypeId, demarcheId, firstEtapeDate, communes), + etapeAvisStepIsComplete(etape, etapeAvis, machineInfo, communes), ] const errors: string[] = isCompleteChecks.reduce<string[]>((acc, c) => { if (!c.valid) { @@ -355,19 +328,16 @@ export const isEtapeComplete = ( type IsEtapeDeposableEtapeAvis = Pick<EtapeAvis | TempEtapeAvis, 'avis_type_id'>[] export const isEtapeDeposable = ( user: User, - titreTypeId: TitreTypeId, - demarcheId: DemarcheId, - demarcheTypeId: DemarcheTypeId, + machineInfo: MachineInfo, titreEtape: Pick<FlattenEtape, 'typeId' | 'date' | 'statutId' | 'duree' | 'contenu' | 'substances' | 'perimetre' | 'isBrouillon' | 'titulaires' | 'amodiataires'>, etapeDocuments: IsEtapeCompleteDocuments, entrepriseDocuments: IsEtapeCompleteEntrepriseDocuments, sdomZones: IsEtapeCompleteSdomZones, communes: IsEtapeCompleteCommunes, - etapeAvis: IsEtapeDeposableEtapeAvis, - firstEtapeDate: FirstEtapeDate + etapeAvis: IsEtapeDeposableEtapeAvis ): boolean => { if (titreEtape.isBrouillon === ETAPE_IS_BROUILLON) { - const complete = isEtapeComplete(titreEtape, titreTypeId, demarcheId, demarcheTypeId, etapeDocuments, entrepriseDocuments, sdomZones, communes, etapeAvis, user, firstEtapeDate) + const complete = isEtapeComplete(titreEtape, machineInfo, etapeDocuments, entrepriseDocuments, sdomZones, communes, etapeAvis, user) if (!complete.valid) { console.warn(complete.errors) @@ -382,32 +352,29 @@ export const isEtapeDeposable = ( export const canDeposeEtape = ( user: User, + machineInfo: MachineInfo, titre: { - typeId: TitreTypeId titreStatutId: TitreStatutId titulaires: EntrepriseId[] administrationsLocales: AdministrationId[] }, - demarcheId: DemarcheId, - demarcheTypeId: DemarcheTypeId, titreEtape: Pick<FlattenEtape, 'typeId' | 'date' | 'statutId' | 'duree' | 'contenu' | 'substances' | 'perimetre' | 'isBrouillon' | 'titulaires' | 'amodiataires'>, etapeDocuments: Pick<EtapeDocument, 'etape_document_type_id'>[], entrepriseDocuments: Pick<EntrepriseDocument, 'entreprise_document_type_id' | 'entreprise_id'>[], sdomZones: SDOMZoneId[] | null | undefined, communes: CommuneId[], - etapeAvis: IsEtapeDeposableEtapeAvis, - firstEtapeDate: FirstEtapeDate + etapeAvis: IsEtapeDeposableEtapeAvis ): boolean => { return ( - isEtapeDeposable(user, titre.typeId, demarcheId, demarcheTypeId, titreEtape, etapeDocuments, entrepriseDocuments, sdomZones, communes, etapeAvis, firstEtapeDate) && + isEtapeDeposable(user, machineInfo, titreEtape, etapeDocuments, entrepriseDocuments, sdomZones, communes, etapeAvis) && canCreateOrEditEtape( user, titreEtape.typeId, titreEtape.isBrouillon, titre.titulaires, titre.administrationsLocales, - demarcheTypeId, - { typeId: titre.typeId, titreStatutId: titre.titreStatutId }, + machineInfo.demarcheTypeId, + { typeId: machineInfo.titreTypeId, titreStatutId: titre.titreStatutId }, 'modification' ) ) diff --git a/packages/common/src/permissions/titres.test.ts b/packages/common/src/permissions/titres.test.ts index 3871a67dc7deb1bc51df0baad22d47e34049e8c5..444e445946bf4eaab891bfe445d49add581da63e 100644 --- a/packages/common/src/permissions/titres.test.ts +++ b/packages/common/src/permissions/titres.test.ts @@ -10,7 +10,7 @@ import { canSeeTitreLastModifiedDate, getLinkConfig, } from './titres' -import { TitresTypesIds, TitreTypeId } from '../static/titresTypes' +import { TITRES_TYPES_IDS, TitresTypesIds, TitreTypeId } from '../static/titresTypes' import { ADMINISTRATION_IDS, AdministrationId } from '../static/administrations' import { test, expect, describe } from 'vitest' import { testBlankUser, TestUser } from '../tests-utils' @@ -20,6 +20,10 @@ import { ACTIVITES_TYPES_IDS } from '../static/activitesTypes' import { toCommuneId } from '../static/communes' import { TitreStatutId, titresStatutsArray } from '../static/titresStatuts' import { isAssociee, isGestionnaire } from '../static/administrationsTitresTypes' +import { MachineInfo } from '../machines' +import { DEMARCHES_TYPES_IDS } from '../static/demarchesTypes' +import { firstEtapeDateValidator } from '../date' +import { demarcheIdValidator } from '../demarche' const shouldNotBeCalled = () => Promise.reject(new Error('should not be called')) @@ -44,8 +48,16 @@ test('canHaveActivites', () => { }) test('canHaveForages', () => { - expect(canHaveForages('apc')).toBe(false) - expect(canHaveForages('pxg')).toBe(true) + expect( + canHaveForages( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_CARRIERES, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')) + ) + ).toBe(false) + expect( + canHaveForages( + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')) + ) + ).toBe(true) }) test('getTitreFromTypeId pas de fusions', () => { diff --git a/packages/common/src/permissions/titres.ts b/packages/common/src/permissions/titres.ts index 12f1348736a7871178c08c141501605cfd50e8e7..0d0d0df5d1dea1e39e71b2c80504df2ca63d90c3 100644 --- a/packages/common/src/permissions/titres.ts +++ b/packages/common/src/permissions/titres.ts @@ -14,6 +14,7 @@ import { isNotNullNorUndefinedNorEmpty, isNullOrUndefinedOrEmpty, SimplePromiseF import { SecteursMaritimes } from '../static/facades' import { EntrepriseId } from '../entreprise' import { TITRES_TYPES_TYPES_IDS } from '../static/titresTypesTypes' +import { MachineInfo } from '../machines' export const canSeeTitreLastModifiedDate = (user: User): boolean => isSuper(user) || isAdministration(user) export type LinkConfig = { count: 'single' | 'multiple'; typeId: TitreTypeId } @@ -150,4 +151,4 @@ export const canHaveActiviteTypeId = (activiteTypeId: ActivitesTypesId, titre: T return false } -export const canHaveForages = (titreTypeId: TitreTypeId): boolean => titreTypeId === 'pxg' +export const canHaveForages = (machineInfo: MachineInfo): boolean => machineInfo.titreTypeId === TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_GEOTHERMIE diff --git a/packages/common/src/sections.test.ts b/packages/common/src/sections.test.ts index 3d5285cfe742a428e9617fc456c3a5ba06120dea..bede292e143c940c296b9159f068db3b223b5843 100644 --- a/packages/common/src/sections.test.ts +++ b/packages/common/src/sections.test.ts @@ -1,6 +1,11 @@ import { test, expect } from 'vitest' import { flattenContenuToSimpleContenu, isRadioElement, simpleContenuToFlattenedContenu, valeurFind } from './sections' -import { caminoDateValidator, toCaminoDate } from './date' +import { caminoDateValidator, firstEtapeDateValidator, toCaminoDate } from './date' +import { MachineInfo } from './machines' +import { TITRES_TYPES_IDS } from './static/titresTypes' +import { DEMARCHES_TYPES_IDS } from './static/demarchesTypes' +import { ETAPES_TYPES } from './static/etapesTypes' +import { demarcheIdValidator } from './demarche' test('valeurFind', () => { expect(valeurFind({ id: 'camino', type: 'text', value: null, optionnel: false })).toBe('–') @@ -81,11 +86,10 @@ test('isRadioElement', () => { test('simpleContenuToFlattenedContenu', () => { expect( simpleContenuToFlattenedContenu( - 'arm', - 'oct', - 'mfr', + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), + ETAPES_TYPES.demande, { arm: { mecanise: true } }, - { arm: { mecanise: { actif: true, etape: { date: caminoDateValidator.parse('2023-02-02'), typeId: 'mfr', contenu: { arm: { mecanise: false } } } } } } + { arm: { mecanise: { actif: true, etape: { date: caminoDateValidator.parse('2023-02-02'), typeId: ETAPES_TYPES.demande, contenu: { arm: { mecanise: false } } } } } } ) ).toMatchInlineSnapshot(` { @@ -109,11 +113,10 @@ test('simpleContenuToFlattenedContenu', () => { `) expect( simpleContenuToFlattenedContenu( - 'arm', - 'oct', - 'mfr', + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), + ETAPES_TYPES.demande, { arm: { mecanise: true } }, - { arm: { mecanise: { actif: false, etape: { date: caminoDateValidator.parse('2023-02-02'), typeId: 'mfr', contenu: { arm: { mecanise: false } } } } } } + { arm: { mecanise: { actif: false, etape: { date: caminoDateValidator.parse('2023-02-02'), typeId: ETAPES_TYPES.demande, contenu: { arm: { mecanise: false } } } } } } ) ).toMatchInlineSnapshot(` { @@ -137,11 +140,10 @@ test('simpleContenuToFlattenedContenu', () => { `) expect( simpleContenuToFlattenedContenu( - 'arm', - 'oct', - 'mfr', + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01')), + ETAPES_TYPES.demande, { arm: {} }, - { arm: { mecanise: { actif: true, etape: { date: caminoDateValidator.parse('2023-02-02'), typeId: 'mfr', contenu: { arm: {} } } } } } + { arm: { mecanise: { actif: true, etape: { date: caminoDateValidator.parse('2023-02-02'), typeId: ETAPES_TYPES.demande, contenu: { arm: {} } } } } } ) ).toMatchInlineSnapshot(` { @@ -178,7 +180,7 @@ test('flattenContenuToSimpleContenu', () => { mecanise: { etapeHeritee: { date: toCaminoDate('2023-02-02'), - etapeTypeId: 'mfr', + etapeTypeId: ETAPES_TYPES.demande, value: false, }, heritee: false, diff --git a/packages/common/src/sections.ts b/packages/common/src/sections.ts index 4231561877aa56e0de1c1c3fff8f179922d544c9..e90df463206c2f651d46f197f202383e0c5ea9a9 100644 --- a/packages/common/src/sections.ts +++ b/packages/common/src/sections.ts @@ -13,10 +13,9 @@ import { } from './static/titresTypes_demarchesTypes_etapesTypes/sections' import { z } from 'zod' import { isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty } from './typescript-tools' -import { TitreTypeId } from './static/titresTypes' -import { DemarcheTypeId } from './static/demarchesTypes' import { EtapeTypeId } from './static/etapesTypes' import { EtapeContenu, FlattenEtape, FlattenedContenu, RestEtapeCreation, HeritageContenu } from './etape-form' +import { MachineInfo } from './machines' const dateElementWithValueValidator = dateElementValidator.extend({ value: caminoDateValidator.nullable() }) @@ -99,14 +98,8 @@ export const valeurFind = (element: ElementWithValue): string | '–' => { return element.value } -export const simpleContenuToFlattenedContenu = ( - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - etapeTypeId: EtapeTypeId, - contenu: EtapeContenu, - heritageContenu: HeritageContenu -): FlattenedContenu => { - const sections = getSections(titreTypeId, demarcheTypeId, etapeTypeId) +export const simpleContenuToFlattenedContenu = (machineInfo: MachineInfo, etapeTypeId: EtapeTypeId, contenu: EtapeContenu, heritageContenu: HeritageContenu): FlattenedContenu => { + const sections = getSections(machineInfo, etapeTypeId) return sections.reduce<FlattenedContenu>((accSection, section) => { accSection[section.id] = section.elements.reduce<NonNullable<FlattenedContenu[string]>>((accElement, element) => { diff --git a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/documents.test.ts b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/documents.test.ts index ec36bb4730d178f4795435dffe73427f1965e68a..a4744369bcb09c7a4a5a653f21fcd48c9002247a 100644 --- a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/documents.test.ts +++ b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/documents.test.ts @@ -1,5 +1,6 @@ import { firstEtapeDateValidator } from '../../date' import { demarcheIdValidator } from '../../demarche' +import { MachineInfo } from '../../machines' import { DEMARCHES_TYPES_IDS } from '../demarchesTypes' import { ETAPES_TYPES } from '../etapesTypes' import { IS_ARM_MECANISE, IS_ARM_NON_MECANISE } from '../mecanise' @@ -14,7 +15,14 @@ test('toDocuments', () => { const firstEtapeDate = firstEtapeDateValidator.parse('2020-11-01') const demarcheId = demarcheIdValidator.parse('id1Demarche') test('getDocuments pas de surcharge mais pas de documents', () => { - expect(getDocuments('apm', 'amo', 'pqr', firstEtapeDate, demarcheId, [], IS_ARM_NON_MECANISE)).toMatchInlineSnapshot(` + expect( + getDocuments( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_METAUX, DEMARCHES_TYPES_IDS.Amodiation, demarcheId, firstEtapeDate), + ETAPES_TYPES.publicationDansUnJournalLocalOuNational, + [], + IS_ARM_NON_MECANISE + ) + ).toMatchInlineSnapshot(` [ { "id": "aut", @@ -26,7 +34,14 @@ test('getDocuments pas de surcharge mais pas de documents', () => { }) test('getDocuments pas de surcharge', () => { - expect(getDocuments('apm', 'amo', 'wfo', firstEtapeDate, demarcheId, [], IS_ARM_NON_MECANISE)).toMatchInlineSnapshot(` + expect( + getDocuments( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_METAUX, DEMARCHES_TYPES_IDS.Amodiation, demarcheId, firstEtapeDate), + ETAPES_TYPES.declarationDouvertureDeTravauxMiniers_DOTM_, + [], + IS_ARM_NON_MECANISE + ) + ).toMatchInlineSnapshot(` [ { "id": "dcl", @@ -43,19 +58,22 @@ test('getDocuments pas de surcharge', () => { }) test('getDocuments surcharge', () => { - expect(getDocuments('axm', 'oct', 'mfr', firstEtapeDate, demarcheId, [], IS_ARM_NON_MECANISE)).toMatchSnapshot() + expect( + getDocuments(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), ETAPES_TYPES.demande, [], IS_ARM_NON_MECANISE) + ).toMatchSnapshot() - expect(getDocuments('axm', 'oct', 'mfr', firstEtapeDate, demarcheId, [], IS_ARM_NON_MECANISE)).not.toEqual(getDocuments('axm', 'ces', 'mfr', firstEtapeDate, demarcheId, [], IS_ARM_NON_MECANISE)) + expect( + getDocuments(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), ETAPES_TYPES.demande, [], IS_ARM_NON_MECANISE) + ).not.toEqual( + getDocuments(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Cession, demarcheId, firstEtapeDate), ETAPES_TYPES.demande, [], IS_ARM_NON_MECANISE) + ) }) test("la lettre des saisines est obligatoire pour l'avis des services et commissions consultatives", () => { expect( getDocuments( - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives, - firstEtapeDate, - demarcheId, [], IS_ARM_NON_MECANISE ) @@ -78,11 +96,8 @@ test("la lettre des saisines est obligatoire pour l'avis des services et commiss test("le courrier de notification au préfet est obligatoire pour l'information du préfet et des collectivités", () => { expect( getDocuments( - TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), ETAPES_TYPES.informationDuPrefetEtDesCollectivites, - firstEtapeDate, - demarcheId, [], IS_ARM_NON_MECANISE ) @@ -105,11 +120,8 @@ test("le courrier de notification au préfet est obligatoire pour l'information test('getDocuments', () => { expect( getDocuments( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), ETAPES_TYPES.consultationDesAdministrationsCentrales, - firstEtapeDateValidator.parse('2022-01-01'), - demarcheIdValidator.parse('demarcheId'), [], IS_ARM_NON_MECANISE ) @@ -130,11 +142,8 @@ test('getDocuments', () => { expect( getDocuments( - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), ETAPES_TYPES.demande, - firstEtapeDateValidator.parse('2022-01-01'), - demarcheIdValidator.parse('demarcheId'), [], IS_ARM_NON_MECANISE ) @@ -241,11 +250,8 @@ test('getDocuments', () => { expect( getDocuments( - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), ETAPES_TYPES.demande, - firstEtapeDateValidator.parse('2022-01-01'), - demarcheIdValidator.parse('demarcheId'), [], IS_ARM_MECANISE ) @@ -351,11 +357,8 @@ test('getDocuments', () => { `) expect( getDocuments( - TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2024-10-01')), ETAPES_TYPES.demande, - firstEtapeDateValidator.parse('2024-10-01'), - demarcheIdValidator.parse('demarcheId'), [], IS_ARM_MECANISE ) @@ -461,33 +464,24 @@ test('getDocuments', () => { `) expect( getDocuments( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), ETAPES_TYPES.demande, - firstEtapeDateValidator.parse('2022-01-01'), - demarcheIdValidator.parse('demarcheId'), ['1'], IS_ARM_NON_MECANISE ) ).toMatchSnapshot() expect( getDocuments( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2022-01-01')), ETAPES_TYPES.demande, - firstEtapeDateValidator.parse('2022-01-01'), - demarcheIdValidator.parse('demarcheId'), ['2'], IS_ARM_NON_MECANISE ) ).toMatchSnapshot() expect( getDocuments( - TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, - DEMARCHES_TYPES_IDS.Octroi, + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2024-12-01')), ETAPES_TYPES.demande, - firstEtapeDateValidator.parse('2024-12-01'), - demarcheIdValidator.parse('demarcheId'), ['2'], IS_ARM_NON_MECANISE ) diff --git a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/documents.ts b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/documents.ts index 9482cba7362e43aeb5d7c22fa1b8eef2a54f48e1..012777e33dc77420206832d0d03d0fee972349e4 100644 --- a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/documents.ts +++ b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/documents.ts @@ -1,6 +1,4 @@ -import { FirstEtapeDate } from '../../date' -import { DemarcheId } from '../../demarche' -import { isProcedureOuverte, machineIdFind } from '../../machines' +import { isProcedureOuverte, MachineInfo } from '../../machines' import { getEntriesHardcore, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty } from '../../typescript-tools' import { IS_ARM_MECANISE, IsArmMecanise } from '../mecanise' import { SDOMZoneId } from '../sdom' @@ -359,26 +357,17 @@ export const toDocuments = (): ToDocument[] => { values.map(value => ({ etapeTypeId: key, documentTypeId: value.documentTypeId, description: null, optionnel: value.optionnel })) ) } -export const getDocuments = ( - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - etapeTypeId: EtapeTypeId, - firstEtapeDate: FirstEtapeDate, - demarcheId: DemarcheId, - sdomZoneIds: SDOMZoneId[], - isArmMecanise: IsArmMecanise -): (DocumentType | AutreDocumentType)[] => { +export const getDocuments = (machineInfo: MachineInfo, etapeTypeId: EtapeTypeId, sdomZoneIds: SDOMZoneId[], isArmMecanise: IsArmMecanise): (DocumentType | AutreDocumentType)[] => { const documentTypes: (DocumentType | AutreDocumentType)[] = [] - const machineId = machineIdFind(titreTypeId, demarcheTypeId, demarcheId, firstEtapeDate) if (isEtapesTypesEtapesTypesDocumentsTypes(etapeTypeId)) { documentTypes.push(...EtapesTypesDocumentsTypes[etapeTypeId].map(({ documentTypeId, optionnel }) => ({ ...DocumentsTypes[documentTypeId], optionnel }))) } - Object.keys((TDEDocumentsTypes as TDEDocumentsTypesUnleashed)[titreTypeId]?.[demarcheTypeId]?.[etapeTypeId] ?? {}) + Object.keys((TDEDocumentsTypes as TDEDocumentsTypesUnleashed)[machineInfo.titreTypeId]?.[machineInfo.demarcheTypeId]?.[etapeTypeId] ?? {}) .filter(isDocumentTypeId) .forEach(documentTypeIdSpecifique => { - const documentSpecifique = (TDEDocumentsTypes as TDEDocumentsTypesUnleashed)[titreTypeId]?.[demarcheTypeId]?.[etapeTypeId]?.[documentTypeIdSpecifique] + const documentSpecifique = (TDEDocumentsTypes as TDEDocumentsTypesUnleashed)[machineInfo.titreTypeId]?.[machineInfo.demarcheTypeId]?.[etapeTypeId]?.[documentTypeIdSpecifique] if (isNotNullNorUndefined(documentSpecifique)) { const knownDocumentType = documentTypes.find(({ id }) => id === documentTypeIdSpecifique) @@ -395,9 +384,9 @@ export const getDocuments = ( }) if ( - machineId === 'ProcedureSpecifique' && - titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX && - demarcheTypeId === DEMARCHES_TYPES_IDS.Octroi && + machineInfo.machineId === 'ProcedureSpecifique' && + machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX && + machineInfo.demarcheTypeId === DEMARCHES_TYPES_IDS.Octroi && etapeTypeId === ETAPES_TYPES.demande ) { for (const documentType of documentTypes) { @@ -409,13 +398,13 @@ export const getDocuments = ( // si la démarche est mécanisée il faut ajouter des documents obligatoires if (isArmMecanise === IS_ARM_MECANISE) { for (const documentType of documentTypes) { - if ([DOCUMENTS_TYPES_IDS.dossierLoiSurLEau, machineId !== 'ProcedureSpecifique' ? DOCUMENTS_TYPES_IDS.decisionCasParCas : null].includes(documentType.id)) { + if ([DOCUMENTS_TYPES_IDS.dossierLoiSurLEau, machineInfo.machineId !== 'ProcedureSpecifique' ? DOCUMENTS_TYPES_IDS.decisionCasParCas : null].includes(documentType.id)) { documentType.optionnel = false } } } - const sdomZonesDocumentTypeIds = documentTypeIdsBySdomZonesGet(sdomZoneIds, titreTypeId, demarcheTypeId, etapeTypeId) + const sdomZonesDocumentTypeIds = documentTypeIdsBySdomZonesGet(sdomZoneIds, machineInfo.titreTypeId, machineInfo.demarcheTypeId, etapeTypeId) if (isNotNullNorUndefinedNorEmpty(sdomZonesDocumentTypeIds)) { for (const documentType of documentTypes) { if (sdomZonesDocumentTypeIds.includes(documentType.id)) { @@ -426,7 +415,7 @@ export const getDocuments = ( return [ ...documentTypes.map(d => { - if (isProcedureOuverte(machineId)) { + if (isProcedureOuverte(machineInfo.machineId)) { d.optionnel = true } diff --git a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/entrepriseDocuments.test.ts b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/entrepriseDocuments.test.ts index a4a4d2b3b9445201a3ef70163dea25ab628ffd9c..184e4b6ecc8bbba3445228aeb7bd9f14ab30877e 100644 --- a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/entrepriseDocuments.test.ts +++ b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/entrepriseDocuments.test.ts @@ -1,12 +1,26 @@ import { expect, test } from 'vitest' import { getEntrepriseDocuments } from './entrepriseDocuments' +import { TITRES_TYPES_IDS } from '../titresTypes' +import { DEMARCHES_TYPES_IDS } from '../demarchesTypes' +import { ETAPES_TYPES } from '../etapesTypes' +import { MachineInfo } from '../../machines' +import { demarcheIdValidator } from '../../demarche' +import { firstEtapeDateValidator } from '../../date' +const demarcheId = demarcheIdValidator.parse('demarcheId') +const firstEtapeDate = firstEtapeDateValidator.parse('2020-01-01') test('getEntrepriseDocuments pas de documents', () => { - expect(getEntrepriseDocuments('apm', 'amo', 'wfo')).toMatchInlineSnapshot('[]') + expect( + getEntrepriseDocuments( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_METAUX, DEMARCHES_TYPES_IDS.Amodiation, demarcheId, firstEtapeDate), + ETAPES_TYPES.declarationDouvertureDeTravauxMiniers_DOTM_ + ) + ).toMatchInlineSnapshot('[]') }) test('getEntrepriseDocuments', () => { - expect(getEntrepriseDocuments('arm', 'oct', 'mfr')).toMatchInlineSnapshot(` + expect(getEntrepriseDocuments(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), ETAPES_TYPES.demande)) + .toMatchInlineSnapshot(` [ { "description": undefined, @@ -58,7 +72,8 @@ test('getEntrepriseDocuments', () => { ] `) - expect(getEntrepriseDocuments('prr', 'oct', 'mfr')).toMatchInlineSnapshot(` + expect(getEntrepriseDocuments(MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_RADIOACTIF, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), ETAPES_TYPES.demande)) + .toMatchInlineSnapshot(` [ { "id": "atf", diff --git a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/entrepriseDocuments.ts b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/entrepriseDocuments.ts index 05bfd7a8902b3bcd86f503592f4c970ee561b3c2..30f1d0935ec1eea8b67acd2a6a79455f14860798 100644 --- a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/entrepriseDocuments.ts +++ b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/entrepriseDocuments.ts @@ -1,3 +1,4 @@ +import { MachineInfo } from '../../machines' import { onlyUnique } from '../../typescript-tools' import { DEMARCHES_TYPES_IDS, DemarcheTypeId } from '../demarchesTypes' import { DocumentsTypes, DOCUMENTS_TYPES_IDS, EntrepriseDocumentTypeId, EntrepriseDocumentType, isEntrepriseDocumentTypeId } from '../documentsTypes' @@ -82,17 +83,19 @@ type TDEEntrepriseDocumentsTypesUnleashed = { [key in TitreTypeId]?: { [key in DemarcheTypeId]?: { [key in EtapeTypeId]?: { [key in EntrepriseDocumentTypeId]: { optionnel: boolean; description?: string } } } } } -export const getEntrepriseDocuments = (titreTypeId: TitreTypeId, demarcheTypeId: DemarcheTypeId, etapeTypeId: EtapeTypeId): EntrepriseDocumentType[] => { +export const getEntrepriseDocuments = (machineInfo: MachineInfo, etapeTypeId: EtapeTypeId): EntrepriseDocumentType[] => { const documentsIds: EntrepriseDocumentTypeId[] = [] if (isEtapesTypesEntrepriseDocumentsTypes(etapeTypeId)) { documentsIds.push(...EtapesTypesEntrepriseDocumentsTypes[etapeTypeId]) } - documentsIds.push(...Object.keys((TDEEntrepriseDocumentsTypes as TDEEntrepriseDocumentsTypesUnleashed)[titreTypeId]?.[demarcheTypeId]?.[etapeTypeId] ?? {}).filter(isEntrepriseDocumentTypeId)) + documentsIds.push( + ...Object.keys((TDEEntrepriseDocumentsTypes as TDEEntrepriseDocumentsTypesUnleashed)[machineInfo.titreTypeId]?.[machineInfo.demarcheTypeId]?.[etapeTypeId] ?? {}).filter(isEntrepriseDocumentTypeId) + ) return documentsIds.filter(onlyUnique).map(documentTypeId => { - const documentSpecifique = (TDEEntrepriseDocumentsTypes as TDEEntrepriseDocumentsTypesUnleashed)[titreTypeId]?.[demarcheTypeId]?.[etapeTypeId]?.[documentTypeId] + const documentSpecifique = (TDEEntrepriseDocumentsTypes as TDEEntrepriseDocumentsTypesUnleashed)[machineInfo.titreTypeId]?.[machineInfo.demarcheTypeId]?.[etapeTypeId]?.[documentTypeId] const document = { ...DocumentsTypes[documentTypeId], optionnel: true } if (documentSpecifique) { document.optionnel = documentSpecifique.optionnel diff --git a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.test.ts b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.test.ts index 50ae9e264508208ce42e54e186d6597fdc1e61d4..da2c544865773afd80ac254a4e1eb3af4b2a946a 100644 --- a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.test.ts +++ b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.test.ts @@ -1,3 +1,6 @@ +import { firstEtapeDateValidator } from '../../date' +import { demarcheIdValidator } from '../../demarche' +import { MachineInfo } from '../../machines' import { isNumberElement } from '../../sections' import { DEMARCHES_TYPES_IDS } from '../demarchesTypes' import { ETAPES_TYPES } from '../etapesTypes' @@ -16,19 +19,31 @@ test('isNumberElement', () => { }) ).toBe(true) }) +const demarcheId = demarcheIdValidator.parse('demarcheId') +const firstEtapeDate = firstEtapeDateValidator.parse('2020-01-01') test('getSections erreurs', () => { - expect(() => getSections(undefined, undefined, undefined)).toThrowErrorMatchingInlineSnapshot( - "[Error: il manque des éléments pour trouver les sections titreTypeId: 'undefined', demarcheId: undefined, etapeTypeId: undefined]" - ) + expect(() => + getSections(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), undefined) + ).toThrowErrorMatchingInlineSnapshot(`[Error: il manque des éléments pour trouver les sections titreTypeId: 'arm', demarcheId: oct, etapeTypeId: undefined]`) }) test('getSections pas de surcharge mais pas de sections', () => { - expect(getSections(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_METAUX, DEMARCHES_TYPES_IDS.Amodiation, ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives)).toMatchInlineSnapshot('[]') + expect( + getSections( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_PROSPECTION_METAUX, DEMARCHES_TYPES_IDS.Amodiation, demarcheId, firstEtapeDate), + ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives + ) + ).toMatchInlineSnapshot('[]') }) test('getSections retourne le numéro de RAA pour les publications de décision au RAA', () => { - expect(getSections(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, ETAPES_TYPES.publicationDeDecisionAuRecueilDesActesAdministratifs)).toMatchInlineSnapshot(` + expect( + getSections( + MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), + ETAPES_TYPES.publicationDeDecisionAuRecueilDesActesAdministratifs + ) + ).toMatchInlineSnapshot(` [ { "elements": [ @@ -47,7 +62,8 @@ test('getSections retourne le numéro de RAA pour les publications de décision }) test('getSections surcharge', () => { - expect(getSections(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, ETAPES_TYPES.recepisseDeDeclarationLoiSurLeau)).toMatchInlineSnapshot(` + expect(getSections(MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), ETAPES_TYPES.recepisseDeDeclarationLoiSurLeau)) + .toMatchInlineSnapshot(` [ { "elements": [ diff --git a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.ts b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.ts index 6895ca3cf5ea56107bc9994f770ba584702b5ba9..be9f82938e8c90fe0d5c4c85d34365fcf3094a65 100644 --- a/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.ts +++ b/packages/common/src/static/titresTypes_demarchesTypes_etapesTypes/sections.ts @@ -10,6 +10,7 @@ import { z } from 'zod' import { ElementWithValue, SectionWithValue } from '../../sections' import { Contenu } from '../../permissions/sections' import { FlattenEtape } from '../../etape-form' +import { MachineInfo } from '../../machines' const sectionUnites = Object.values(Unites).map(({ id, nom }) => ({ id, nom })) as NonEmptyArray<{ id: UniteId; nom: string }> const sectionDevises = sortedDevises as NonEmptyArray<{ id: DeviseId; nom: string }> @@ -1016,13 +1017,13 @@ const isEtapesTypesEtapesTypesSections = (etapeTypeId?: EtapeTypeId): etapeTypeI return Object.keys(EtapesTypesSections).includes(etapeTypeId) } -export const getSections = (titreTypeId: TitreTypeId | undefined, demarcheTypeId: DemarcheTypeId | undefined, etapeTypeId: EtapeTypeId | undefined): Section[] => { - if (isNotNullNorUndefined(titreTypeId) && isNotNullNorUndefined(demarcheTypeId) && isNotNullNorUndefined(etapeTypeId)) { +export const getSections = (machineInfo: MachineInfo, etapeTypeId: EtapeTypeId | undefined): Section[] => { + if (isNotNullNorUndefined(machineInfo.titreTypeId) && isNotNullNorUndefined(machineInfo.demarcheTypeId) && isNotNullNorUndefined(etapeTypeId)) { const sections: Section[] = [] type TDESectionsTypesUnleashed = { [key in TitreTypeId]?: { [key in DemarcheTypeId]?: { [key in EtapeTypeId]?: Section[] } } } - sections.push(...((TDESections as TDESectionsTypesUnleashed)[titreTypeId]?.[demarcheTypeId]?.[etapeTypeId] ?? [])) + sections.push(...((TDESections as TDESectionsTypesUnleashed)[machineInfo.titreTypeId]?.[machineInfo.demarcheTypeId]?.[etapeTypeId] ?? [])) if (isEtapesTypesEtapesTypesSections(etapeTypeId)) { EtapesTypesSections[etapeTypeId].forEach(section => { @@ -1034,7 +1035,7 @@ export const getSections = (titreTypeId: TitreTypeId | undefined, demarcheTypeId return sections } else { - throw new Error(`il manque des éléments pour trouver les sections titreTypeId: '${titreTypeId}', demarcheId: ${demarcheTypeId}, etapeTypeId: ${etapeTypeId}`) + throw new Error(`il manque des éléments pour trouver les sections titreTypeId: '${machineInfo.titreTypeId}', demarcheId: ${machineInfo.demarcheTypeId}, etapeTypeId: ${etapeTypeId}`) } } diff --git a/packages/common/src/titres.ts b/packages/common/src/titres.ts index f2ae33c9e68203b799c39859bbc61495164bb91e..a073b30051ededb94605229b28bfa2a7d96085af 100644 --- a/packages/common/src/titres.ts +++ b/packages/common/src/titres.ts @@ -14,6 +14,7 @@ import { EntrepriseId, entrepriseIdValidator } from './entreprise' import { isFondamentalesStatutOk } from './static/etapesStatuts' import { ETAPE_IS_NOT_BROUILLON, etapeIdValidator, etapeSlugValidator } from './etape' import { isEntrepriseOrBureauDEtude, User } from './roles' +import { machineIdValidator } from './validators/machine' const commonTitreValidator = z.object({ id: titreIdValidator, @@ -49,6 +50,7 @@ export const demarcheGetValidator = z.object({ demarche_date_debut: caminoDateValidator.nullable(), demarche_date_fin: caminoDateValidator.nullable(), demarche_visibilite: demarcheVisibiliteValidator, + machine_id: machineIdValidator.nullable(), ordre: z.number(), }) @@ -93,6 +95,7 @@ export const superTitreValidator = z.object({ etape_type_id: etapeTypeIdValidator, etape_slug: etapeSlugValidator, etape_date: caminoDateValidator, + machine_id: machineIdValidator.nullable(), }) export type SuperTitre = z.infer<typeof superTitreValidator> @@ -182,6 +185,7 @@ export const getDemarcheByIdOrSlugValidator = z.object({ demarche_slug: demarcheSlugValidator, demarche_type_id: demarcheTypeIdValidator, demarche_description: z.string().nullable(), + machine_id: machineIdValidator.nullable(), titre_id: titreIdValidator, titre_slug: titreSlugValidator, titre_type_id: titreTypeIdValidator, diff --git a/packages/common/src/validators/machine.ts b/packages/common/src/validators/machine.ts new file mode 100644 index 0000000000000000000000000000000000000000..42df508d1f566044dda2a6b5d72d74bc8253bcf0 --- /dev/null +++ b/packages/common/src/validators/machine.ts @@ -0,0 +1,13 @@ +import { z } from 'zod' +const CAMINO_MACHINES = [ + 'AncienLogigrammeOctroiARM', + 'AncienLogigrammeRenonciationEtProlongationARM', + 'AncienLogigrammeOctroiPRM', + 'AncienLogigrammeOctroiAXM', + 'AncienLogigrammeProlongationAXM', + 'ProcedureSimplifiee', + 'ProcedureSpecifique', +] as const +export const machineIdValidator = z.enum(CAMINO_MACHINES) + +export type CaminoMachineId = (typeof CAMINO_MACHINES)[number] diff --git a/packages/ui/src/components/_common/dsfr-perimetre.stories.tsx b/packages/ui/src/components/_common/dsfr-perimetre.stories.tsx index 642bad974402bf81073aee806bd1e2d32706d806..fe18ee537820500b529ea3fe5bf6b10b765c78e3 100644 --- a/packages/ui/src/components/_common/dsfr-perimetre.stories.tsx +++ b/packages/ui/src/components/_common/dsfr-perimetre.stories.tsx @@ -9,6 +9,10 @@ import { FeatureCollectionForages, FeatureCollectionPoints, FeatureMultiPolygon import { ApiClient } from '@/api/api-client' import { GEO_SYSTEME_IDS } from 'camino-common/src/static/geoSystemes' import { km2Validator } from 'camino-common/src/number' +import { MachineInfo } from 'camino-common/src/machines' +import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' +import { demarcheIdValidator } from 'camino-common/src/demarche' +import { firstEtapeDateValidator } from 'camino-common/src/date' const meta: Meta = { title: 'Components/Common/Perimetre', @@ -54,13 +58,18 @@ const apiClientMock: Pick<ApiClient, 'getTitresWithPerimetreForCarte'> = { return Promise.resolve({ elements: [], total: 0 }) }, } - +const machineInfo = MachineInfo.withDate( + TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX, + DEMARCHES_TYPES_IDS.Octroi, + demarcheIdValidator.parse('demarcheId'), + firstEtapeDateValidator.parse('2020-01-01') +) export const Default: StoryFn = () => ( <> <MapPattern /> <DsfrPerimetre id="test" - titreTypeId="axm" + machineInfo={machineInfo} perimetre={{ geojson4326_perimetre, geojson4326_points: null, @@ -128,7 +137,7 @@ export const NoNeighbors: StoryFn = () => ( <MapPattern /> <DsfrPerimetre id="test" - titreTypeId="axm" + machineInfo={machineInfo} perimetre={{ geojson4326_perimetre, geojson4326_points: null, @@ -174,7 +183,7 @@ export const PolygonWithLacune: StoryFn = () => ( <MapPattern /> <DsfrPerimetre id="test" - titreTypeId="axm" + machineInfo={machineInfo} perimetre={{ geojson4326_perimetre: perimetreWithLacune, geojson4326_points: null, @@ -217,7 +226,7 @@ export const Big: StoryFn = () => ( <MapPattern /> <DsfrPerimetre id="test" - titreTypeId="axm" + machineInfo={machineInfo} perimetre={{ geojson4326_perimetre: bigGeoJson, geojson4326_points: null, @@ -284,7 +293,7 @@ export const Multiple: StoryFn = () => ( <MapPattern /> <DsfrPerimetre id="test" - titreTypeId="axm" + machineInfo={machineInfo} perimetre={{ geojson4326_perimetre: multiplePolygone, geojson_origine_perimetre: multiplePolygone, @@ -373,7 +382,7 @@ export const MultiplePolygonWithLacuneTableau: StoryFn = () => ( <MapPattern /> <DsfrPerimetre id="test" - titreTypeId="axm" + machineInfo={machineInfo} perimetre={{ geojson4326_perimetre: multiplePolygoneWithLacune, geojson4326_points: null, @@ -411,7 +420,7 @@ export const CustomPoints: StoryFn = () => ( <MapPattern /> <DsfrPerimetre id="test" - titreTypeId="axm" + machineInfo={machineInfo} perimetre={{ geojson4326_perimetre, geojson4326_points: customPoints, @@ -439,7 +448,7 @@ export const CustomPointsWithoutNameAndDesc: StoryFn = () => ( <MapPattern /> <DsfrPerimetre id="test" - titreTypeId="axm" + machineInfo={machineInfo} perimetre={{ geojson4326_perimetre, geojson4326_points: customPointWithoutNameAndDesc, @@ -462,7 +471,7 @@ export const CustomPointsWithAnotherGeoSysteme: StoryFn = () => ( <MapPattern /> <DsfrPerimetre id="test" - titreTypeId="axm" + machineInfo={machineInfo} perimetre={{ geojson4326_perimetre, geojson4326_points: customPointWithoutNameAndDesc, @@ -489,7 +498,7 @@ export const CustomPointsWithAnotherLegacyGeoSysteme: StoryFn = () => ( <MapPattern /> <DsfrPerimetre id="test" - titreTypeId="axm" + machineInfo={machineInfo} perimetre={{ geojson4326_perimetre, geojson4326_points: customPointWithoutNameAndDesc, @@ -514,7 +523,7 @@ export const CustomPointsWithAnotherLegacyGeoSysteme: StoryFn = () => ( export const WithForages: StoryFn = () => ( <DsfrPerimetre id="test" - titreTypeId="pxm" + machineInfo={MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2020-01-01'))} perimetre={{ geojson4326_perimetre, geojson4326_points: customPointWithoutNameAndDesc, diff --git a/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Big.html b/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Big.html index dd1755f3d13543df15fd3c1398346159ae1d251f..7d84c157ae8185ad8998ea40ba301d8e4ec28118 100644 --- a/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Big.html +++ b/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Big.html @@ -305,10 +305,10 @@ </ul> <div id="tabpanel-carte-test-panel" class="fr-tabs__panel fr-tabs__panel--selected" role="tabpanel" aria-labelledby="tabpanel-carte-test" tabindex="0"> <div style="display: flex; flex-direction: column;"> - <mocked-map perimetre="[object Object]" id="test" titretypeid="axm" style="min-height: 400px;" class="fr-mb-1w" maxmarkers="20" neighbours="[object Object]"> + <mocked-map perimetre="[object Object]" id="test" machineinfo="[object Object]" style="min-height: 400px;" class="fr-mb-1w" maxmarkers="20" neighbours="[object Object]"> <perimetre>{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-4.370364497124209,48.53380508608616],[-4.373271574712479,48.47151134163559],[-4.03753485335386,48.579164636474836],[-3.89919702975027,48.603980178934115],[-3.860482328708233,48.62511389817695],[-3.858436311611334,48.629031691751045],[-3.862157259991486,48.633014015139416],[-3.870281882041237,48.63550010399696],[-3.879786359001045,48.639113643702565],[-3.895430188480503,48.64455770816115],[-3.89902273351368,48.64822789311303],[-3.902536979616769,48.654435032933826],[-3.906528075174153,48.66061643462235],[-3.904489574558275,48.6643307169305],[-3.89647573803132,48.66601900245078],[-3.890673665115296,48.667020244464325],[-3.890721315690864,48.67062455977177],[-3.892950905315848,48.67088770685571],[-3.898005277721187,48.6723935639094],[-3.8992413951649,48.67074624589731],[-3.903300809713803,48.67034264689684],[-3.907548440632195,48.66910635173531],[-3.91185396569359,48.669954398127075],[-3.914635548862354,48.67322568941628],[-3.920575104032537,48.67458696237509],[-3.924157593611878,48.669749821082725],[-3.927138109422188,48.66538094626539],[-3.927802453245391,48.66178827244388],[-3.92880004801291,48.660065331624466],[-3.930674658925236,48.657424523021],[-3.934385020441046,48.65730036039394],[-3.940574301992641,48.65682750256307],[-3.949892212356874,48.653210569309856],[-3.9518951695476,48.64983646195122],[-3.95135848409069,48.646306571150944],[-3.952791103114349,48.64456097348628],[-3.954311041643234,48.64535110107629],[-3.957178207067545,48.65093506946735],[-3.95632686509049,48.654756209794456],[-3.954939197043658,48.66049485799891],[-3.958264581105623,48.66351217516115],[-3.954301077151103,48.665175330569724],[-3.958113788215813,48.66678821578858],[-3.958288500972019,48.67004622329816],[-3.953583216471425,48.67102223996598],[-3.952154912225681,48.67280542236],[-3.954601922703807,48.67354649576719],[-3.957150323952388,48.6728667311387],[-3.962232217223142,48.674085603023535],[-3.96509885038279,48.67647290565392],[-3.968196892552599,48.67354977814375],[-3.970552500285286,48.67336152037275],[-3.971907150463719,48.67429537178488],[-3.971687730880199,48.67565139942766],[-3.968925351937541,48.67998621214178],[-3.97276835094199,48.68681279071675],[-3.969905040239144,48.687617856017994],[-3.967785856011854,48.69274164929216],[-3.97050395358365,48.693904041872074],[-3.974129066864182,48.69665141578885],[-3.976827175680581,48.699084231748806],[-3.973964059500176,48.70207052891004],[-3.97557715354335,48.70449012698265],[-3.972337757698344,48.70582333762662],[-3.974038535718974,48.710344199247295],[-3.972061362590358,48.71168433267898],[-3.969407494937729,48.71919463600953],[-3.966114995158957,48.719188628020184],[-3.964815895310649,48.72248973384656],[-3.968123622922862,48.72216808659624],[-3.970117554054281,48.7239825094888],[-3.971030085004171,48.72531725688056],[-3.974105493634571,48.72442714535237],[-3.977130032296356,48.72223266964199],[-3.98038470744471,48.72282149601802],[-3.98267568678471,48.72451484026706],[-3.983159793997456,48.72623219482621],[-3.985655519886893,48.726898196761965],[-3.988412331317411,48.727004809776105],[-3.990251104366354,48.72588975599552],[-3.992106999472123,48.723541171653366],[-3.992308257471176,48.72204072794657],[-3.990818477440011,48.71838055340067],[-3.993241558794496,48.715311146944074],[-3.99726181945054,48.71273584775902],[-4.000886986292233,48.71141716999743],[-4.005573266114372,48.715195490443925],[-4.004640753163968,48.716989015759715],[-4.007861713401779,48.72044675798358],[-4.009590286562232,48.72068101995395],[-4.012907971574204,48.71865165832863],[-4.010881803078078,48.716872551149415],[-4.013298574720932,48.713765123429766],[-4.018283788022766,48.71146515516518],[-4.02502266800395,48.710486602386844],[-4.029102910364339,48.7109751516783],[-4.032895375568785,48.712496949149184],[-4.034013864663466,48.71364906002572],[-4.035203599079426,48.71386049099469],[-4.036426674181452,48.711761570746404],[-4.035857818689737,48.70935978588029],[-4.037836186006247,48.70536884991981],[-4.040876440962449,48.70331706201061],[-4.042661395770205,48.70267658451317],[-4.044522857875245,48.70264835316387],[-4.048746772595955,48.70536952092104],[-4.051782617787177,48.70458102418029],[-4.053387641319855,48.70237110662314],[-4.054960885021424,48.69887510664347],[-4.057098904957046,48.688336149296134],[-4.047492224129947,48.6881905546806],[-4.04264615919883,48.688356681641565],[-4.05570877851515,48.685187990084636],[-4.061384711067841,48.687678086132514],[-4.063856568443375,48.68626486757381],[-4.069006699782528,48.687977416990556],[-4.066114156101222,48.68600063748565],[-4.065917761777147,48.68383188367652],[-4.06536435070835,48.68281963355705],[-4.062811851052143,48.68243638561189],[-4.063604286352126,48.680735563101265],[-4.061249339782617,48.68019915458731],[-4.060491984152113,48.67893668983929],[-4.056630622211962,48.67523642323898],[-4.055350396131191,48.67179995101334],[-4.057224936686009,48.670572879663034],[-4.057969445321888,48.675068847630506],[-4.059622862128396,48.675122344607715],[-4.06024682153259,48.67613145254186],[-4.063213863275964,48.67815002912692],[-4.064507934140134,48.677605925445725],[-4.067195178609656,48.67891661518815],[-4.068000601946539,48.68272446881325],[-4.07116708376152,48.68462241191764],[-4.080222240659125,48.689712089777736],[-4.082890717412141,48.693212237422216],[-4.0837341887691,48.69168549285934],[-4.08645810312384,48.69005696722575],[-4.08922980276701,48.69161527586137],[-4.091651149022687,48.69171173600047],[-4.095188717132302,48.686965610139666],[-4.097383839952319,48.69356464812578],[-4.102536986221444,48.69351221259058],[-4.106197887484285,48.692515838515405],[-4.109568285925066,48.69472448012849],[-4.115803404112282,48.69506791354793],[-4.118098969264236,48.692778728280935],[-4.12511664716867,48.693877169595176],[-4.127837461875522,48.69361476668908],[-4.131236501370729,48.6960475956426],[-4.136181126707938,48.69293107079426],[-4.142132619722753,48.69237814384752],[-4.150020162763907,48.69217377284019],[-4.152170300893284,48.691487051119246],[-4.162483098525137,48.68833023827453],[-4.174170898732186,48.657628672506775],[-4.409843663429304,48.633874515395604],[-4.370364497124209,48.53380508608616]]]]}},"geojson4326_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.370364497124209,48.53380508608616]},"properties":{"nom":"A","description":"Polygone 1","latitude":"48.53380508608616","longitude":"-4.370364497124209"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.373271574712479,48.47151134163559]},"properties":{"nom":"B","description":"Polygone 1","latitude":"48.47151134163559","longitude":"-4.373271574712479"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.03753485335386,48.579164636474836]},"properties":{"nom":"C","description":"Polygone 1","latitude":"48.579164636474836","longitude":"-4.03753485335386"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.89919702975027,48.603980178934115]},"properties":{"nom":"D","description":"Polygone 1","latitude":"48.603980178934115","longitude":"-3.89919702975027"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.860482328708233,48.62511389817695]},"properties":{"nom":"E","description":"Polygone 1","latitude":"48.62511389817695","longitude":"-3.860482328708233"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.858436311611334,48.629031691751045]},"properties":{"nom":"F","description":"Polygone 1","latitude":"48.629031691751045","longitude":"-3.858436311611334"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.862157259991486,48.633014015139416]},"properties":{"nom":"G","description":"Polygone 1","latitude":"48.633014015139416","longitude":"-3.862157259991486"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.870281882041237,48.63550010399696]},"properties":{"nom":"H","description":"Polygone 1","latitude":"48.63550010399696","longitude":"-3.870281882041237"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.879786359001045,48.639113643702565]},"properties":{"nom":"I","description":"Polygone 1","latitude":"48.639113643702565","longitude":"-3.879786359001045"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.895430188480503,48.64455770816115]},"properties":{"nom":"J","description":"Polygone 1","latitude":"48.64455770816115","longitude":"-3.895430188480503"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.89902273351368,48.64822789311303]},"properties":{"nom":"K","description":"Polygone 1","latitude":"48.64822789311303","longitude":"-3.89902273351368"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.902536979616769,48.654435032933826]},"properties":{"nom":"L","description":"Polygone 1","latitude":"48.654435032933826","longitude":"-3.902536979616769"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.906528075174153,48.66061643462235]},"properties":{"nom":"M","description":"Polygone 1","latitude":"48.66061643462235","longitude":"-3.906528075174153"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.904489574558275,48.6643307169305]},"properties":{"nom":"N","description":"Polygone 1","latitude":"48.6643307169305","longitude":"-3.904489574558275"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.89647573803132,48.66601900245078]},"properties":{"nom":"O","description":"Polygone 1","latitude":"48.66601900245078","longitude":"-3.89647573803132"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.890673665115296,48.667020244464325]},"properties":{"nom":"P","description":"Polygone 1","latitude":"48.667020244464325","longitude":"-3.890673665115296"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.890721315690864,48.67062455977177]},"properties":{"nom":"Q","description":"Polygone 1","latitude":"48.67062455977177","longitude":"-3.890721315690864"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.892950905315848,48.67088770685571]},"properties":{"nom":"R","description":"Polygone 1","latitude":"48.67088770685571","longitude":"-3.892950905315848"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.898005277721187,48.6723935639094]},"properties":{"nom":"S","description":"Polygone 1","latitude":"48.6723935639094","longitude":"-3.898005277721187"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.8992413951649,48.67074624589731]},"properties":{"nom":"T","description":"Polygone 1","latitude":"48.67074624589731","longitude":"-3.8992413951649"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.903300809713803,48.67034264689684]},"properties":{"nom":"U","description":"Polygone 1","latitude":"48.67034264689684","longitude":"-3.903300809713803"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.907548440632195,48.66910635173531]},"properties":{"nom":"V","description":"Polygone 1","latitude":"48.66910635173531","longitude":"-3.907548440632195"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.91185396569359,48.669954398127075]},"properties":{"nom":"W","description":"Polygone 1","latitude":"48.669954398127075","longitude":"-3.91185396569359"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.914635548862354,48.67322568941628]},"properties":{"nom":"X","description":"Polygone 1","latitude":"48.67322568941628","longitude":"-3.914635548862354"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.920575104032537,48.67458696237509]},"properties":{"nom":"Y","description":"Polygone 1","latitude":"48.67458696237509","longitude":"-3.920575104032537"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.924157593611878,48.669749821082725]},"properties":{"nom":"Z","description":"Polygone 1","latitude":"48.669749821082725","longitude":"-3.924157593611878"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.927138109422188,48.66538094626539]},"properties":{"nom":"AA","description":"Polygone 1","latitude":"48.66538094626539","longitude":"-3.927138109422188"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.927802453245391,48.66178827244388]},"properties":{"nom":"AB","description":"Polygone 1","latitude":"48.66178827244388","longitude":"-3.927802453245391"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.92880004801291,48.660065331624466]},"properties":{"nom":"AC","description":"Polygone 1","latitude":"48.660065331624466","longitude":"-3.92880004801291"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.930674658925236,48.657424523021]},"properties":{"nom":"AD","description":"Polygone 1","latitude":"48.657424523021","longitude":"-3.930674658925236"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.934385020441046,48.65730036039394]},"properties":{"nom":"AE","description":"Polygone 1","latitude":"48.65730036039394","longitude":"-3.934385020441046"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.940574301992641,48.65682750256307]},"properties":{"nom":"AF","description":"Polygone 1","latitude":"48.65682750256307","longitude":"-3.940574301992641"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.949892212356874,48.653210569309856]},"properties":{"nom":"AG","description":"Polygone 1","latitude":"48.653210569309856","longitude":"-3.949892212356874"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.9518951695476,48.64983646195122]},"properties":{"nom":"AH","description":"Polygone 1","latitude":"48.64983646195122","longitude":"-3.9518951695476"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.95135848409069,48.646306571150944]},"properties":{"nom":"AI","description":"Polygone 1","latitude":"48.646306571150944","longitude":"-3.95135848409069"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.952791103114349,48.64456097348628]},"properties":{"nom":"AJ","description":"Polygone 1","latitude":"48.64456097348628","longitude":"-3.952791103114349"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.954311041643234,48.64535110107629]},"properties":{"nom":"AK","description":"Polygone 1","latitude":"48.64535110107629","longitude":"-3.954311041643234"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.957178207067545,48.65093506946735]},"properties":{"nom":"AL","description":"Polygone 1","latitude":"48.65093506946735","longitude":"-3.957178207067545"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.95632686509049,48.654756209794456]},"properties":{"nom":"AM","description":"Polygone 1","latitude":"48.654756209794456","longitude":"-3.95632686509049"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.954939197043658,48.66049485799891]},"properties":{"nom":"AN","description":"Polygone 1","latitude":"48.66049485799891","longitude":"-3.954939197043658"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.958264581105623,48.66351217516115]},"properties":{"nom":"AO","description":"Polygone 1","latitude":"48.66351217516115","longitude":"-3.958264581105623"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.954301077151103,48.665175330569724]},"properties":{"nom":"AP","description":"Polygone 1","latitude":"48.665175330569724","longitude":"-3.954301077151103"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.958113788215813,48.66678821578858]},"properties":{"nom":"AQ","description":"Polygone 1","latitude":"48.66678821578858","longitude":"-3.958113788215813"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.958288500972019,48.67004622329816]},"properties":{"nom":"AR","description":"Polygone 1","latitude":"48.67004622329816","longitude":"-3.958288500972019"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.953583216471425,48.67102223996598]},"properties":{"nom":"AS","description":"Polygone 1","latitude":"48.67102223996598","longitude":"-3.953583216471425"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.952154912225681,48.67280542236]},"properties":{"nom":"AT","description":"Polygone 1","latitude":"48.67280542236","longitude":"-3.952154912225681"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.954601922703807,48.67354649576719]},"properties":{"nom":"AU","description":"Polygone 1","latitude":"48.67354649576719","longitude":"-3.954601922703807"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.957150323952388,48.6728667311387]},"properties":{"nom":"AV","description":"Polygone 1","latitude":"48.6728667311387","longitude":"-3.957150323952388"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.962232217223142,48.674085603023535]},"properties":{"nom":"AW","description":"Polygone 1","latitude":"48.674085603023535","longitude":"-3.962232217223142"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.96509885038279,48.67647290565392]},"properties":{"nom":"AX","description":"Polygone 1","latitude":"48.67647290565392","longitude":"-3.96509885038279"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.968196892552599,48.67354977814375]},"properties":{"nom":"AY","description":"Polygone 1","latitude":"48.67354977814375","longitude":"-3.968196892552599"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.970552500285286,48.67336152037275]},"properties":{"nom":"AZ","description":"Polygone 1","latitude":"48.67336152037275","longitude":"-3.970552500285286"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.971907150463719,48.67429537178488]},"properties":{"nom":"BA","description":"Polygone 1","latitude":"48.67429537178488","longitude":"-3.971907150463719"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.971687730880199,48.67565139942766]},"properties":{"nom":"BB","description":"Polygone 1","latitude":"48.67565139942766","longitude":"-3.971687730880199"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.968925351937541,48.67998621214178]},"properties":{"nom":"BC","description":"Polygone 1","latitude":"48.67998621214178","longitude":"-3.968925351937541"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.97276835094199,48.68681279071675]},"properties":{"nom":"BD","description":"Polygone 1","latitude":"48.68681279071675","longitude":"-3.97276835094199"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.969905040239144,48.687617856017994]},"properties":{"nom":"BE","description":"Polygone 1","latitude":"48.687617856017994","longitude":"-3.969905040239144"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.967785856011854,48.69274164929216]},"properties":{"nom":"BF","description":"Polygone 1","latitude":"48.69274164929216","longitude":"-3.967785856011854"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.97050395358365,48.693904041872074]},"properties":{"nom":"BG","description":"Polygone 1","latitude":"48.693904041872074","longitude":"-3.97050395358365"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.974129066864182,48.69665141578885]},"properties":{"nom":"BH","description":"Polygone 1","latitude":"48.69665141578885","longitude":"-3.974129066864182"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.976827175680581,48.699084231748806]},"properties":{"nom":"BI","description":"Polygone 1","latitude":"48.699084231748806","longitude":"-3.976827175680581"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.973964059500176,48.70207052891004]},"properties":{"nom":"BJ","description":"Polygone 1","latitude":"48.70207052891004","longitude":"-3.973964059500176"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.97557715354335,48.70449012698265]},"properties":{"nom":"BK","description":"Polygone 1","latitude":"48.70449012698265","longitude":"-3.97557715354335"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.972337757698344,48.70582333762662]},"properties":{"nom":"BL","description":"Polygone 1","latitude":"48.70582333762662","longitude":"-3.972337757698344"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.974038535718974,48.710344199247295]},"properties":{"nom":"BM","description":"Polygone 1","latitude":"48.710344199247295","longitude":"-3.974038535718974"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.972061362590358,48.71168433267898]},"properties":{"nom":"BN","description":"Polygone 1","latitude":"48.71168433267898","longitude":"-3.972061362590358"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.969407494937729,48.71919463600953]},"properties":{"nom":"BO","description":"Polygone 1","latitude":"48.71919463600953","longitude":"-3.969407494937729"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.966114995158957,48.719188628020184]},"properties":{"nom":"BP","description":"Polygone 1","latitude":"48.719188628020184","longitude":"-3.966114995158957"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.964815895310649,48.72248973384656]},"properties":{"nom":"BQ","description":"Polygone 1","latitude":"48.72248973384656","longitude":"-3.964815895310649"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.968123622922862,48.72216808659624]},"properties":{"nom":"BR","description":"Polygone 1","latitude":"48.72216808659624","longitude":"-3.968123622922862"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.970117554054281,48.7239825094888]},"properties":{"nom":"BS","description":"Polygone 1","latitude":"48.7239825094888","longitude":"-3.970117554054281"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.971030085004171,48.72531725688056]},"properties":{"nom":"BT","description":"Polygone 1","latitude":"48.72531725688056","longitude":"-3.971030085004171"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.974105493634571,48.72442714535237]},"properties":{"nom":"BU","description":"Polygone 1","latitude":"48.72442714535237","longitude":"-3.974105493634571"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.977130032296356,48.72223266964199]},"properties":{"nom":"BV","description":"Polygone 1","latitude":"48.72223266964199","longitude":"-3.977130032296356"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.98038470744471,48.72282149601802]},"properties":{"nom":"BW","description":"Polygone 1","latitude":"48.72282149601802","longitude":"-3.98038470744471"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.98267568678471,48.72451484026706]},"properties":{"nom":"BX","description":"Polygone 1","latitude":"48.72451484026706","longitude":"-3.98267568678471"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.983159793997456,48.72623219482621]},"properties":{"nom":"BY","description":"Polygone 1","latitude":"48.72623219482621","longitude":"-3.983159793997456"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.985655519886893,48.726898196761965]},"properties":{"nom":"BZ","description":"Polygone 1","latitude":"48.726898196761965","longitude":"-3.985655519886893"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.988412331317411,48.727004809776105]},"properties":{"nom":"CA","description":"Polygone 1","latitude":"48.727004809776105","longitude":"-3.988412331317411"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.990251104366354,48.72588975599552]},"properties":{"nom":"CB","description":"Polygone 1","latitude":"48.72588975599552","longitude":"-3.990251104366354"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.992106999472123,48.723541171653366]},"properties":{"nom":"CC","description":"Polygone 1","latitude":"48.723541171653366","longitude":"-3.992106999472123"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.992308257471176,48.72204072794657]},"properties":{"nom":"CD","description":"Polygone 1","latitude":"48.72204072794657","longitude":"-3.992308257471176"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.990818477440011,48.71838055340067]},"properties":{"nom":"CE","description":"Polygone 1","latitude":"48.71838055340067","longitude":"-3.990818477440011"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.993241558794496,48.715311146944074]},"properties":{"nom":"CF","description":"Polygone 1","latitude":"48.715311146944074","longitude":"-3.993241558794496"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.99726181945054,48.71273584775902]},"properties":{"nom":"CG","description":"Polygone 1","latitude":"48.71273584775902","longitude":"-3.99726181945054"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.000886986292233,48.71141716999743]},"properties":{"nom":"CH","description":"Polygone 1","latitude":"48.71141716999743","longitude":"-4.000886986292233"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.005573266114372,48.715195490443925]},"properties":{"nom":"CI","description":"Polygone 1","latitude":"48.715195490443925","longitude":"-4.005573266114372"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.004640753163968,48.716989015759715]},"properties":{"nom":"CJ","description":"Polygone 1","latitude":"48.716989015759715","longitude":"-4.004640753163968"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.007861713401779,48.72044675798358]},"properties":{"nom":"CK","description":"Polygone 1","latitude":"48.72044675798358","longitude":"-4.007861713401779"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.009590286562232,48.72068101995395]},"properties":{"nom":"CL","description":"Polygone 1","latitude":"48.72068101995395","longitude":"-4.009590286562232"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.012907971574204,48.71865165832863]},"properties":{"nom":"CM","description":"Polygone 1","latitude":"48.71865165832863","longitude":"-4.012907971574204"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.010881803078078,48.716872551149415]},"properties":{"nom":"CN","description":"Polygone 1","latitude":"48.716872551149415","longitude":"-4.010881803078078"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.013298574720932,48.713765123429766]},"properties":{"nom":"CO","description":"Polygone 1","latitude":"48.713765123429766","longitude":"-4.013298574720932"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.018283788022766,48.71146515516518]},"properties":{"nom":"CP","description":"Polygone 1","latitude":"48.71146515516518","longitude":"-4.018283788022766"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.02502266800395,48.710486602386844]},"properties":{"nom":"CQ","description":"Polygone 1","latitude":"48.710486602386844","longitude":"-4.02502266800395"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.029102910364339,48.7109751516783]},"properties":{"nom":"CR","description":"Polygone 1","latitude":"48.7109751516783","longitude":"-4.029102910364339"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.032895375568785,48.712496949149184]},"properties":{"nom":"CS","description":"Polygone 1","latitude":"48.712496949149184","longitude":"-4.032895375568785"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.034013864663466,48.71364906002572]},"properties":{"nom":"CT","description":"Polygone 1","latitude":"48.71364906002572","longitude":"-4.034013864663466"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.035203599079426,48.71386049099469]},"properties":{"nom":"CU","description":"Polygone 1","latitude":"48.71386049099469","longitude":"-4.035203599079426"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.036426674181452,48.711761570746404]},"properties":{"nom":"CV","description":"Polygone 1","latitude":"48.711761570746404","longitude":"-4.036426674181452"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.035857818689737,48.70935978588029]},"properties":{"nom":"CW","description":"Polygone 1","latitude":"48.70935978588029","longitude":"-4.035857818689737"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.037836186006247,48.70536884991981]},"properties":{"nom":"CX","description":"Polygone 1","latitude":"48.70536884991981","longitude":"-4.037836186006247"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.040876440962449,48.70331706201061]},"properties":{"nom":"CY","description":"Polygone 1","latitude":"48.70331706201061","longitude":"-4.040876440962449"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.042661395770205,48.70267658451317]},"properties":{"nom":"CZ","description":"Polygone 1","latitude":"48.70267658451317","longitude":"-4.042661395770205"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.044522857875245,48.70264835316387]},"properties":{"nom":"DA","description":"Polygone 1","latitude":"48.70264835316387","longitude":"-4.044522857875245"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.048746772595955,48.70536952092104]},"properties":{"nom":"DB","description":"Polygone 1","latitude":"48.70536952092104","longitude":"-4.048746772595955"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.051782617787177,48.70458102418029]},"properties":{"nom":"DC","description":"Polygone 1","latitude":"48.70458102418029","longitude":"-4.051782617787177"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.053387641319855,48.70237110662314]},"properties":{"nom":"DD","description":"Polygone 1","latitude":"48.70237110662314","longitude":"-4.053387641319855"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.054960885021424,48.69887510664347]},"properties":{"nom":"DE","description":"Polygone 1","latitude":"48.69887510664347","longitude":"-4.054960885021424"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.057098904957046,48.688336149296134]},"properties":{"nom":"DF","description":"Polygone 1","latitude":"48.688336149296134","longitude":"-4.057098904957046"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.047492224129947,48.6881905546806]},"properties":{"nom":"DG","description":"Polygone 1","latitude":"48.6881905546806","longitude":"-4.047492224129947"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.04264615919883,48.688356681641565]},"properties":{"nom":"DH","description":"Polygone 1","latitude":"48.688356681641565","longitude":"-4.04264615919883"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.05570877851515,48.685187990084636]},"properties":{"nom":"DI","description":"Polygone 1","latitude":"48.685187990084636","longitude":"-4.05570877851515"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.061384711067841,48.687678086132514]},"properties":{"nom":"DJ","description":"Polygone 1","latitude":"48.687678086132514","longitude":"-4.061384711067841"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.063856568443375,48.68626486757381]},"properties":{"nom":"DK","description":"Polygone 1","latitude":"48.68626486757381","longitude":"-4.063856568443375"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.069006699782528,48.687977416990556]},"properties":{"nom":"DL","description":"Polygone 1","latitude":"48.687977416990556","longitude":"-4.069006699782528"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.066114156101222,48.68600063748565]},"properties":{"nom":"DM","description":"Polygone 1","latitude":"48.68600063748565","longitude":"-4.066114156101222"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.065917761777147,48.68383188367652]},"properties":{"nom":"DN","description":"Polygone 1","latitude":"48.68383188367652","longitude":"-4.065917761777147"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.06536435070835,48.68281963355705]},"properties":{"nom":"DO","description":"Polygone 1","latitude":"48.68281963355705","longitude":"-4.06536435070835"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.062811851052143,48.68243638561189]},"properties":{"nom":"DP","description":"Polygone 1","latitude":"48.68243638561189","longitude":"-4.062811851052143"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.063604286352126,48.680735563101265]},"properties":{"nom":"DQ","description":"Polygone 1","latitude":"48.680735563101265","longitude":"-4.063604286352126"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.061249339782617,48.68019915458731]},"properties":{"nom":"DR","description":"Polygone 1","latitude":"48.68019915458731","longitude":"-4.061249339782617"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.060491984152113,48.67893668983929]},"properties":{"nom":"DS","description":"Polygone 1","latitude":"48.67893668983929","longitude":"-4.060491984152113"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.056630622211962,48.67523642323898]},"properties":{"nom":"DT","description":"Polygone 1","latitude":"48.67523642323898","longitude":"-4.056630622211962"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.055350396131191,48.67179995101334]},"properties":{"nom":"DU","description":"Polygone 1","latitude":"48.67179995101334","longitude":"-4.055350396131191"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.057224936686009,48.670572879663034]},"properties":{"nom":"DV","description":"Polygone 1","latitude":"48.670572879663034","longitude":"-4.057224936686009"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.057969445321888,48.675068847630506]},"properties":{"nom":"DW","description":"Polygone 1","latitude":"48.675068847630506","longitude":"-4.057969445321888"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.059622862128396,48.675122344607715]},"properties":{"nom":"DX","description":"Polygone 1","latitude":"48.675122344607715","longitude":"-4.059622862128396"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.06024682153259,48.67613145254186]},"properties":{"nom":"DY","description":"Polygone 1","latitude":"48.67613145254186","longitude":"-4.06024682153259"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.063213863275964,48.67815002912692]},"properties":{"nom":"DZ","description":"Polygone 1","latitude":"48.67815002912692","longitude":"-4.063213863275964"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.064507934140134,48.677605925445725]},"properties":{"nom":"EA","description":"Polygone 1","latitude":"48.677605925445725","longitude":"-4.064507934140134"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.067195178609656,48.67891661518815]},"properties":{"nom":"EB","description":"Polygone 1","latitude":"48.67891661518815","longitude":"-4.067195178609656"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.068000601946539,48.68272446881325]},"properties":{"nom":"EC","description":"Polygone 1","latitude":"48.68272446881325","longitude":"-4.068000601946539"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.07116708376152,48.68462241191764]},"properties":{"nom":"ED","description":"Polygone 1","latitude":"48.68462241191764","longitude":"-4.07116708376152"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.080222240659125,48.689712089777736]},"properties":{"nom":"EE","description":"Polygone 1","latitude":"48.689712089777736","longitude":"-4.080222240659125"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.082890717412141,48.693212237422216]},"properties":{"nom":"EF","description":"Polygone 1","latitude":"48.693212237422216","longitude":"-4.082890717412141"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.0837341887691,48.69168549285934]},"properties":{"nom":"EG","description":"Polygone 1","latitude":"48.69168549285934","longitude":"-4.0837341887691"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.08645810312384,48.69005696722575]},"properties":{"nom":"EH","description":"Polygone 1","latitude":"48.69005696722575","longitude":"-4.08645810312384"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.08922980276701,48.69161527586137]},"properties":{"nom":"EI","description":"Polygone 1","latitude":"48.69161527586137","longitude":"-4.08922980276701"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.091651149022687,48.69171173600047]},"properties":{"nom":"EJ","description":"Polygone 1","latitude":"48.69171173600047","longitude":"-4.091651149022687"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.095188717132302,48.686965610139666]},"properties":{"nom":"EK","description":"Polygone 1","latitude":"48.686965610139666","longitude":"-4.095188717132302"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.097383839952319,48.69356464812578]},"properties":{"nom":"EL","description":"Polygone 1","latitude":"48.69356464812578","longitude":"-4.097383839952319"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.102536986221444,48.69351221259058]},"properties":{"nom":"EM","description":"Polygone 1","latitude":"48.69351221259058","longitude":"-4.102536986221444"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.106197887484285,48.692515838515405]},"properties":{"nom":"EN","description":"Polygone 1","latitude":"48.692515838515405","longitude":"-4.106197887484285"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.109568285925066,48.69472448012849]},"properties":{"nom":"EO","description":"Polygone 1","latitude":"48.69472448012849","longitude":"-4.109568285925066"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.115803404112282,48.69506791354793]},"properties":{"nom":"EP","description":"Polygone 1","latitude":"48.69506791354793","longitude":"-4.115803404112282"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.118098969264236,48.692778728280935]},"properties":{"nom":"EQ","description":"Polygone 1","latitude":"48.692778728280935","longitude":"-4.118098969264236"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.12511664716867,48.693877169595176]},"properties":{"nom":"ER","description":"Polygone 1","latitude":"48.693877169595176","longitude":"-4.12511664716867"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.127837461875522,48.69361476668908]},"properties":{"nom":"ES","description":"Polygone 1","latitude":"48.69361476668908","longitude":"-4.127837461875522"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.131236501370729,48.6960475956426]},"properties":{"nom":"ET","description":"Polygone 1","latitude":"48.6960475956426","longitude":"-4.131236501370729"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.136181126707938,48.69293107079426]},"properties":{"nom":"EU","description":"Polygone 1","latitude":"48.69293107079426","longitude":"-4.136181126707938"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.142132619722753,48.69237814384752]},"properties":{"nom":"EV","description":"Polygone 1","latitude":"48.69237814384752","longitude":"-4.142132619722753"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.150020162763907,48.69217377284019]},"properties":{"nom":"EW","description":"Polygone 1","latitude":"48.69217377284019","longitude":"-4.150020162763907"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.152170300893284,48.691487051119246]},"properties":{"nom":"EX","description":"Polygone 1","latitude":"48.691487051119246","longitude":"-4.152170300893284"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.162483098525137,48.68833023827453]},"properties":{"nom":"EY","description":"Polygone 1","latitude":"48.68833023827453","longitude":"-4.162483098525137"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.174170898732186,48.657628672506775]},"properties":{"nom":"EZ","description":"Polygone 1","latitude":"48.657628672506775","longitude":"-4.174170898732186"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.409843663429304,48.633874515395604]},"properties":{"nom":"FA","description":"Polygone 1","latitude":"48.633874515395604","longitude":"-4.409843663429304"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-4.370364497124209,48.53380508608616],[-4.373271574712479,48.47151134163559],[-4.03753485335386,48.579164636474836],[-3.89919702975027,48.603980178934115],[-3.860482328708233,48.62511389817695],[-3.858436311611334,48.629031691751045],[-3.862157259991486,48.633014015139416],[-3.870281882041237,48.63550010399696],[-3.879786359001045,48.639113643702565],[-3.895430188480503,48.64455770816115],[-3.89902273351368,48.64822789311303],[-3.902536979616769,48.654435032933826],[-3.906528075174153,48.66061643462235],[-3.904489574558275,48.6643307169305],[-3.89647573803132,48.66601900245078],[-3.890673665115296,48.667020244464325],[-3.890721315690864,48.67062455977177],[-3.892950905315848,48.67088770685571],[-3.898005277721187,48.6723935639094],[-3.8992413951649,48.67074624589731],[-3.903300809713803,48.67034264689684],[-3.907548440632195,48.66910635173531],[-3.91185396569359,48.669954398127075],[-3.914635548862354,48.67322568941628],[-3.920575104032537,48.67458696237509],[-3.924157593611878,48.669749821082725],[-3.927138109422188,48.66538094626539],[-3.927802453245391,48.66178827244388],[-3.92880004801291,48.660065331624466],[-3.930674658925236,48.657424523021],[-3.934385020441046,48.65730036039394],[-3.940574301992641,48.65682750256307],[-3.949892212356874,48.653210569309856],[-3.9518951695476,48.64983646195122],[-3.95135848409069,48.646306571150944],[-3.952791103114349,48.64456097348628],[-3.954311041643234,48.64535110107629],[-3.957178207067545,48.65093506946735],[-3.95632686509049,48.654756209794456],[-3.954939197043658,48.66049485799891],[-3.958264581105623,48.66351217516115],[-3.954301077151103,48.665175330569724],[-3.958113788215813,48.66678821578858],[-3.958288500972019,48.67004622329816],[-3.953583216471425,48.67102223996598],[-3.952154912225681,48.67280542236],[-3.954601922703807,48.67354649576719],[-3.957150323952388,48.6728667311387],[-3.962232217223142,48.674085603023535],[-3.96509885038279,48.67647290565392],[-3.968196892552599,48.67354977814375],[-3.970552500285286,48.67336152037275],[-3.971907150463719,48.67429537178488],[-3.971687730880199,48.67565139942766],[-3.968925351937541,48.67998621214178],[-3.97276835094199,48.68681279071675],[-3.969905040239144,48.687617856017994],[-3.967785856011854,48.69274164929216],[-3.97050395358365,48.693904041872074],[-3.974129066864182,48.69665141578885],[-3.976827175680581,48.699084231748806],[-3.973964059500176,48.70207052891004],[-3.97557715354335,48.70449012698265],[-3.972337757698344,48.70582333762662],[-3.974038535718974,48.710344199247295],[-3.972061362590358,48.71168433267898],[-3.969407494937729,48.71919463600953],[-3.966114995158957,48.719188628020184],[-3.964815895310649,48.72248973384656],[-3.968123622922862,48.72216808659624],[-3.970117554054281,48.7239825094888],[-3.971030085004171,48.72531725688056],[-3.974105493634571,48.72442714535237],[-3.977130032296356,48.72223266964199],[-3.98038470744471,48.72282149601802],[-3.98267568678471,48.72451484026706],[-3.983159793997456,48.72623219482621],[-3.985655519886893,48.726898196761965],[-3.988412331317411,48.727004809776105],[-3.990251104366354,48.72588975599552],[-3.992106999472123,48.723541171653366],[-3.992308257471176,48.72204072794657],[-3.990818477440011,48.71838055340067],[-3.993241558794496,48.715311146944074],[-3.99726181945054,48.71273584775902],[-4.000886986292233,48.71141716999743],[-4.005573266114372,48.715195490443925],[-4.004640753163968,48.716989015759715],[-4.007861713401779,48.72044675798358],[-4.009590286562232,48.72068101995395],[-4.012907971574204,48.71865165832863],[-4.010881803078078,48.716872551149415],[-4.013298574720932,48.713765123429766],[-4.018283788022766,48.71146515516518],[-4.02502266800395,48.710486602386844],[-4.029102910364339,48.7109751516783],[-4.032895375568785,48.712496949149184],[-4.034013864663466,48.71364906002572],[-4.035203599079426,48.71386049099469],[-4.036426674181452,48.711761570746404],[-4.035857818689737,48.70935978588029],[-4.037836186006247,48.70536884991981],[-4.040876440962449,48.70331706201061],[-4.042661395770205,48.70267658451317],[-4.044522857875245,48.70264835316387],[-4.048746772595955,48.70536952092104],[-4.051782617787177,48.70458102418029],[-4.053387641319855,48.70237110662314],[-4.054960885021424,48.69887510664347],[-4.057098904957046,48.688336149296134],[-4.047492224129947,48.6881905546806],[-4.04264615919883,48.688356681641565],[-4.05570877851515,48.685187990084636],[-4.061384711067841,48.687678086132514],[-4.063856568443375,48.68626486757381],[-4.069006699782528,48.687977416990556],[-4.066114156101222,48.68600063748565],[-4.065917761777147,48.68383188367652],[-4.06536435070835,48.68281963355705],[-4.062811851052143,48.68243638561189],[-4.063604286352126,48.680735563101265],[-4.061249339782617,48.68019915458731],[-4.060491984152113,48.67893668983929],[-4.056630622211962,48.67523642323898],[-4.055350396131191,48.67179995101334],[-4.057224936686009,48.670572879663034],[-4.057969445321888,48.675068847630506],[-4.059622862128396,48.675122344607715],[-4.06024682153259,48.67613145254186],[-4.063213863275964,48.67815002912692],[-4.064507934140134,48.677605925445725],[-4.067195178609656,48.67891661518815],[-4.068000601946539,48.68272446881325],[-4.07116708376152,48.68462241191764],[-4.080222240659125,48.689712089777736],[-4.082890717412141,48.693212237422216],[-4.0837341887691,48.69168549285934],[-4.08645810312384,48.69005696722575],[-4.08922980276701,48.69161527586137],[-4.091651149022687,48.69171173600047],[-4.095188717132302,48.686965610139666],[-4.097383839952319,48.69356464812578],[-4.102536986221444,48.69351221259058],[-4.106197887484285,48.692515838515405],[-4.109568285925066,48.69472448012849],[-4.115803404112282,48.69506791354793],[-4.118098969264236,48.692778728280935],[-4.12511664716867,48.693877169595176],[-4.127837461875522,48.69361476668908],[-4.131236501370729,48.6960475956426],[-4.136181126707938,48.69293107079426],[-4.142132619722753,48.69237814384752],[-4.150020162763907,48.69217377284019],[-4.152170300893284,48.691487051119246],[-4.162483098525137,48.68833023827453],[-4.174170898732186,48.657628672506775],[-4.409843663429304,48.633874515395604],[-4.370364497124209,48.53380508608616]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.370364497124209,48.53380508608616]},"properties":{"nom":"A","description":"Polygone 1","latitude":"48.53380508608616","longitude":"-4.370364497124209"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.373271574712479,48.47151134163559]},"properties":{"nom":"B","description":"Polygone 1","latitude":"48.47151134163559","longitude":"-4.373271574712479"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.03753485335386,48.579164636474836]},"properties":{"nom":"C","description":"Polygone 1","latitude":"48.579164636474836","longitude":"-4.03753485335386"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.89919702975027,48.603980178934115]},"properties":{"nom":"D","description":"Polygone 1","latitude":"48.603980178934115","longitude":"-3.89919702975027"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.860482328708233,48.62511389817695]},"properties":{"nom":"E","description":"Polygone 1","latitude":"48.62511389817695","longitude":"-3.860482328708233"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.858436311611334,48.629031691751045]},"properties":{"nom":"F","description":"Polygone 1","latitude":"48.629031691751045","longitude":"-3.858436311611334"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.862157259991486,48.633014015139416]},"properties":{"nom":"G","description":"Polygone 1","latitude":"48.633014015139416","longitude":"-3.862157259991486"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.870281882041237,48.63550010399696]},"properties":{"nom":"H","description":"Polygone 1","latitude":"48.63550010399696","longitude":"-3.870281882041237"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.879786359001045,48.639113643702565]},"properties":{"nom":"I","description":"Polygone 1","latitude":"48.639113643702565","longitude":"-3.879786359001045"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.895430188480503,48.64455770816115]},"properties":{"nom":"J","description":"Polygone 1","latitude":"48.64455770816115","longitude":"-3.895430188480503"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.89902273351368,48.64822789311303]},"properties":{"nom":"K","description":"Polygone 1","latitude":"48.64822789311303","longitude":"-3.89902273351368"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.902536979616769,48.654435032933826]},"properties":{"nom":"L","description":"Polygone 1","latitude":"48.654435032933826","longitude":"-3.902536979616769"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.906528075174153,48.66061643462235]},"properties":{"nom":"M","description":"Polygone 1","latitude":"48.66061643462235","longitude":"-3.906528075174153"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.904489574558275,48.6643307169305]},"properties":{"nom":"N","description":"Polygone 1","latitude":"48.6643307169305","longitude":"-3.904489574558275"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.89647573803132,48.66601900245078]},"properties":{"nom":"O","description":"Polygone 1","latitude":"48.66601900245078","longitude":"-3.89647573803132"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.890673665115296,48.667020244464325]},"properties":{"nom":"P","description":"Polygone 1","latitude":"48.667020244464325","longitude":"-3.890673665115296"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.890721315690864,48.67062455977177]},"properties":{"nom":"Q","description":"Polygone 1","latitude":"48.67062455977177","longitude":"-3.890721315690864"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.892950905315848,48.67088770685571]},"properties":{"nom":"R","description":"Polygone 1","latitude":"48.67088770685571","longitude":"-3.892950905315848"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.898005277721187,48.6723935639094]},"properties":{"nom":"S","description":"Polygone 1","latitude":"48.6723935639094","longitude":"-3.898005277721187"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.8992413951649,48.67074624589731]},"properties":{"nom":"T","description":"Polygone 1","latitude":"48.67074624589731","longitude":"-3.8992413951649"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.903300809713803,48.67034264689684]},"properties":{"nom":"U","description":"Polygone 1","latitude":"48.67034264689684","longitude":"-3.903300809713803"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.907548440632195,48.66910635173531]},"properties":{"nom":"V","description":"Polygone 1","latitude":"48.66910635173531","longitude":"-3.907548440632195"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.91185396569359,48.669954398127075]},"properties":{"nom":"W","description":"Polygone 1","latitude":"48.669954398127075","longitude":"-3.91185396569359"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.914635548862354,48.67322568941628]},"properties":{"nom":"X","description":"Polygone 1","latitude":"48.67322568941628","longitude":"-3.914635548862354"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.920575104032537,48.67458696237509]},"properties":{"nom":"Y","description":"Polygone 1","latitude":"48.67458696237509","longitude":"-3.920575104032537"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.924157593611878,48.669749821082725]},"properties":{"nom":"Z","description":"Polygone 1","latitude":"48.669749821082725","longitude":"-3.924157593611878"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.927138109422188,48.66538094626539]},"properties":{"nom":"AA","description":"Polygone 1","latitude":"48.66538094626539","longitude":"-3.927138109422188"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.927802453245391,48.66178827244388]},"properties":{"nom":"AB","description":"Polygone 1","latitude":"48.66178827244388","longitude":"-3.927802453245391"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.92880004801291,48.660065331624466]},"properties":{"nom":"AC","description":"Polygone 1","latitude":"48.660065331624466","longitude":"-3.92880004801291"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.930674658925236,48.657424523021]},"properties":{"nom":"AD","description":"Polygone 1","latitude":"48.657424523021","longitude":"-3.930674658925236"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.934385020441046,48.65730036039394]},"properties":{"nom":"AE","description":"Polygone 1","latitude":"48.65730036039394","longitude":"-3.934385020441046"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.940574301992641,48.65682750256307]},"properties":{"nom":"AF","description":"Polygone 1","latitude":"48.65682750256307","longitude":"-3.940574301992641"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.949892212356874,48.653210569309856]},"properties":{"nom":"AG","description":"Polygone 1","latitude":"48.653210569309856","longitude":"-3.949892212356874"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.9518951695476,48.64983646195122]},"properties":{"nom":"AH","description":"Polygone 1","latitude":"48.64983646195122","longitude":"-3.9518951695476"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.95135848409069,48.646306571150944]},"properties":{"nom":"AI","description":"Polygone 1","latitude":"48.646306571150944","longitude":"-3.95135848409069"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.952791103114349,48.64456097348628]},"properties":{"nom":"AJ","description":"Polygone 1","latitude":"48.64456097348628","longitude":"-3.952791103114349"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.954311041643234,48.64535110107629]},"properties":{"nom":"AK","description":"Polygone 1","latitude":"48.64535110107629","longitude":"-3.954311041643234"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.957178207067545,48.65093506946735]},"properties":{"nom":"AL","description":"Polygone 1","latitude":"48.65093506946735","longitude":"-3.957178207067545"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.95632686509049,48.654756209794456]},"properties":{"nom":"AM","description":"Polygone 1","latitude":"48.654756209794456","longitude":"-3.95632686509049"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.954939197043658,48.66049485799891]},"properties":{"nom":"AN","description":"Polygone 1","latitude":"48.66049485799891","longitude":"-3.954939197043658"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.958264581105623,48.66351217516115]},"properties":{"nom":"AO","description":"Polygone 1","latitude":"48.66351217516115","longitude":"-3.958264581105623"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.954301077151103,48.665175330569724]},"properties":{"nom":"AP","description":"Polygone 1","latitude":"48.665175330569724","longitude":"-3.954301077151103"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.958113788215813,48.66678821578858]},"properties":{"nom":"AQ","description":"Polygone 1","latitude":"48.66678821578858","longitude":"-3.958113788215813"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.958288500972019,48.67004622329816]},"properties":{"nom":"AR","description":"Polygone 1","latitude":"48.67004622329816","longitude":"-3.958288500972019"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.953583216471425,48.67102223996598]},"properties":{"nom":"AS","description":"Polygone 1","latitude":"48.67102223996598","longitude":"-3.953583216471425"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.952154912225681,48.67280542236]},"properties":{"nom":"AT","description":"Polygone 1","latitude":"48.67280542236","longitude":"-3.952154912225681"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.954601922703807,48.67354649576719]},"properties":{"nom":"AU","description":"Polygone 1","latitude":"48.67354649576719","longitude":"-3.954601922703807"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.957150323952388,48.6728667311387]},"properties":{"nom":"AV","description":"Polygone 1","latitude":"48.6728667311387","longitude":"-3.957150323952388"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.962232217223142,48.674085603023535]},"properties":{"nom":"AW","description":"Polygone 1","latitude":"48.674085603023535","longitude":"-3.962232217223142"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.96509885038279,48.67647290565392]},"properties":{"nom":"AX","description":"Polygone 1","latitude":"48.67647290565392","longitude":"-3.96509885038279"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.968196892552599,48.67354977814375]},"properties":{"nom":"AY","description":"Polygone 1","latitude":"48.67354977814375","longitude":"-3.968196892552599"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.970552500285286,48.67336152037275]},"properties":{"nom":"AZ","description":"Polygone 1","latitude":"48.67336152037275","longitude":"-3.970552500285286"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.971907150463719,48.67429537178488]},"properties":{"nom":"BA","description":"Polygone 1","latitude":"48.67429537178488","longitude":"-3.971907150463719"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.971687730880199,48.67565139942766]},"properties":{"nom":"BB","description":"Polygone 1","latitude":"48.67565139942766","longitude":"-3.971687730880199"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.968925351937541,48.67998621214178]},"properties":{"nom":"BC","description":"Polygone 1","latitude":"48.67998621214178","longitude":"-3.968925351937541"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.97276835094199,48.68681279071675]},"properties":{"nom":"BD","description":"Polygone 1","latitude":"48.68681279071675","longitude":"-3.97276835094199"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.969905040239144,48.687617856017994]},"properties":{"nom":"BE","description":"Polygone 1","latitude":"48.687617856017994","longitude":"-3.969905040239144"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.967785856011854,48.69274164929216]},"properties":{"nom":"BF","description":"Polygone 1","latitude":"48.69274164929216","longitude":"-3.967785856011854"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.97050395358365,48.693904041872074]},"properties":{"nom":"BG","description":"Polygone 1","latitude":"48.693904041872074","longitude":"-3.97050395358365"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.974129066864182,48.69665141578885]},"properties":{"nom":"BH","description":"Polygone 1","latitude":"48.69665141578885","longitude":"-3.974129066864182"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.976827175680581,48.699084231748806]},"properties":{"nom":"BI","description":"Polygone 1","latitude":"48.699084231748806","longitude":"-3.976827175680581"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.973964059500176,48.70207052891004]},"properties":{"nom":"BJ","description":"Polygone 1","latitude":"48.70207052891004","longitude":"-3.973964059500176"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.97557715354335,48.70449012698265]},"properties":{"nom":"BK","description":"Polygone 1","latitude":"48.70449012698265","longitude":"-3.97557715354335"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.972337757698344,48.70582333762662]},"properties":{"nom":"BL","description":"Polygone 1","latitude":"48.70582333762662","longitude":"-3.972337757698344"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.974038535718974,48.710344199247295]},"properties":{"nom":"BM","description":"Polygone 1","latitude":"48.710344199247295","longitude":"-3.974038535718974"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.972061362590358,48.71168433267898]},"properties":{"nom":"BN","description":"Polygone 1","latitude":"48.71168433267898","longitude":"-3.972061362590358"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.969407494937729,48.71919463600953]},"properties":{"nom":"BO","description":"Polygone 1","latitude":"48.71919463600953","longitude":"-3.969407494937729"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.966114995158957,48.719188628020184]},"properties":{"nom":"BP","description":"Polygone 1","latitude":"48.719188628020184","longitude":"-3.966114995158957"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.964815895310649,48.72248973384656]},"properties":{"nom":"BQ","description":"Polygone 1","latitude":"48.72248973384656","longitude":"-3.964815895310649"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.968123622922862,48.72216808659624]},"properties":{"nom":"BR","description":"Polygone 1","latitude":"48.72216808659624","longitude":"-3.968123622922862"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.970117554054281,48.7239825094888]},"properties":{"nom":"BS","description":"Polygone 1","latitude":"48.7239825094888","longitude":"-3.970117554054281"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.971030085004171,48.72531725688056]},"properties":{"nom":"BT","description":"Polygone 1","latitude":"48.72531725688056","longitude":"-3.971030085004171"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.974105493634571,48.72442714535237]},"properties":{"nom":"BU","description":"Polygone 1","latitude":"48.72442714535237","longitude":"-3.974105493634571"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.977130032296356,48.72223266964199]},"properties":{"nom":"BV","description":"Polygone 1","latitude":"48.72223266964199","longitude":"-3.977130032296356"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.98038470744471,48.72282149601802]},"properties":{"nom":"BW","description":"Polygone 1","latitude":"48.72282149601802","longitude":"-3.98038470744471"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.98267568678471,48.72451484026706]},"properties":{"nom":"BX","description":"Polygone 1","latitude":"48.72451484026706","longitude":"-3.98267568678471"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.983159793997456,48.72623219482621]},"properties":{"nom":"BY","description":"Polygone 1","latitude":"48.72623219482621","longitude":"-3.983159793997456"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.985655519886893,48.726898196761965]},"properties":{"nom":"BZ","description":"Polygone 1","latitude":"48.726898196761965","longitude":"-3.985655519886893"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.988412331317411,48.727004809776105]},"properties":{"nom":"CA","description":"Polygone 1","latitude":"48.727004809776105","longitude":"-3.988412331317411"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.990251104366354,48.72588975599552]},"properties":{"nom":"CB","description":"Polygone 1","latitude":"48.72588975599552","longitude":"-3.990251104366354"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.992106999472123,48.723541171653366]},"properties":{"nom":"CC","description":"Polygone 1","latitude":"48.723541171653366","longitude":"-3.992106999472123"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.992308257471176,48.72204072794657]},"properties":{"nom":"CD","description":"Polygone 1","latitude":"48.72204072794657","longitude":"-3.992308257471176"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.990818477440011,48.71838055340067]},"properties":{"nom":"CE","description":"Polygone 1","latitude":"48.71838055340067","longitude":"-3.990818477440011"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.993241558794496,48.715311146944074]},"properties":{"nom":"CF","description":"Polygone 1","latitude":"48.715311146944074","longitude":"-3.993241558794496"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-3.99726181945054,48.71273584775902]},"properties":{"nom":"CG","description":"Polygone 1","latitude":"48.71273584775902","longitude":"-3.99726181945054"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.000886986292233,48.71141716999743]},"properties":{"nom":"CH","description":"Polygone 1","latitude":"48.71141716999743","longitude":"-4.000886986292233"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.005573266114372,48.715195490443925]},"properties":{"nom":"CI","description":"Polygone 1","latitude":"48.715195490443925","longitude":"-4.005573266114372"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.004640753163968,48.716989015759715]},"properties":{"nom":"CJ","description":"Polygone 1","latitude":"48.716989015759715","longitude":"-4.004640753163968"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.007861713401779,48.72044675798358]},"properties":{"nom":"CK","description":"Polygone 1","latitude":"48.72044675798358","longitude":"-4.007861713401779"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.009590286562232,48.72068101995395]},"properties":{"nom":"CL","description":"Polygone 1","latitude":"48.72068101995395","longitude":"-4.009590286562232"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.012907971574204,48.71865165832863]},"properties":{"nom":"CM","description":"Polygone 1","latitude":"48.71865165832863","longitude":"-4.012907971574204"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.010881803078078,48.716872551149415]},"properties":{"nom":"CN","description":"Polygone 1","latitude":"48.716872551149415","longitude":"-4.010881803078078"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.013298574720932,48.713765123429766]},"properties":{"nom":"CO","description":"Polygone 1","latitude":"48.713765123429766","longitude":"-4.013298574720932"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.018283788022766,48.71146515516518]},"properties":{"nom":"CP","description":"Polygone 1","latitude":"48.71146515516518","longitude":"-4.018283788022766"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.02502266800395,48.710486602386844]},"properties":{"nom":"CQ","description":"Polygone 1","latitude":"48.710486602386844","longitude":"-4.02502266800395"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.029102910364339,48.7109751516783]},"properties":{"nom":"CR","description":"Polygone 1","latitude":"48.7109751516783","longitude":"-4.029102910364339"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.032895375568785,48.712496949149184]},"properties":{"nom":"CS","description":"Polygone 1","latitude":"48.712496949149184","longitude":"-4.032895375568785"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.034013864663466,48.71364906002572]},"properties":{"nom":"CT","description":"Polygone 1","latitude":"48.71364906002572","longitude":"-4.034013864663466"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.035203599079426,48.71386049099469]},"properties":{"nom":"CU","description":"Polygone 1","latitude":"48.71386049099469","longitude":"-4.035203599079426"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.036426674181452,48.711761570746404]},"properties":{"nom":"CV","description":"Polygone 1","latitude":"48.711761570746404","longitude":"-4.036426674181452"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.035857818689737,48.70935978588029]},"properties":{"nom":"CW","description":"Polygone 1","latitude":"48.70935978588029","longitude":"-4.035857818689737"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.037836186006247,48.70536884991981]},"properties":{"nom":"CX","description":"Polygone 1","latitude":"48.70536884991981","longitude":"-4.037836186006247"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.040876440962449,48.70331706201061]},"properties":{"nom":"CY","description":"Polygone 1","latitude":"48.70331706201061","longitude":"-4.040876440962449"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.042661395770205,48.70267658451317]},"properties":{"nom":"CZ","description":"Polygone 1","latitude":"48.70267658451317","longitude":"-4.042661395770205"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.044522857875245,48.70264835316387]},"properties":{"nom":"DA","description":"Polygone 1","latitude":"48.70264835316387","longitude":"-4.044522857875245"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.048746772595955,48.70536952092104]},"properties":{"nom":"DB","description":"Polygone 1","latitude":"48.70536952092104","longitude":"-4.048746772595955"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.051782617787177,48.70458102418029]},"properties":{"nom":"DC","description":"Polygone 1","latitude":"48.70458102418029","longitude":"-4.051782617787177"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.053387641319855,48.70237110662314]},"properties":{"nom":"DD","description":"Polygone 1","latitude":"48.70237110662314","longitude":"-4.053387641319855"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.054960885021424,48.69887510664347]},"properties":{"nom":"DE","description":"Polygone 1","latitude":"48.69887510664347","longitude":"-4.054960885021424"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.057098904957046,48.688336149296134]},"properties":{"nom":"DF","description":"Polygone 1","latitude":"48.688336149296134","longitude":"-4.057098904957046"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.047492224129947,48.6881905546806]},"properties":{"nom":"DG","description":"Polygone 1","latitude":"48.6881905546806","longitude":"-4.047492224129947"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.04264615919883,48.688356681641565]},"properties":{"nom":"DH","description":"Polygone 1","latitude":"48.688356681641565","longitude":"-4.04264615919883"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.05570877851515,48.685187990084636]},"properties":{"nom":"DI","description":"Polygone 1","latitude":"48.685187990084636","longitude":"-4.05570877851515"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.061384711067841,48.687678086132514]},"properties":{"nom":"DJ","description":"Polygone 1","latitude":"48.687678086132514","longitude":"-4.061384711067841"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.063856568443375,48.68626486757381]},"properties":{"nom":"DK","description":"Polygone 1","latitude":"48.68626486757381","longitude":"-4.063856568443375"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.069006699782528,48.687977416990556]},"properties":{"nom":"DL","description":"Polygone 1","latitude":"48.687977416990556","longitude":"-4.069006699782528"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.066114156101222,48.68600063748565]},"properties":{"nom":"DM","description":"Polygone 1","latitude":"48.68600063748565","longitude":"-4.066114156101222"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.065917761777147,48.68383188367652]},"properties":{"nom":"DN","description":"Polygone 1","latitude":"48.68383188367652","longitude":"-4.065917761777147"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.06536435070835,48.68281963355705]},"properties":{"nom":"DO","description":"Polygone 1","latitude":"48.68281963355705","longitude":"-4.06536435070835"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.062811851052143,48.68243638561189]},"properties":{"nom":"DP","description":"Polygone 1","latitude":"48.68243638561189","longitude":"-4.062811851052143"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.063604286352126,48.680735563101265]},"properties":{"nom":"DQ","description":"Polygone 1","latitude":"48.680735563101265","longitude":"-4.063604286352126"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.061249339782617,48.68019915458731]},"properties":{"nom":"DR","description":"Polygone 1","latitude":"48.68019915458731","longitude":"-4.061249339782617"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.060491984152113,48.67893668983929]},"properties":{"nom":"DS","description":"Polygone 1","latitude":"48.67893668983929","longitude":"-4.060491984152113"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.056630622211962,48.67523642323898]},"properties":{"nom":"DT","description":"Polygone 1","latitude":"48.67523642323898","longitude":"-4.056630622211962"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.055350396131191,48.67179995101334]},"properties":{"nom":"DU","description":"Polygone 1","latitude":"48.67179995101334","longitude":"-4.055350396131191"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.057224936686009,48.670572879663034]},"properties":{"nom":"DV","description":"Polygone 1","latitude":"48.670572879663034","longitude":"-4.057224936686009"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.057969445321888,48.675068847630506]},"properties":{"nom":"DW","description":"Polygone 1","latitude":"48.675068847630506","longitude":"-4.057969445321888"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.059622862128396,48.675122344607715]},"properties":{"nom":"DX","description":"Polygone 1","latitude":"48.675122344607715","longitude":"-4.059622862128396"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.06024682153259,48.67613145254186]},"properties":{"nom":"DY","description":"Polygone 1","latitude":"48.67613145254186","longitude":"-4.06024682153259"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.063213863275964,48.67815002912692]},"properties":{"nom":"DZ","description":"Polygone 1","latitude":"48.67815002912692","longitude":"-4.063213863275964"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.064507934140134,48.677605925445725]},"properties":{"nom":"EA","description":"Polygone 1","latitude":"48.677605925445725","longitude":"-4.064507934140134"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.067195178609656,48.67891661518815]},"properties":{"nom":"EB","description":"Polygone 1","latitude":"48.67891661518815","longitude":"-4.067195178609656"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.068000601946539,48.68272446881325]},"properties":{"nom":"EC","description":"Polygone 1","latitude":"48.68272446881325","longitude":"-4.068000601946539"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.07116708376152,48.68462241191764]},"properties":{"nom":"ED","description":"Polygone 1","latitude":"48.68462241191764","longitude":"-4.07116708376152"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.080222240659125,48.689712089777736]},"properties":{"nom":"EE","description":"Polygone 1","latitude":"48.689712089777736","longitude":"-4.080222240659125"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.082890717412141,48.693212237422216]},"properties":{"nom":"EF","description":"Polygone 1","latitude":"48.693212237422216","longitude":"-4.082890717412141"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.0837341887691,48.69168549285934]},"properties":{"nom":"EG","description":"Polygone 1","latitude":"48.69168549285934","longitude":"-4.0837341887691"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.08645810312384,48.69005696722575]},"properties":{"nom":"EH","description":"Polygone 1","latitude":"48.69005696722575","longitude":"-4.08645810312384"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.08922980276701,48.69161527586137]},"properties":{"nom":"EI","description":"Polygone 1","latitude":"48.69161527586137","longitude":"-4.08922980276701"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.091651149022687,48.69171173600047]},"properties":{"nom":"EJ","description":"Polygone 1","latitude":"48.69171173600047","longitude":"-4.091651149022687"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.095188717132302,48.686965610139666]},"properties":{"nom":"EK","description":"Polygone 1","latitude":"48.686965610139666","longitude":"-4.095188717132302"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.097383839952319,48.69356464812578]},"properties":{"nom":"EL","description":"Polygone 1","latitude":"48.69356464812578","longitude":"-4.097383839952319"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.102536986221444,48.69351221259058]},"properties":{"nom":"EM","description":"Polygone 1","latitude":"48.69351221259058","longitude":"-4.102536986221444"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.106197887484285,48.692515838515405]},"properties":{"nom":"EN","description":"Polygone 1","latitude":"48.692515838515405","longitude":"-4.106197887484285"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.109568285925066,48.69472448012849]},"properties":{"nom":"EO","description":"Polygone 1","latitude":"48.69472448012849","longitude":"-4.109568285925066"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.115803404112282,48.69506791354793]},"properties":{"nom":"EP","description":"Polygone 1","latitude":"48.69506791354793","longitude":"-4.115803404112282"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.118098969264236,48.692778728280935]},"properties":{"nom":"EQ","description":"Polygone 1","latitude":"48.692778728280935","longitude":"-4.118098969264236"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.12511664716867,48.693877169595176]},"properties":{"nom":"ER","description":"Polygone 1","latitude":"48.693877169595176","longitude":"-4.12511664716867"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.127837461875522,48.69361476668908]},"properties":{"nom":"ES","description":"Polygone 1","latitude":"48.69361476668908","longitude":"-4.127837461875522"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.131236501370729,48.6960475956426]},"properties":{"nom":"ET","description":"Polygone 1","latitude":"48.6960475956426","longitude":"-4.131236501370729"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.136181126707938,48.69293107079426]},"properties":{"nom":"EU","description":"Polygone 1","latitude":"48.69293107079426","longitude":"-4.136181126707938"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.142132619722753,48.69237814384752]},"properties":{"nom":"EV","description":"Polygone 1","latitude":"48.69237814384752","longitude":"-4.142132619722753"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.150020162763907,48.69217377284019]},"properties":{"nom":"EW","description":"Polygone 1","latitude":"48.69217377284019","longitude":"-4.150020162763907"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.152170300893284,48.691487051119246]},"properties":{"nom":"EX","description":"Polygone 1","latitude":"48.691487051119246","longitude":"-4.152170300893284"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.162483098525137,48.68833023827453]},"properties":{"nom":"EY","description":"Polygone 1","latitude":"48.68833023827453","longitude":"-4.162483098525137"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.174170898732186,48.657628672506775]},"properties":{"nom":"EZ","description":"Polygone 1","latitude":"48.657628672506775","longitude":"-4.174170898732186"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-4.409843663429304,48.633874515395604]},"properties":{"nom":"FA","description":"Polygone 1","latitude":"48.633874515395604","longitude":"-4.409843663429304"}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":3}</perimetre> <id>"test"</id> - <titretypeid>"axm"</titretypeid> + <machineinfo>{"_titreTypeId":"axm","_demarcheTypeId":"oct","_demarcheId":"demarcheId"}</machineinfo> <style> { "minHeight": "400px" diff --git a/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Default.html b/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Default.html index aa81f34ebf3895db2bf47753912d1b1621704132..69ed19ac8ed3ea92ba0d89ac4778a5b90f5aeaa8 100644 --- a/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Default.html +++ b/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Default.html @@ -305,10 +305,10 @@ </ul> <div id="tabpanel-carte-test-panel" class="fr-tabs__panel fr-tabs__panel--selected" role="tabpanel" aria-labelledby="tabpanel-carte-test" tabindex="0"> <div style="display: flex; flex-direction: column;"> - <mocked-map perimetre="[object Object]" id="test" titretypeid="axm" style="min-height: 400px;" class="fr-mb-1w" maxmarkers="20" neighbours="[object Object]"> + <mocked-map perimetre="[object Object]" id="test" machineinfo="[object Object]" style="min-height: 400px;" class="fr-mb-1w" maxmarkers="20" neighbours="[object Object]"> <perimetre>{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-52.5660583466962,4.23944263425535],[-52.5591878553913,4.22269896902571],[-52.5550566725882,4.22438936251509],[-52.5619271168799,4.24113309117193],[-52.5660583466962,4.23944263425535]]]]}},"geojson4326_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5660583466962,4.23944263425535]},"properties":{"nom":"A","description":"Polygone 1","latitude":"4.23944263425535","longitude":"-52.5660583466962"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5591878553913,4.22269896902571]},"properties":{"nom":"B","description":"Polygone 1","latitude":"4.22269896902571","longitude":"-52.5591878553913"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5550566725882,4.22438936251509]},"properties":{"nom":"C","description":"Polygone 1","latitude":"4.22438936251509","longitude":"-52.5550566725882"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5619271168799,4.24113309117193]},"properties":{"nom":"D","description":"Polygone 1","latitude":"4.24113309117193","longitude":"-52.5619271168799"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-52.5660583466962,4.23944263425535],[-52.5591878553913,4.22269896902571],[-52.5550566725882,4.22438936251509],[-52.5619271168799,4.24113309117193],[-52.5660583466962,4.23944263425535]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5660583466962,4.23944263425535]},"properties":{"nom":"A","description":"Polygone 1","latitude":"4.23944263425535","longitude":"-52.5660583466962"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5591878553913,4.22269896902571]},"properties":{"nom":"B","description":"Polygone 1","latitude":"4.22269896902571","longitude":"-52.5591878553913"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5550566725882,4.22438936251509]},"properties":{"nom":"C","description":"Polygone 1","latitude":"4.22438936251509","longitude":"-52.5550566725882"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5619271168799,4.24113309117193]},"properties":{"nom":"D","description":"Polygone 1","latitude":"4.24113309117193","longitude":"-52.5619271168799"}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":3}</perimetre> <id>"test"</id> - <titretypeid>"axm"</titretypeid> + <machineinfo>{"_titreTypeId":"axm","_demarcheTypeId":"oct","_demarcheId":"demarcheId"}</machineinfo> <style> { "minHeight": "400px" diff --git a/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Multiple.html b/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Multiple.html index 0660c4d1647a0bc085cfeb2636fc03cb579d138f..f4c934bc008116e0f9d4fe419ec1fa7bb71c6835 100644 --- a/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Multiple.html +++ b/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_Multiple.html @@ -305,10 +305,10 @@ </ul> <div id="tabpanel-carte-test-panel" class="fr-tabs__panel fr-tabs__panel--selected" role="tabpanel" aria-labelledby="tabpanel-carte-test" tabindex="0"> <div style="display: flex; flex-direction: column;"> - <mocked-map perimetre="[object Object]" id="test" titretypeid="axm" style="min-height: 400px;" class="fr-mb-1w" maxmarkers="20" neighbours="[object Object]"> + <mocked-map perimetre="[object Object]" id="test" machineinfo="[object Object]" style="min-height: 400px;" class="fr-mb-1w" maxmarkers="20" neighbours="[object Object]"> <perimetre>{"geojson4326_perimetre":{"properties":{},"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-53.58181013905019,3.8309654861273],[-53.58178306390299,3.8219278216269807],[-53.572785590706495,3.82195493825841],[-53.57281257175149,3.8309926670647294],[-53.58181013905019,3.8309654861273]]],[[[-53.60031408473134,3.8224780986447566],[-53.59891645305842,3.8181831495446303],[-53.58181205656814,3.82379854768971],[-53.58320964990986,3.828093576227541],[-53.60031408473134,3.8224780986447566]]],[[[-53.583861926103765,3.8502114455117433],[-53.592379712320195,3.834289122043602],[-53.588417035915334,3.8321501920354253],[-53.57989914401643,3.8480725119510217],[-53.583861926103765,3.8502114455117433]]]]}},"geojson_origine_perimetre":{"properties":{},"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-53.58181013905019,3.8309654861273],[-53.58178306390299,3.8219278216269807],[-53.572785590706495,3.82195493825841],[-53.57281257175149,3.8309926670647294],[-53.58181013905019,3.8309654861273]]],[[[-53.60031408473134,3.8224780986447566],[-53.59891645305842,3.8181831495446303],[-53.58181205656814,3.82379854768971],[-53.58320964990986,3.828093576227541],[-53.60031408473134,3.8224780986447566]]],[[[-53.583861926103765,3.8502114455117433],[-53.592379712320195,3.834289122043602],[-53.588417035915334,3.8321501920354253],[-53.57989914401643,3.8480725119510217],[-53.583861926103765,3.8502114455117433]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58181013905019,3.8309654861273]},"properties":{"nom":"A","description":"Polygone 1","latitude":"3.8309654861273","longitude":"-53.58181013905019"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58178306390299,3.8219278216269807]},"properties":{"nom":"B","description":"Polygone 1","latitude":"3.8219278216269807","longitude":"-53.58178306390299"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.572785590706495,3.82195493825841]},"properties":{"nom":"C","description":"Polygone 1","latitude":"3.82195493825841","longitude":"-53.572785590706495"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.57281257175149,3.8309926670647294]},"properties":{"nom":"D","description":"Polygone 1","latitude":"3.8309926670647294","longitude":"-53.57281257175149"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.60031408473134,3.8224780986447566]},"properties":{"nom":"E","description":"Polygone 2","latitude":"3.8224780986447566","longitude":"-53.60031408473134"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.59891645305842,3.8181831495446303]},"properties":{"nom":"F","description":"Polygone 2","latitude":"3.8181831495446303","longitude":"-53.59891645305842"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58181205656814,3.82379854768971]},"properties":{"nom":"G","description":"Polygone 2","latitude":"3.82379854768971","longitude":"-53.58181205656814"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58320964990986,3.828093576227541]},"properties":{"nom":"H","description":"Polygone 2","latitude":"3.828093576227541","longitude":"-53.58320964990986"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.583861926103765,3.8502114455117433]},"properties":{"nom":"I","description":"Polygone 3","latitude":"3.8502114455117433","longitude":"-53.583861926103765"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.592379712320195,3.834289122043602]},"properties":{"nom":"J","description":"Polygone 3","latitude":"3.834289122043602","longitude":"-53.592379712320195"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.588417035915334,3.8321501920354253]},"properties":{"nom":"K","description":"Polygone 3","latitude":"3.8321501920354253","longitude":"-53.588417035915334"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.57989914401643,3.8480725119510217]},"properties":{"nom":"L","description":"Polygone 3","latitude":"3.8480725119510217","longitude":"-53.57989914401643"}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58181013905019,3.8309654861273]},"properties":{"nom":"A","description":"Polygone 1","latitude":"3.8309654861273","longitude":"-53.58181013905019"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58178306390299,3.8219278216269807]},"properties":{"nom":"B","description":"Polygone 1","latitude":"3.8219278216269807","longitude":"-53.58178306390299"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.572785590706495,3.82195493825841]},"properties":{"nom":"C","description":"Polygone 1","latitude":"3.82195493825841","longitude":"-53.572785590706495"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.57281257175149,3.8309926670647294]},"properties":{"nom":"D","description":"Polygone 1","latitude":"3.8309926670647294","longitude":"-53.57281257175149"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.60031408473134,3.8224780986447566]},"properties":{"nom":"E","description":"Polygone 2","latitude":"3.8224780986447566","longitude":"-53.60031408473134"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.59891645305842,3.8181831495446303]},"properties":{"nom":"F","description":"Polygone 2","latitude":"3.8181831495446303","longitude":"-53.59891645305842"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58181205656814,3.82379854768971]},"properties":{"nom":"G","description":"Polygone 2","latitude":"3.82379854768971","longitude":"-53.58181205656814"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58320964990986,3.828093576227541]},"properties":{"nom":"H","description":"Polygone 2","latitude":"3.828093576227541","longitude":"-53.58320964990986"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.583861926103765,3.8502114455117433]},"properties":{"nom":"I","description":"Polygone 3","latitude":"3.8502114455117433","longitude":"-53.583861926103765"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.592379712320195,3.834289122043602]},"properties":{"nom":"J","description":"Polygone 3","latitude":"3.834289122043602","longitude":"-53.592379712320195"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.588417035915334,3.8321501920354253]},"properties":{"nom":"K","description":"Polygone 3","latitude":"3.8321501920354253","longitude":"-53.588417035915334"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.57989914401643,3.8480725119510217]},"properties":{"nom":"L","description":"Polygone 3","latitude":"3.8480725119510217","longitude":"-53.57989914401643"}}]},"geojson4326_forages":null,"geojson_origine_forages":null,"surface":3}</perimetre> <id>"test"</id> - <titretypeid>"axm"</titretypeid> + <machineinfo>{"_titreTypeId":"axm","_demarcheTypeId":"oct","_demarcheId":"demarcheId"}</machineinfo> <style> { "minHeight": "400px" diff --git a/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_NoNeighbors.html b/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_NoNeighbors.html index f061e33e428e33715af9730254a6b99aae7ce288..18f657e6876973025dee523d5a4123a4fff77e34 100644 --- a/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_NoNeighbors.html +++ b/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_NoNeighbors.html @@ -305,10 +305,10 @@ </ul> <div id="tabpanel-carte-test-panel" class="fr-tabs__panel fr-tabs__panel--selected" role="tabpanel" aria-labelledby="tabpanel-carte-test" tabindex="0"> <div style="display: flex; flex-direction: column;"> - <mocked-map perimetre="[object Object]" id="test" titretypeid="axm" style="min-height: 400px;" class="fr-mb-1w" maxmarkers="20"> + <mocked-map perimetre="[object Object]" id="test" machineinfo="[object Object]" style="min-height: 400px;" class="fr-mb-1w" maxmarkers="20"> <perimetre>{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-52.5660583466962,4.23944263425535],[-52.5591878553913,4.22269896902571],[-52.5550566725882,4.22438936251509],[-52.5619271168799,4.24113309117193],[-52.5660583466962,4.23944263425535]]]]}},"geojson4326_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5660583466962,4.23944263425535]},"properties":{"nom":"A","description":"Polygone 1","latitude":"4.23944263425535","longitude":"-52.5660583466962"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5591878553913,4.22269896902571]},"properties":{"nom":"B","description":"Polygone 1","latitude":"4.22269896902571","longitude":"-52.5591878553913"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5550566725882,4.22438936251509]},"properties":{"nom":"C","description":"Polygone 1","latitude":"4.22438936251509","longitude":"-52.5550566725882"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5619271168799,4.24113309117193]},"properties":{"nom":"D","description":"Polygone 1","latitude":"4.24113309117193","longitude":"-52.5619271168799"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-52.5660583466962,4.23944263425535],[-52.5591878553913,4.22269896902571],[-52.5550566725882,4.22438936251509],[-52.5619271168799,4.24113309117193],[-52.5660583466962,4.23944263425535]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5660583466962,4.23944263425535]},"properties":{"nom":"A","description":"Polygone 1","latitude":"4.23944263425535","longitude":"-52.5660583466962"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5591878553913,4.22269896902571]},"properties":{"nom":"B","description":"Polygone 1","latitude":"4.22269896902571","longitude":"-52.5591878553913"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5550566725882,4.22438936251509]},"properties":{"nom":"C","description":"Polygone 1","latitude":"4.22438936251509","longitude":"-52.5550566725882"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5619271168799,4.24113309117193]},"properties":{"nom":"D","description":"Polygone 1","latitude":"4.24113309117193","longitude":"-52.5619271168799"}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":3}</perimetre> <id>"test"</id> - <titretypeid>"axm"</titretypeid> + <machineinfo>{"_titreTypeId":"axm","_demarcheTypeId":"oct","_demarcheId":"demarcheId"}</machineinfo> <style> { "minHeight": "400px" diff --git a/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_PolygonWithLacune.html b/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_PolygonWithLacune.html index 497fddec1c42b34f9574a49c80ddb30e4c84e364..2f51e5ee61b476abb7e3a5bf1197aeff3422663e 100644 --- a/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_PolygonWithLacune.html +++ b/packages/ui/src/components/_common/dsfr-perimetre.stories_snapshots_PolygonWithLacune.html @@ -305,10 +305,10 @@ </ul> <div id="tabpanel-carte-test-panel" class="fr-tabs__panel fr-tabs__panel--selected" role="tabpanel" aria-labelledby="tabpanel-carte-test" tabindex="0"> <div style="display: flex; flex-direction: column;"> - <mocked-map perimetre="[object Object]" id="test" titretypeid="axm" style="min-height: 400px;" class="fr-mb-1w" maxmarkers="20" neighbours="[object Object]"> + <mocked-map perimetre="[object Object]" id="test" machineinfo="[object Object]" style="min-height: 400px;" class="fr-mb-1w" maxmarkers="20" neighbours="[object Object]"> <perimetre>{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-52.5660583466962,4.23944263425535],[-52.5591878553913,4.22269896902571],[-52.5550566725882,4.22438936251509],[-52.5619271168799,4.24113309117193],[-52.5660583466962,4.23944263425535]],[[-52.563,4.236],[-52.5591878553913,4.227],[-52.561,4.236],[-52.563,4.236]]]]}},"geojson4326_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5660583466962,4.23944263425535]},"properties":{"nom":"A","description":"Polygone 1","latitude":"4.23944263425535","longitude":"-52.5660583466962"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5591878553913,4.22269896902571]},"properties":{"nom":"B","description":"Polygone 1","latitude":"4.22269896902571","longitude":"-52.5591878553913"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5550566725882,4.22438936251509]},"properties":{"nom":"C","description":"Polygone 1","latitude":"4.22438936251509","longitude":"-52.5550566725882"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5619271168799,4.24113309117193]},"properties":{"nom":"D","description":"Polygone 1","latitude":"4.24113309117193","longitude":"-52.5619271168799"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.563,4.236]},"properties":{"nom":"E","description":"Polygone 1 - Lacune 1","latitude":"4.236","longitude":"-52.563"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5591878553913,4.227]},"properties":{"nom":"F","description":"Polygone 1 - Lacune 1","latitude":"4.227","longitude":"-52.5591878553913"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.561,4.236]},"properties":{"nom":"G","description":"Polygone 1 - Lacune 1","latitude":"4.236","longitude":"-52.561"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-52.5660583466962,4.23944263425535],[-52.5591878553913,4.22269896902571],[-52.5550566725882,4.22438936251509],[-52.5619271168799,4.24113309117193],[-52.5660583466962,4.23944263425535]],[[-52.563,4.236],[-52.5591878553913,4.227],[-52.561,4.236],[-52.563,4.236]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5660583466962,4.23944263425535]},"properties":{"nom":"A","description":"Polygone 1","latitude":"4.23944263425535","longitude":"-52.5660583466962"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5591878553913,4.22269896902571]},"properties":{"nom":"B","description":"Polygone 1","latitude":"4.22269896902571","longitude":"-52.5591878553913"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5550566725882,4.22438936251509]},"properties":{"nom":"C","description":"Polygone 1","latitude":"4.22438936251509","longitude":"-52.5550566725882"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5619271168799,4.24113309117193]},"properties":{"nom":"D","description":"Polygone 1","latitude":"4.24113309117193","longitude":"-52.5619271168799"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.563,4.236]},"properties":{"nom":"E","description":"Polygone 1 - Lacune 1","latitude":"4.236","longitude":"-52.563"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.5591878553913,4.227]},"properties":{"nom":"F","description":"Polygone 1 - Lacune 1","latitude":"4.227","longitude":"-52.5591878553913"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-52.561,4.236]},"properties":{"nom":"G","description":"Polygone 1 - Lacune 1","latitude":"4.236","longitude":"-52.561"}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":3}</perimetre> <id>"test"</id> - <titretypeid>"axm"</titretypeid> + <machineinfo>{"_titreTypeId":"axm","_demarcheTypeId":"oct","_demarcheId":"demarcheId"}</machineinfo> <style> { "minHeight": "400px" diff --git a/packages/ui/src/components/_common/dsfr-perimetre.tsx b/packages/ui/src/components/_common/dsfr-perimetre.tsx index 5fe77a1aa2ff5e966ecacc1b646697dfd311fe68..ca14fb204542d518ad62d99568e9448970de7565 100644 --- a/packages/ui/src/components/_common/dsfr-perimetre.tsx +++ b/packages/ui/src/components/_common/dsfr-perimetre.tsx @@ -8,9 +8,9 @@ import { ApiClient } from '../../api/api-client' import { TabCaminoTable, transformMultipolygonToPoints } from './dsfr-perimetre-table' import { OmitDistributive, isNotNullNorUndefined } from 'camino-common/src/typescript-tools' import { GeoSystemeId } from 'camino-common/src/static/geoSystemes' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' import { KM2 } from 'camino-common/src/number' import { CaminoRouter } from '@/typings/vue-router' +import { MachineInfo } from 'camino-common/src/machines' export type TabId = 'carte' | 'points' type Props = { @@ -25,7 +25,7 @@ type Props = { surface: KM2 | null } titreSlug: TitreSlug - titreTypeId: TitreTypeId + machineInfo: MachineInfo id: string initTab?: TabId class?: HTMLAttributes['class'] @@ -116,7 +116,7 @@ const TabCaminoMap = defineComponent<TabCaminoMapProps>(props => { return () => ( <div style={{ display: 'flex', flexDirection: 'column' }}> - <DemarcheMap perimetre={props.perimetre} id={props.id} titreTypeId={props.titreTypeId} style={{ minHeight: '400px' }} class="fr-mb-1w" maxMarkers={maxRows} neighbours={neighbours} /> + <DemarcheMap perimetre={props.perimetre} id={props.id} machineInfo={props.machineInfo} style={{ minHeight: '400px' }} class="fr-mb-1w" maxMarkers={maxRows} neighbours={neighbours} /> <div style={{ display: 'flex' }}> {isNotNullNorUndefined(props.perimetre.surface) ? <div class="fr-text--md">Surface : {props.perimetre.surface} Km²</div> : null} <div style={{ marginLeft: 'auto' }}> @@ -146,7 +146,7 @@ const TabCaminoMap = defineComponent<TabCaminoMapProps>(props => { }) // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 -DsfrPerimetre.props = ['id', 'perimetre', 'apiClient', 'titreSlug', 'titreTypeId', 'router', 'initTab', 'calculateNeighbours'] +DsfrPerimetre.props = ['id', 'perimetre', 'apiClient', 'titreSlug', 'machineInfo', 'router', 'initTab', 'calculateNeighbours'] // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 -TabCaminoMap.props = ['id', 'perimetre', 'apiClient', 'titreSlug', 'titreTypeId', 'router', 'initTab', 'calculateNeighbours'] +TabCaminoMap.props = ['id', 'perimetre', 'apiClient', 'titreSlug', 'machineInfo', 'router', 'initTab', 'calculateNeighbours'] diff --git a/packages/ui/src/components/dashboard/pure-super-dashboard.stories.tsx b/packages/ui/src/components/dashboard/pure-super-dashboard.stories.tsx index a3b7dfb341a7cd3d4eb64148e79719467c859284..1a33bc935eec08beee4524a47bc8887dcebe7ee4 100644 --- a/packages/ui/src/components/dashboard/pure-super-dashboard.stories.tsx +++ b/packages/ui/src/components/dashboard/pure-super-dashboard.stories.tsx @@ -51,6 +51,7 @@ const titres: SuperTitre[] = [ etape_date: caminoDateValidator.parse('1810-01-01'), etape_slug: etapeSlugValidator.parse('m-cx-aachen-1810-oct01-mfr01'), etape_type_id: 'mfr', + machine_id: 'AncienLogigrammeOctroiARM', }, { titre_nom: 'Amadis 5', @@ -62,6 +63,7 @@ const titres: SuperTitre[] = [ etape_date: caminoDateValidator.parse('2022-01-01'), etape_slug: etapeSlugValidator.parse('m-ax-amadis-5-2022-oct01-mfr01'), etape_type_id: 'asc', + machine_id: 'ProcedureSpecifique', }, ] diff --git a/packages/ui/src/components/dashboard/pure-super-dashboard.stories_snapshots_TableauPleinBrouillon.html b/packages/ui/src/components/dashboard/pure-super-dashboard.stories_snapshots_TableauPleinBrouillon.html index 91ad572118cbc54109b76090f0048cec839b7a73..be512670b970c8f9d2e2e72958c837bd612a3418 100644 --- a/packages/ui/src/components/dashboard/pure-super-dashboard.stories_snapshots_TableauPleinBrouillon.html +++ b/packages/ui/src/components/dashboard/pure-super-dashboard.stories_snapshots_TableauPleinBrouillon.html @@ -31,6 +31,7 @@ <th scope="col">Statut du titre</th> <th scope="col">Étape en brouillon</th> <th scope="col">Date de l'étape</th> + <th scope="col">Machine associée</th> </tr> </thead> <tbody> @@ -46,6 +47,7 @@ </td> <td><span class="">Demande</span></td> <td><span class="">1810-01-01</span></td> + <td><span class="">Ancien logigramme octroi d'ARM</span></td> </tr> <tr> <td><a href="/mocked-href" title="Amadis 5" aria-label="Amadis 5">Amadis 5</a></td> @@ -59,6 +61,7 @@ </td> <td><span class="">Avis des services et commissions consultatives</span></td> <td><span class="">2022-01-01</span></td> + <td><span class="">Procédure spécifique</span></td> </tr> </tbody> </table> diff --git a/packages/ui/src/components/dashboard/pure-super-dashboard.tsx b/packages/ui/src/components/dashboard/pure-super-dashboard.tsx index ec83dd855a144d43eece1e2e0478a39827f84812..7809e96958c088a86a142ee466c286902267b07c 100644 --- a/packages/ui/src/components/dashboard/pure-super-dashboard.tsx +++ b/packages/ui/src/components/dashboard/pure-super-dashboard.tsx @@ -8,7 +8,7 @@ import { ComponentColumnData, JSXElementColumnData, TableRow, TextColumnData } f import { DashboardApiClient } from './dashboard-api-client' import { User } from 'camino-common/src/roles' import { PageContentHeader } from '../_common/page-header-content' -import { exhaustiveCheck, isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools' +import { exhaustiveCheck, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools' import { CaminoRouterLink, routerQueryToString } from '@/router/camino-router-link' import { DemarchesTypes } from 'camino-common/src/static/demarchesTypes' import { capitalize } from 'camino-common/src/strings' @@ -25,7 +25,17 @@ import { ActivitesTypes } from 'camino-common/src/static/activitesTypes' import { ActiviteStatut } from '../_common/activite-statut' import { fr } from '@codegouvfr/react-dsfr' import { ACTIVITES_STATUTS_IDS } from 'camino-common/src/static/activitesStatuts' +import { CaminoMachineId } from 'camino-common/src/validators/machine' +const machineIdToText = { + AncienLogigrammeOctroiARM: "Ancien logigramme octroi d'ARM", + AncienLogigrammeOctroiAXM: "Ancien logigramme octroi d'AEX", + AncienLogigrammeOctroiPRM: 'Ancien logigramme octroi de PRM', + AncienLogigrammeProlongationAXM: "Ancien logigramme prolongation d'AEX", + AncienLogigrammeRenonciationEtProlongationARM: "Ancien logigramme renonciation et prolongation d'ARM", + ProcedureSimplifiee: 'Procédure simplifiée', + ProcedureSpecifique: 'Procédure spécifique', +} as const satisfies Record<CaminoMachineId, string> interface Props { apiClient: Pick<DashboardApiClient, 'getTitresAvecEtapeEnBrouillon' | 'getActivitesSuper'> user: User @@ -40,6 +50,7 @@ const brouillonsColumns = [ { id: 'titre_statut', contentTitle: 'Statut du titre' }, { id: 'etape_brouillon', contentTitle: 'Étape en brouillon' }, { id: 'etape_date', contentTitle: "Date de l'étape" }, + { id: 'machine', contentTitle: 'Machine associée' }, ] as const satisfies Column[] type BrouillonColumnId = (typeof brouillonsColumns)[number]['id'] @@ -124,6 +135,7 @@ export const PureSuperDashboard = defineComponent<Props>(props => { titre_statut: statutCell(titre), etape_brouillon: { type: 'text', value: capitalize(EtapesTypes[titre.etape_type_id].nom) }, etape_date: { type: 'text', value: titre.etape_date }, + machine: { type: 'text', value: isNotNullNorUndefined(titre.machine_id) ? machineIdToText[titre.machine_id] : 'TDE' }, } return { diff --git a/packages/ui/src/components/demarche-resultat-mise-en-concurrence.tsx b/packages/ui/src/components/demarche-resultat-mise-en-concurrence.tsx index 45f18f27fa91c4af9ba681deae5315df71ac8e1a..20e43ddef087fd1e41da396e0305ca1bc171cfd8 100644 --- a/packages/ui/src/components/demarche-resultat-mise-en-concurrence.tsx +++ b/packages/ui/src/components/demarche-resultat-mise-en-concurrence.tsx @@ -10,6 +10,7 @@ import { useRoute, useRouter } from 'vue-router' import { useState } from '@/utils/vue-tsx-utils' import { inject } from 'vue' import { entreprisesKey, userKey } from '@/moi' +import { MachineInfo } from 'camino-common/src/machines' export const DemarcheResultatMiseEnConcurrence = defineComponent(() => { const currentRoute = useRoute<'resultatMiseEnConcurrence'>() @@ -28,7 +29,7 @@ type Props = { } const PureDemarcheResultatMiseEnConcurrence = defineComponent<Props>(props => { - const [data, setData] = useState<AsyncData<GetResultatMiseEnConcurrence>>({ status: 'LOADING' }) + const [data, setData] = useState<AsyncData<{ pivot: GetResultatMiseEnConcurrence; machineInfo: MachineInfo }>>({ status: 'LOADING' }) const entreprises = inject(entreprisesKey, ref([])) const user = inject(userKey) @@ -42,7 +43,12 @@ const PureDemarcheResultatMiseEnConcurrence = defineComponent<Props>(props => { error: result, }) } else { - setData({ status: 'LOADED', value: result }) + const machineInfo = MachineInfo.withMachineId(result.titreTypeId, result.demarcheTypeId, result.demarcheId, result.machineId) + if (!machineInfo.valid) { + setData({ status: 'NEW_ERROR', error: { message: machineInfo.error } }) + } else { + setData({ status: 'LOADED', value: { pivot: result, machineInfo: machineInfo.value } }) + } } }) @@ -60,7 +66,8 @@ const PureDemarcheResultatMiseEnConcurrence = defineComponent<Props>(props => { }, }} user={user} - pivot={item} + pivot={item.pivot} + machineInfo={item.machineInfo} entreprises={entreprises.value} /> )} diff --git a/packages/ui/src/components/demarche/demarche-etape.stories.tsx b/packages/ui/src/components/demarche/demarche-etape.stories.tsx index fc40ce3368eaeab20bca263866e8bc99efdc6bc9..0a890add28b5d9e5410238c43239d72181517e4b 100644 --- a/packages/ui/src/components/demarche/demarche-etape.stories.tsx +++ b/packages/ui/src/components/demarche/demarche-etape.stories.tsx @@ -1,7 +1,7 @@ import { Meta, StoryFn } from '@storybook/vue3' import { DemarcheEtape } from './demarche-etape' import { EtapesTypesEtapesStatuts } from 'camino-common/src/static/etapesTypesEtapesStatuts' -import { toCaminoDate } from 'camino-common/src/date' +import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { Entreprise, EtapeEntrepriseDocument, entrepriseDocumentIdValidator, entrepriseIdValidator } from 'camino-common/src/entreprise' import { titreSlugValidator } from 'camino-common/src/validators/titres' import { action } from '@storybook/addon-actions' @@ -19,6 +19,7 @@ import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' import { AVIS_STATUTS, AVIS_TYPES, AvisVisibilityIds } from 'camino-common/src/static/avisTypes' import { TitresStatutIds } from 'camino-common/src/static/titresStatuts' +import { MachineInfo } from 'camino-common/src/machines' import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' @@ -290,14 +291,17 @@ const fondamentale: DemarcheEtapeFondamentale['fondamentale'] = { secteurs_maritimes: [], }, } +const demarcheId = demarcheIdValidator.parse('demarcheId') +const firstEtapeDate = firstEtapeDateValidator.parse('2020-01-01') export const NoSnapshotDemande: StoryFn = () => ( <DemarcheEtape - titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} + titre={{ titreStatutId: 'val', typeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_visibilite: 'Publique', - demarche_type_id: 'oct', + demarche_type_id: DEMARCHES_TYPES_IDS.Octroi, titulaireIds: [entrepriseIdValidator.parse('titulaire1'), entrepriseIdValidator.parse('titulaire2')], administrationsLocales: [], sdom_zones: [], @@ -334,7 +338,8 @@ export const DemandeMultipleEntreprisesDocuments: StoryFn = () => ( demarche={{ demarche_visibilite: 'Publique', demarche_type_id: 'oct', - id: demarcheIdValidator.parse('demarcheId'), + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), + id: demarcheId, demarche_statut_id: DemarchesStatutsIds.EnInstruction, titulaireIds: [entrepriseIdValidator.parse('titulaire1'), entrepriseIdValidator.parse('titulaire2')], administrationsLocales: [], @@ -417,7 +422,8 @@ export const DemandeNoMap: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), + id: demarcheId, demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -485,7 +491,8 @@ export const DemandeNonDeposable: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [], @@ -532,7 +539,8 @@ export const DemandeNonSupprimable: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -617,8 +625,9 @@ export const DemandeArmMecaniseNonDeposable: StoryFn = () => ( <DemarcheEtape titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ + id: demarcheId, demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -715,7 +724,8 @@ export const DemandeArmMecaniseDeposable: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -816,7 +826,8 @@ export const DemandeArmNonMecaniseDeposable: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -877,7 +888,8 @@ export const Depot: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -912,7 +924,8 @@ export const AvisDefavorable: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [], @@ -966,7 +979,8 @@ export const DemandeAvecSeulementPerimetre: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [], @@ -1045,7 +1059,8 @@ export const DemandeAvecGrosseNote: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [], @@ -1106,7 +1121,8 @@ export const AxmDeposableAvecDaeEtAsl: StoryFn = () => ( titre={{ titreStatutId: 'dmi', typeId: 'axm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -1232,7 +1248,8 @@ export const DemandeAvecForage: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'pxg', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_D_EXPLOITATION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [], @@ -1303,7 +1320,8 @@ export const AvisDesServices: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -1338,7 +1356,8 @@ export const AvisDesServicesSansTelechargerToutLesDocuments: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -1392,7 +1411,8 @@ export const EtapeAvecNoteAvertissement: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), + id: demarcheId, demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -1426,8 +1446,9 @@ export const DemandeDeComplement: StoryFn = () => ( <DemarcheEtape titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ + id: demarcheId, demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -1481,8 +1502,9 @@ export const DemandeDeConsentement: StoryFn = () => ( <DemarcheEtape titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ + id: demarcheId, demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -1535,7 +1557,8 @@ export const DemandeDeComplementEntreprise: StoryFn = () => ( titre={{ titreStatutId: 'val', typeId: 'arm', nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: 'oct', titulaireIds: [entrepriseIdValidator.parse('titulaire1')], @@ -1605,7 +1628,8 @@ export const EtapeSimple: StoryFn = () => ( titre={{ titreStatutId: TitresStatutIds.Valide, typeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, nom: 'nom du titre', slug: titreSlug, titre_visibilite: 'Publique' }} demarche={{ demarche_visibilite: 'Publique', - id: demarcheIdValidator.parse('demarcheId'), + id: demarcheId, + machineInfo: MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDate), demarche_statut_id: DemarchesStatutsIds.EnInstruction, demarche_type_id: DEMARCHES_TYPES_IDS.Octroi, titulaireIds: [entrepriseIdValidator.parse('titulaire1')], diff --git a/packages/ui/src/components/demarche/demarche-etape.tsx b/packages/ui/src/components/demarche/demarche-etape.tsx index 4201d4ef4008c486e5bbb9dda9810375ea4fdc03..6257e9e3c4a21fea418c5a6661586776e8912a1a 100644 --- a/packages/ui/src/components/demarche/demarche-etape.tsx +++ b/packages/ui/src/components/demarche/demarche-etape.tsx @@ -10,11 +10,11 @@ import { EtapeStatut } from '../_common/etape-statut' import { PropDuree } from '../etape/prop-duree' import { SubstancesLegale } from 'camino-common/src/static/substancesLegales' import { EtapePropEntreprisesItem, EtapePropItem } from '../etape/etape-prop-item' -import { DemarcheEtape as CommonDemarcheEtape, DemarcheConsentement, demarcheEnregistrementDemandeDateFind, DemarcheId } from 'camino-common/src/demarche' +import { DemarcheEtape as CommonDemarcheEtape, DemarcheConsentement, DemarcheId } from 'camino-common/src/demarche' import { DsfrPerimetre, TabId } from '../_common/dsfr-perimetre' import { TitreSlug } from 'camino-common/src/validators/titres' import { numberFormat } from 'camino-common/src/number' -import { OmitDistributive, getValues, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefined } from 'camino-common/src/typescript-tools' +import { OmitDistributive, getValues, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools' import { ElementWithValue, valeurFind } from 'camino-common/src/sections' import { EtapeDocuments } from '../etape/etape-documents' import { isEntrepriseOrBureauDEtude, User } from 'camino-common/src/roles' @@ -50,6 +50,7 @@ import { LoadingElement } from '../_ui/functional-loader' import { useState } from '@/utils/vue-tsx-utils' import { fr } from '@codegouvfr/react-dsfr' import { EtapeVisibilite } from '../_common/etape-visibilite' +import { MachineInfo } from 'camino-common/src/machines' // Il ne faut pas utiliser de literal dans le 'in' il n'y aura jamais d'erreur typescript const fondamentalePropsName = 'fondamentale' @@ -65,6 +66,7 @@ type Props = { sdom_zones: SDOMZoneId[] communes: CommuneId[] etapes: TitreGetDemarche['etapes'] + machineInfo: MachineInfo } titre: { typeId: TitreTypeId @@ -157,7 +159,8 @@ export const DemarcheEtape = defineComponent<Props>(props => { const perimetre = getMostRecentValuePropFromEtapeFondamentale('perimetre', [{ ...props.demarche, ordre: 0 }]) const substances = getMostRecentValuePropFromEtapeFondamentale('substances', [{ ...props.demarche, ordre: 0 }]) const duree = getMostRecentValuePropFromEtapeFondamentale('duree', [{ ...props.demarche, ordre: 0 }]) - const sections = getSections(props.titre.typeId, props.demarche.demarche_type_id, props.etape.etape_type_id) + + const sections = getSections(props.demarche.machineInfo, props.etape.etape_type_id) const sortedEtapes = [...props.demarche.etapes].sort((a, b) => b.ordre - a.ordre) const contenu: FlattenEtape['contenu'] = {} @@ -179,16 +182,10 @@ export const DemarcheEtape = defineComponent<Props>(props => { }) }) - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(props.demarche.etapes.map(({ date, etape_type_id }) => ({ date, typeId: etape_type_id }))) - if (isNullOrUndefined(firstEtapeDate)) { - return false - } - return canDeposeEtape( props.user, - { typeId: props.titre.typeId, titreStatutId: props.titre.titreStatutId, titulaires: props.demarche.titulaireIds, administrationsLocales: props.demarche.administrationsLocales }, - props.demarche.id, - props.demarche.demarche_type_id, + props.demarche.machineInfo, + { titreStatutId: props.titre.titreStatutId, titulaires: props.demarche.titulaireIds, administrationsLocales: props.demarche.administrationsLocales }, { amodiataires: { value: amodiataireIds ?? [], heritee: false, etapeHeritee: null }, titulaires: { value: titulaireIds ?? [], heritee: false, etapeHeritee: null }, @@ -219,8 +216,7 @@ export const DemarcheEtape = defineComponent<Props>(props => { props.etape.entreprises_documents, props.demarche.sdom_zones, props.demarche.communes, - props.etape.avis_documents, - firstEtapeDate + props.etape.avis_documents ) }) @@ -446,7 +442,7 @@ export const DemarcheEtape = defineComponent<Props>(props => { class="fr-pt-2w" initTab={props.initTab} titreSlug={props.titre.slug} - titreTypeId={props.titre.typeId} + machineInfo={props.demarche.machineInfo} id={props.etape.id} calculateNeighbours={false} perimetre={{ diff --git a/packages/ui/src/components/demarche/demarche-map.tsx b/packages/ui/src/components/demarche/demarche-map.tsx index d975cd41862194c3f69884edd7e8935e5c5db808..5b6ea10e5120168e64b06bcd2eb33cb58df12267 100644 --- a/packages/ui/src/components/demarche/demarche-map.tsx +++ b/packages/ui/src/components/demarche/demarche-map.tsx @@ -8,7 +8,7 @@ import { TitreApiClient } from '../titre/titre-api-client' import { TitreWithPerimetre } from '../titres/mapUtil' import { isNotNullNorUndefined, isNullOrUndefined } from 'camino-common/src/typescript-tools' import { couleurParDomaine } from '../_common/domaine' -import { TitreTypeId, getDomaineId } from 'camino-common/src/static/titresTypes' +import { getDomaineId } from 'camino-common/src/static/titresTypes' import { canHaveForages } from 'camino-common/src/permissions/titres' import { capitalize } from 'camino-common/src/strings' import { CaminoLngLatBounds, CaminoMapLibre, CaminoStyleSpecification } from '@/typings/maplibre-gl' @@ -32,6 +32,7 @@ import { titresValidesLineName, } from './demarche-map-layer-controls' import { CaminoRouter } from '@/typings/vue-router' +import { MachineInfo } from 'camino-common/src/machines' type Props = { id: string @@ -39,7 +40,7 @@ type Props = { maxMarkers: number style?: HTMLAttributes['style'] class?: HTMLAttributes['class'] - titreTypeId: TitreTypeId + machineInfo: MachineInfo neighbours: { apiClient: Pick<TitreApiClient, 'getTitresWithPerimetreForCarte'> titreSlug: TitreSlug @@ -253,7 +254,7 @@ export const DemarcheMap = defineComponent<Props>(props => { values.push('Points') } - if (canHaveForages(props.titreTypeId)) { + if (canHaveForages(props.machineInfo)) { values.push('Forages') } @@ -567,7 +568,7 @@ export const DemarcheMap = defineComponent<Props>(props => { if (isNullOrUndefined(props.neighbours) && name === 'Titres valides') { return false } - if (!canHaveForages(props.titreTypeId) && name === 'Forages') { + if (!canHaveForages(props.machineInfo) && name === 'Forages') { return false } @@ -589,4 +590,4 @@ export const DemarcheMap = defineComponent<Props>(props => { ) }) // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 -DemarcheMap.props = ['id', 'perimetre', 'class', 'style', 'maxMarkers', 'neighbours', 'router', 'titreTypeId'] +DemarcheMap.props = ['id', 'perimetre', 'class', 'style', 'maxMarkers', 'neighbours', 'router', 'machineInfo'] diff --git a/packages/ui/src/components/etape-edition.stories.tsx b/packages/ui/src/components/etape-edition.stories.tsx index f1740055a2cce96094bf565985894ad60b330fa8..9f2ff0106af3457f298aad37be6d1a05a90723f3 100644 --- a/packages/ui/src/components/etape-edition.stories.tsx +++ b/packages/ui/src/components/etape-edition.stories.tsx @@ -284,6 +284,7 @@ const apiClient: Props['apiClient'] = { demarche_type_id: 'oct', demarche_description: 'Super description', demarche_id: demarcheId, + machine_id: 'AncienLogigrammeOctroiARM', titre_id: titreIdValidator.parse('titre-id'), titre_slug: titreSlugValidator.parse('titre-slug'), @@ -305,6 +306,7 @@ const apiClient: Props['apiClient'] = { titre_nom: 'Nom du titre', titre_slug: titreSlugValidator.parse('titre-slug'), titre_type_id: 'arm', + machine_id: null, first_etape_date: firstEtapeDateValidator.parse('2022-01-01'), }) }, @@ -396,6 +398,7 @@ export const AffichageAide: StoryFn = () => ( titre_nom: 'Nom du titre', titre_type_id: 'arm', first_etape_date: firstEtapeDateValidator.parse('2022-01-01'), + machine_id: 'AncienLogigrammeOctroiARM', }, }) }, @@ -582,6 +585,7 @@ export const DemandeArmComplete: StoryFn = () => ( heritageContenu: {}, }, demarche: { + machine_id: 'AncienLogigrammeOctroiARM', demarche_id: demarcheId, demarche_slug: demarcheSlugValidator.parse('demarche-slug'), demarche_type_id: 'oct', @@ -751,6 +755,7 @@ export const ModificationDemandeHeritee: StoryFn = () => ( }, }, demarche: { + machine_id: null, demarche_id: demarcheIdValidator.parse('demarche-id'), demarche_type_id: demarcheTypeIdValidator.parse('oct'), demarche_slug: demarcheSlugValidator.parse('demarche-slug'), @@ -875,6 +880,7 @@ export const AxmEnZoneDuSdom: StoryFn = () => ( heritageContenu: {}, }, demarche: { + machine_id: 'AncienLogigrammeOctroiAXM', demarche_id: demarcheIdValidator.parse('demarche-id'), demarche_type_id: demarcheTypeIdValidator.parse('oct'), demarche_slug: demarcheSlugValidator.parse('demarche-slug'), @@ -894,3 +900,26 @@ export const AxmEnZoneDuSdom: StoryFn = () => ( etapeIdOrSlug={etapeIdOrSlugValidator.parse('etape-id')} /> ) + +export const Loading: StoryFn = () => ( + <PureEtapeEdition + goToDemarche={goToDemarcheAction} + entreprises={entreprises} + apiClient={{ ...apiClient, getEtape: () => new Promise(() => ({})) }} + user={{ ...testBlankUser, role: 'super' }} + initTab="points" + demarcheIdOrSlug={null} + etapeIdOrSlug={etapeIdOrSlugValidator.parse('etape-id')} + /> +) +export const WithError: StoryFn = () => ( + <PureEtapeEdition + goToDemarche={goToDemarcheAction} + entreprises={entreprises} + apiClient={{ ...apiClient, getEtape: () => Promise.resolve({ message: 'Une erreur' }) }} + user={{ ...testBlankUser, role: 'super' }} + initTab="points" + demarcheIdOrSlug={null} + etapeIdOrSlug={etapeIdOrSlugValidator.parse('etape-id')} + /> +) diff --git a/packages/ui/src/components/etape-edition.stories_snapshots_Loading.html b/packages/ui/src/components/etape-edition.stories_snapshots_Loading.html new file mode 100644 index 0000000000000000000000000000000000000000..e3387ed783456c0271d6424e9d9580a0222a2f39 --- /dev/null +++ b/packages/ui/src/components/etape-edition.stories_snapshots_Loading.html @@ -0,0 +1,7 @@ +<div> + <div class="_top-level_3306d0" style="display: flex; justify-content: center;"> + <!----> + <!----> + <div class="_spinner_3306d0"></div> + </div> +</div> \ No newline at end of file diff --git a/packages/ui/src/components/etape-edition.stories_snapshots_WithError.html b/packages/ui/src/components/etape-edition.stories_snapshots_WithError.html new file mode 100644 index 0000000000000000000000000000000000000000..e7848acc658cb6f7d843e97e3375709d0e7b325b --- /dev/null +++ b/packages/ui/src/components/etape-edition.stories_snapshots_WithError.html @@ -0,0 +1,9 @@ +<div> + <div class="" style="display: flex; justify-content: center;"> + <!----> + <div class="fr-alert fr-alert--error fr-alert--sm" role="alert"> + <p>Une erreur</p> + </div> + <!----> + </div> +</div> \ No newline at end of file diff --git a/packages/ui/src/components/etape-edition.tsx b/packages/ui/src/components/etape-edition.tsx index 65b9cedd6027e7b8c2ac4ef8bc18d5127e575f18..e4d089e6449f76553e19e0650cefbbb284a481a2 100644 --- a/packages/ui/src/components/etape-edition.tsx +++ b/packages/ui/src/components/etape-edition.tsx @@ -20,6 +20,7 @@ import { capitalize } from 'camino-common/src/strings' import { EtapeEditForm, Props as EtapeEditFormProps } from './etape/etape-edit-form' import { TitreTypeId } from 'camino-common/src/static/titresTypes' import { CaminoAccessError } from './error' +import { MachineInfo } from 'camino-common/src/machines' export const EtapeEdition = defineComponent(() => { const router = useRouter() @@ -84,7 +85,7 @@ const helpVisible = (user: User, titreTypeId: TitreTypeId, etapeTypeId: EtapeTyp } export const PureEtapeEdition = defineComponent<Props>(props => { - const [asyncData, setAsyncData] = useState<AsyncData<{ etape: EtapeEditFormProps['etape']; demarche: GetDemarcheByIdOrSlug; perimetre: PerimetreInformations }>>({ + const [asyncData, setAsyncData] = useState<AsyncData<{ etape: EtapeEditFormProps['etape']; demarche: GetDemarcheByIdOrSlug; perimetre: PerimetreInformations; machineInfo: MachineInfo }>>({ status: 'LOADING', }) @@ -100,7 +101,12 @@ export const PureEtapeEdition = defineComponent<Props>(props => { if ('message' in perimetre) { setAsyncData({ status: 'NEW_ERROR', error: perimetre }) } else { - setAsyncData({ status: 'LOADED', value: { etape, demarche, perimetre } }) + const machineInfo = MachineInfo.withMachineId(demarche.titre_type_id, demarche.demarche_type_id, demarche.demarche_id, demarche.machine_id) + if (!machineInfo.valid) { + setAsyncData({ status: 'NEW_ERROR', error: { message: machineInfo.error } }) + } else { + setAsyncData({ status: 'LOADED', value: { etape, demarche, perimetre, machineInfo: machineInfo.value } }) + } } } } else if (isNotNullNorUndefined(props.demarcheIdOrSlug)) { @@ -112,31 +118,37 @@ export const PureEtapeEdition = defineComponent<Props>(props => { if ('message' in perimetre) { setAsyncData({ status: 'NEW_ERROR', error: perimetre }) } else { - setAsyncData({ - status: 'LOADED', - value: { - etape: { - id: null, - contenu: {}, - date: null, - typeId: null, - statutId: null, - isBrouillon: ETAPE_IS_NOT_BROUILLON, - note: { valeur: '', is_avertissement: false }, - substances: { value: [], heritee: true, etapeHeritee: null }, - titulaires: { value: [], heritee: true, etapeHeritee: null }, - amodiataires: { value: [], heritee: true, etapeHeritee: null }, - perimetre: { value: null, heritee: true, etapeHeritee: null }, - duree: { value: null, heritee: true, etapeHeritee: null }, - dateDebut: { value: null, heritee: true, etapeHeritee: null }, - dateFin: { value: null, heritee: true, etapeHeritee: null }, - slug: null, - titreDemarcheId: demarche.demarche_id, + const machineInfo = MachineInfo.withMachineId(demarche.titre_type_id, demarche.demarche_type_id, demarche.demarche_id, demarche.machine_id) + if (!machineInfo.valid) { + setAsyncData({ status: 'NEW_ERROR', error: { message: machineInfo.error } }) + } else { + setAsyncData({ + status: 'LOADED', + value: { + etape: { + id: null, + contenu: {}, + date: null, + typeId: null, + statutId: null, + isBrouillon: ETAPE_IS_NOT_BROUILLON, + note: { valeur: '', is_avertissement: false }, + substances: { value: [], heritee: true, etapeHeritee: null }, + titulaires: { value: [], heritee: true, etapeHeritee: null }, + amodiataires: { value: [], heritee: true, etapeHeritee: null }, + perimetre: { value: null, heritee: true, etapeHeritee: null }, + duree: { value: null, heritee: true, etapeHeritee: null }, + dateDebut: { value: null, heritee: true, etapeHeritee: null }, + dateFin: { value: null, heritee: true, etapeHeritee: null }, + slug: null, + titreDemarcheId: demarche.demarche_id, + }, + demarche, + perimetre, + machineInfo: machineInfo.value, }, - demarche, - perimetre, - }, - }) + }) + } } } } @@ -161,7 +173,7 @@ export const PureEtapeEdition = defineComponent<Props>(props => { <div> <LoadingElement data={asyncData.value} - renderItem={({ etape, demarche, perimetre }) => ( + renderItem={({ etape, demarche, perimetre, machineInfo }) => ( <> <div> <DsfrLink to={{ name: 'titre', params: { id: demarche.titre_slug } }} disabled={false} title={demarche.titre_nom} icon={null} /> @@ -198,11 +210,8 @@ export const PureEtapeEdition = defineComponent<Props>(props => { <EtapeEditForm initTab={props.initTab} etape={etape} - demarcheId={demarche.demarche_id} - demarcheTypeId={demarche.demarche_type_id} + machineInfo={machineInfo} titreSlug={demarche.titre_slug} - titreTypeId={demarche.titre_type_id} - firstEtapeDate={demarche.first_etape_date} user={props.user} entreprises={props.entreprises} apiClient={props.apiClient} diff --git a/packages/ui/src/components/etape/entreprises-documents-edit.stories.tsx b/packages/ui/src/components/etape/entreprises-documents-edit.stories.tsx index faddd92d365a5bc631d7a24a75fd21a77254a647..21b141681f9710b3b8bf666c941bbf68a1cecfdc 100644 --- a/packages/ui/src/components/etape/entreprises-documents-edit.stories.tsx +++ b/packages/ui/src/components/etape/entreprises-documents-edit.stories.tsx @@ -2,9 +2,11 @@ import { Meta, StoryFn } from '@storybook/vue3' import { EntrepriseDocumentsEdit } from './entreprises-documents-edit' import { action } from '@storybook/addon-actions' import { EntrepriseDocument, entrepriseDocumentIdValidator, newEntrepriseId, toEntrepriseDocumentId } from 'camino-common/src/entreprise' -import { toCaminoDate } from 'camino-common/src/date' +import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' import { etapeIdValidator } from 'camino-common/src/etape' import { tempDocumentNameValidator } from 'camino-common/src/document' +import { MachineInfo } from 'camino-common/src/machines' +import { demarcheIdValidator } from 'camino-common/src/demarche' const meta: Meta = { title: 'Components/Etape/EditionEntreprisesDocuments', @@ -18,9 +20,11 @@ const getEntrepriseDocumentsAction = action('getEntrepriseDocuments') const completeUpdateAction = action('completeUpdate') const getEtapeEntrepriseDocumentsAction = action('getEtapeEntrepriseDocuments') const uploadTempDocumentAction = action('uploadTempDocumentAction') +const demarcheId = demarcheIdValidator.parse('demarcheId') +const firstEtapeDate = firstEtapeDateValidator.parse('2020-01-01') export const Loading: StoryFn = () => ( <EntrepriseDocumentsEdit - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr' }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} apiClient={{ creerEntrepriseDocument: async (entrepriseId, entrepriseDocumentInput) => { creerEntrepriseDocumentAction(entrepriseId, entrepriseDocumentInput) @@ -48,7 +52,7 @@ export const Loading: StoryFn = () => ( export const ArmUneEntrepriseSansDocumentDEntreprise: StoryFn = () => ( <EntrepriseDocumentsEdit - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr' }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} apiClient={{ creerEntrepriseDocument: async (entrepriseId, entrepriseDocumentInput) => { creerEntrepriseDocumentAction(entrepriseId, entrepriseDocumentInput) @@ -147,7 +151,7 @@ export const ArmUneEntrepriseSansDocumentDEntreprise: StoryFn = () => ( export const ArmUneEntrepriseAvecDocumentDEntrepriseComplet: StoryFn = () => ( <EntrepriseDocumentsEdit - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr' }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} apiClient={{ creerEntrepriseDocument: async (entrepriseId, entrepriseDocumentInput) => { creerEntrepriseDocumentAction(entrepriseId, entrepriseDocumentInput) @@ -295,7 +299,7 @@ export const ArmUneEntrepriseAvecDocumentDEntrepriseComplet: StoryFn = () => ( export const AxmDeuxEntreprisesDocumentDEntrepriseComplet: StoryFn = () => ( <EntrepriseDocumentsEdit - tde={{ titreTypeId: 'axm', demarcheTypeId: 'oct', etapeTypeId: 'mfr' }} + tde={{ machineInfo: MachineInfo.withDate('axm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} apiClient={{ creerEntrepriseDocument: async (entrepriseId, entrepriseDocumentInput) => { creerEntrepriseDocumentAction(entrepriseId, entrepriseDocumentInput) @@ -450,7 +454,7 @@ export const AxmDeuxEntreprisesDocumentDEntrepriseComplet: StoryFn = () => ( export const ArmDocumentOptionnel: StoryFn = () => ( <EntrepriseDocumentsEdit - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mod' }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mod' }} apiClient={{ creerEntrepriseDocument: async (entrepriseId, entrepriseDocumentInput) => { creerEntrepriseDocumentAction(entrepriseId, entrepriseDocumentInput) @@ -492,7 +496,7 @@ export const ArmDocumentOptionnel: StoryFn = () => ( export const ErreurDeChargementDesDocuments: StoryFn = () => ( <EntrepriseDocumentsEdit - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mod' }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mod' }} apiClient={{ creerEntrepriseDocument: async (entrepriseId, entrepriseDocumentInput) => { creerEntrepriseDocumentAction(entrepriseId, entrepriseDocumentInput) diff --git a/packages/ui/src/components/etape/entreprises-documents-edit.tsx b/packages/ui/src/components/etape/entreprises-documents-edit.tsx index 4973f9c84737b628033678d36a1789b2fa0057be..7f027036d83d76ed265d9977ca11963ade35ef45 100644 --- a/packages/ui/src/components/etape/entreprises-documents-edit.tsx +++ b/packages/ui/src/components/etape/entreprises-documents-edit.tsx @@ -5,8 +5,6 @@ import { DocumentsTypes, EntrepriseDocumentType, EntrepriseDocumentTypeId } from import { getEntries, getEntriesHardcore, getKeys, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefined, map, stringArrayEquals } from 'camino-common/src/typescript-tools' import { AddEntrepriseDocumentPopup } from '../entreprise/add-entreprise-document-popup' import { AsyncData, getDownloadRestRoute } from '@/api/client-rest' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' -import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' import { EtapeTypeId } from 'camino-common/src/static/etapesTypes' import { getEntrepriseDocuments } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/entrepriseDocuments' import { EtapeId } from 'camino-common/src/etape' @@ -19,13 +17,13 @@ import { SelectedEntrepriseDocument } from 'camino-common/src/permissions/etape- import { Column, TableSimple } from '../_ui/table-simple' import { TableRow } from '../_ui/table' import { fr } from '@codegouvfr/react-dsfr' +import { MachineInfo } from 'camino-common/src/machines' type Entreprise = { id: EntrepriseId; nom: string } interface Props { tde: { - titreTypeId: TitreTypeId - demarcheTypeId: DemarcheTypeId + machineInfo: MachineInfo etapeTypeId: EtapeTypeId } completeUpdate: (etapeEntrepriseDocuments: SelectedEntrepriseDocument[]) => void @@ -98,7 +96,7 @@ const InternalEntrepriseDocumentsEdit = defineComponent<Props & { etapeEntrepris }, {}) }) const tdeEntrepriseDocuments = computed<EntrepriseDocumentType[]>(() => { - return getEntrepriseDocuments(props.tde.titreTypeId, props.tde.demarcheTypeId, props.tde.etapeTypeId) + return getEntrepriseDocuments(props.tde.machineInfo, props.tde.etapeTypeId) }) const entrepriseDocuments = ref<AsyncData<{ [key in EntrepriseId]?: EntrepriseDocument[] }>>({ status: 'LOADING' }) diff --git a/packages/ui/src/components/etape/etape-api-client.ts b/packages/ui/src/components/etape/etape-api-client.ts index 7f4ab41a83838ddcb6311252d71a35c399c0ecf8..fccc8be9beb5607135953d527a3b1f44e60ff4da 100644 --- a/packages/ui/src/components/etape/etape-api-client.ts +++ b/packages/ui/src/components/etape/etape-api-client.ts @@ -109,7 +109,6 @@ export const etapeApiClient: EtapeApiClient = { if ('message' in demarche) { return demarche } - return { etape, demarche } }, getEtapeHeritagePotentiel: async (etape, titreDemarcheId) => { diff --git a/packages/ui/src/components/etape/etape-avis-edit.stories.tsx b/packages/ui/src/components/etape/etape-avis-edit.stories.tsx index 0497e138b4352258c3eac6685443bd61b04aa265..16663f9647c00a721b85affd01de6f8bc81560b4 100644 --- a/packages/ui/src/components/etape/etape-avis-edit.stories.tsx +++ b/packages/ui/src/components/etape/etape-avis-edit.stories.tsx @@ -9,6 +9,7 @@ import { AvisVisibilityIds } from 'camino-common/src/static/avisTypes' import { testBlankUser } from 'camino-common/src/tests-utils' import { communeIdValidator } from 'camino-common/src/static/communes' import { demarcheIdValidator } from 'camino-common/src/demarche' +import { MachineInfo } from 'camino-common/src/machines' const meta: Meta = { title: 'Components/Etape/EtapeAvisEdit', @@ -56,13 +57,14 @@ const apiClient: Pick<ApiClient, 'uploadTempDocument' | 'getEtapeAvisByEtapeId'> } const completeUpdateAction = action('completeUpdate') - +const demarcheId = demarcheIdValidator.parse('demarcheId') +const firstEtapeDate = firstEtapeDateValidator.parse('2022-01-01') export const Empty: StoryFn = () => ( <EtapeAvisEdit apiClient={{ ...apiClient, getEtapeAvisByEtapeId: () => Promise.resolve([]) }} etapeId={etapeIdValidator.parse('etapeId')} communeIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId: demarcheIdValidator.parse('demarcheId'), firstEtapeDate: firstEtapeDateValidator.parse('2022-01-01') }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} onChange={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} contenu={{}} @@ -73,7 +75,7 @@ export const Rempli: StoryFn = () => ( apiClient={apiClient} etapeId={etapeIdValidator.parse('etapeId')} communeIds={[]} - tde={{ titreTypeId: 'axm', demarcheTypeId: 'oct', etapeTypeId: 'asc', demarcheId: demarcheIdValidator.parse('demarcheId'), firstEtapeDate: firstEtapeDateValidator.parse('2022-01-01') }} + tde={{ machineInfo: MachineInfo.withDate('axm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'asc' }} onChange={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} contenu={{}} @@ -84,7 +86,7 @@ export const DemandeARMProcedureSpecifique: StoryFn = () => ( apiClient={apiClient} etapeId={etapeIdValidator.parse('etapeId')} communeIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId: demarcheIdValidator.parse('demarcheId'), firstEtapeDate: firstEtapeDateValidator.parse('2025-01-01') }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse('2025-01-01')), etapeTypeId: 'mfr' }} onChange={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} contenu={{ arm: { mecanise: { value: true, heritee: false, etapeHeritee: null } } }} @@ -111,7 +113,7 @@ export const AvisEnGuyane: StoryFn = () => ( }} etapeId={etapeIdValidator.parse('etapeId')} communeIds={[communeIdValidator.parse('97302')]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'asc', demarcheId: demarcheIdValidator.parse('demarcheId'), firstEtapeDate: firstEtapeDateValidator.parse('2022-01-01') }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'asc' }} onChange={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} contenu={{}} diff --git a/packages/ui/src/components/etape/etape-avis-edit.tsx b/packages/ui/src/components/etape/etape-avis-edit.tsx index ed976f7639412bd4a9b75b7e2fd58572d4656d44..8cc0c061a2587ae6e7d8b8450d5d974469f140ed 100644 --- a/packages/ui/src/components/etape/etape-avis-edit.tsx +++ b/packages/ui/src/components/etape/etape-avis-edit.tsx @@ -1,7 +1,5 @@ import { EtapeAvis, EtapeAvisModification, EtapeId, TempEtapeAvis } from 'camino-common/src/etape' -import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' import { EtapeTypeId } from 'camino-common/src/static/etapesTypes' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' import { ApiClient } from '../../api/api-client' import { FunctionalComponent, computed, defineComponent, onMounted, ref, watch } from 'vue' import { isNonEmptyArray, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefined, NonEmptyArray } from 'camino-common/src/typescript-tools' @@ -9,13 +7,12 @@ import { LoadingElement } from '../_ui/functional-loader' import { AsyncData, asyncDataAutomaticLoad } from '../../api/client-rest' import { DsfrButtonIcon } from '../_ui/dsfr-button' import { AddEtapeAvisPopup } from './add-etape-avis-popup' -import { dateFormat, FirstEtapeDate } from 'camino-common/src/date' +import { dateFormat } from 'camino-common/src/date' import { AvisStatut } from '../_common/etape-statut' import { AvisTypeId, getAvisNom } from 'camino-common/src/static/avisTypes' import { CommuneId } from 'camino-common/src/static/communes' import { getAvisVisibilityLabel } from './etape-avis' import { User } from 'camino-common/src/roles' -import { DemarcheId } from 'camino-common/src/demarche' import { FlattenedContenu } from 'camino-common/src/etape-form' import { capitalize } from 'camino-common/src/strings' import { fr } from '@codegouvfr/react-dsfr' @@ -24,14 +21,12 @@ import { TableRow } from '../_ui/table' import { getAvisTypes } from 'camino-common/src/avisTypes' import { isArmMecanise } from 'camino-common/src/static/mecanise' import { useState } from '@/utils/vue-tsx-utils' +import { MachineInfo } from 'camino-common/src/machines' interface Props { tde: { - titreTypeId: TitreTypeId - demarcheTypeId: DemarcheTypeId etapeTypeId: EtapeTypeId - demarcheId: DemarcheId - firstEtapeDate: FirstEtapeDate + machineInfo: MachineInfo } onChange: (etapeAvis: (EtapeAvis | TempEtapeAvis)[]) => void etapeId: EtapeId | null @@ -78,9 +73,7 @@ const EtapeAvisLoaded = defineComponent<EtapeAvisLoadedProps>(props => { const addOrEditPopupOpen = ref<{ open: true; required: boolean; avisTypeIds: NonEmptyArray<AvisTypeId>; etapeAvis?: (EtapeAvis | TempEtapeAvis) & WithIndex } | { open: false }>({ open: false }) const avisTypes = computed(() => { - return Object.values( - getAvisTypes(props.tde.etapeTypeId, props.tde.titreTypeId, props.tde.demarcheTypeId, props.tde.demarcheId, props.tde.firstEtapeDate, props.communeIds, isArmMecanise(props.contenu)) - ) + return Object.values(getAvisTypes(props.tde.etapeTypeId, props.tde.machineInfo, props.communeIds, isArmMecanise(props.contenu))) }) const completeRequiredAvis = computed<PropsTable['avis']>(() => { diff --git a/packages/ui/src/components/etape/etape-documents-edit.stories.tsx b/packages/ui/src/components/etape/etape-documents-edit.stories.tsx index 28c6969e7e894ead0ab46e41684ad145c417ee14..a899fed96ef75cd53cea42ba366d18bfc9e1a724 100644 --- a/packages/ui/src/components/etape/etape-documents-edit.stories.tsx +++ b/packages/ui/src/components/etape/etape-documents-edit.stories.tsx @@ -9,6 +9,7 @@ import { useArgs } from '@storybook/preview-api' import { entrepriseIdValidator } from 'camino-common/src/entreprise' import { demarcheIdValidator } from 'camino-common/src/demarche' import { firstEtapeDateValidator } from 'camino-common/src/date' +import { MachineInfo } from 'camino-common/src/machines' const meta: Meta = { title: 'Components/Etape/EtapeDocumentsEdit', @@ -79,7 +80,7 @@ export const Empty: StoryFn = () => ( contenu={{}} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_NOT_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} @@ -91,7 +92,7 @@ export const Rempli: StoryFn = () => ( contenu={{}} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_NOT_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} @@ -151,7 +152,7 @@ export const Complet: StoryFn = () => ( contenu={{}} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_NOT_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} @@ -211,7 +212,7 @@ export const CompletAvecDocumentNonRenseigne: StoryFn = () => ( contenu={{}} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_NOT_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} @@ -224,7 +225,7 @@ export const ArmMecanise: StoryFn = () => ( contenu={{ arm: { mecanise: { value: true, heritee: false, etapeHeritee: null } } }} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_NOT_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'admin', administrationId: 'dea-guyane-01' }} @@ -243,7 +244,7 @@ export const ArmMecaniseDynamicNoSnapshot: StoryObj<{ mecanise: boolean }> = { contenu={{ arm: { mecanise: { value: args.mecanise, heritee: false, etapeHeritee: null } } }} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_NOT_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} @@ -262,7 +263,7 @@ export const EnConstruction: StoryFn = () => ( contenu={{ arm: { mecanise: { value: true, heritee: false, etapeHeritee: null } } }} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} @@ -274,7 +275,7 @@ export const OctroiAxmUtilisateurSuper: StoryFn = () => ( contenu={{}} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'axm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('axm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} @@ -287,7 +288,7 @@ export const OctroiAxmUtilisateurEntreprise: StoryFn = () => ( contenu={{}} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'axm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('axm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'entreprise', entrepriseIds: [entrepriseIdValidator.parse('idEntreprise1')] }} @@ -350,7 +351,7 @@ export const OctroiAxmUtilisateurEntrepriseComplet: StoryFn = () => ( contenu={{}} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'axm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('axm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'entreprise', entrepriseIds: [entrepriseIdValidator.parse('idEntreprise1')] }} @@ -363,7 +364,7 @@ export const SdomZone: StoryFn = () => ( contenu={{ arm: { mecanise: { value: true, heritee: false, etapeHeritee: null } } }} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={['1', '2']} - tde={{ titreTypeId: 'axm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('axm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_NOT_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} @@ -376,7 +377,7 @@ export const PasDeDocumentsObligatoires: StoryFn = () => ( contenu={{}} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={['1', '2']} - tde={{ titreTypeId: 'prm', demarcheTypeId: 'pro', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('prm', 'pro', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_NOT_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} @@ -389,7 +390,7 @@ export const Loading: StoryFn = () => ( contenu={{}} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_NOT_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} @@ -401,7 +402,7 @@ export const WithError: StoryFn = () => ( contenu={{}} etapeId={etapeIdValidator.parse('etapeId')} sdomZoneIds={[]} - tde={{ titreTypeId: 'arm', demarcheTypeId: 'oct', etapeTypeId: 'mfr', demarcheId, firstEtapeDate }} + tde={{ machineInfo: MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate), etapeTypeId: 'mfr' }} isBrouillon={ETAPE_IS_NOT_BROUILLON} completeUpdate={completeUpdateAction} user={{ ...testBlankUser, role: 'super' }} diff --git a/packages/ui/src/components/etape/etape-documents-edit.tsx b/packages/ui/src/components/etape/etape-documents-edit.tsx index 8e973129d82d22404e32dea43731573d095fa9e5..e22275c942be8ecd4f9e57d9567bb45ec4603f9a 100644 --- a/packages/ui/src/components/etape/etape-documents-edit.tsx +++ b/packages/ui/src/components/etape/etape-documents-edit.tsx @@ -1,7 +1,5 @@ import { EtapeBrouillon, EtapeDocument, EtapeDocumentModification, EtapeId, GetEtapeDocumentsByEtapeId, TempEtapeDocument } from 'camino-common/src/etape' -import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' import { EtapeTypeId } from 'camino-common/src/static/etapesTypes' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' import { ApiClient } from '../../api/api-client' import { FunctionalComponent, computed, defineComponent, onMounted, ref, watch } from 'vue' import { SDOMZoneId } from 'camino-common/src/static/sdom' @@ -13,8 +11,6 @@ import { DsfrButtonIcon } from '../_ui/dsfr-button' import { getVisibilityLabel, sortDocumentsColumn } from './etape-documents' import { AddEtapeDocumentPopup } from './add-etape-document-popup' import { User } from 'camino-common/src/roles' -import { FirstEtapeDate } from 'camino-common/src/date' -import { DemarcheId } from 'camino-common/src/demarche' import { FlattenedContenu } from 'camino-common/src/etape-form' import { fr } from '@codegouvfr/react-dsfr' import { Column, TableSimple } from '../_ui/table-simple' @@ -22,14 +18,12 @@ import { TableRow } from '../_ui/table' import { getDocuments } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/documents' import { isArmMecanise } from 'camino-common/src/static/mecanise' import { useState } from '@/utils/vue-tsx-utils' +import { MachineInfo } from 'camino-common/src/machines' interface Props { tde: { - titreTypeId: TitreTypeId - demarcheTypeId: DemarcheTypeId etapeTypeId: EtapeTypeId - demarcheId: DemarcheId - firstEtapeDate: FirstEtapeDate + machineInfo: MachineInfo } isBrouillon: EtapeBrouillon sdomZoneIds: SDOMZoneId[] @@ -79,7 +73,7 @@ const EtapeDocumentsLoaded = defineComponent<EtapeDocumentsLoadedProps>(props => }) const documentTypes = computed<(DocumentType | AutreDocumentType)[]>(() => { - return getDocuments(props.tde.titreTypeId, props.tde.demarcheTypeId, props.tde.etapeTypeId, props.tde.firstEtapeDate, props.tde.demarcheId, props.sdomZoneIds, isArmMecanise(props.contenu)) + return getDocuments(props.tde.machineInfo, props.tde.etapeTypeId, props.sdomZoneIds, isArmMecanise(props.contenu)) }) const completeRequiredDocuments = computed<PropsTable['documents']>(() => { diff --git a/packages/ui/src/components/etape/etape-edit-form.stories.tsx b/packages/ui/src/components/etape/etape-edit-form.stories.tsx index 965a72cfe4f1ed0fae51f900cb0ac7258d12629d..3a83261a5bf2ef8c06773c16bbc37ad59a8b9f48 100644 --- a/packages/ui/src/components/etape/etape-edit-form.stories.tsx +++ b/packages/ui/src/components/etape/etape-edit-form.stories.tsx @@ -10,6 +10,7 @@ import { titreSlugValidator } from 'camino-common/src/validators/titres' import { FeatureMultiPolygon } from 'camino-common/src/perimetre' import { tempDocumentNameValidator } from 'camino-common/src/document' import { DOCUMENTS_TYPES_IDS } from 'camino-common/src/static/documentsTypes' +import { MachineInfo } from 'camino-common/src/machines' const meta: Meta = { title: 'Components/Etape/EditForm', @@ -231,16 +232,15 @@ const etapeEditFormApiClient: Props['apiClient'] = { return Promise.resolve({ id: entrepriseDocumentIdValidator.parse('entrepriseDocumentId') }) }, } - +const firstEtapeDate = firstEtapeDateValidator.parse('2022-01-01') +const demarcheId = demarcheIdValidator.parse('demarcheId') export const Default: StoryFn = () => ( <EtapeEditForm initTab="points" perimetre={{ sdomZoneIds: [], superposition_alertes: [], communes: [] }} apiClient={etapeEditFormApiClient} - demarcheId={demarcheIdValidator.parse('demarcheId')} - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlugValidator.parse('titre-slug')} - titreTypeId="arm" etape={{ ...etape, contenu: { arm: { mecanise: { value: true, heritee: false, etapeHeritee: null }, franchissements: { value: 2, heritee: false, etapeHeritee: null } } }, @@ -251,7 +251,6 @@ export const Default: StoryFn = () => ( }} entreprises={entreprises} goToDemarche={goToDemarcheAction} - firstEtapeDate={firstEtapeDateValidator.parse('2022-01-01')} /> ) @@ -412,10 +411,8 @@ export const EtapeCompleteEnregistrable: StoryFn = () => ( initTab="points" perimetre={{ sdomZoneIds: [], superposition_alertes: [], communes: [] }} apiClient={apiClientAvecDocumentsComplets} - demarcheId={demarcheIdValidator.parse('demarcheId')} - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlugValidator.parse('titre-slug')} - titreTypeId="arm" etape={{ ...etape, perimetre: { @@ -446,7 +443,6 @@ export const EtapeCompleteEnregistrable: StoryFn = () => ( }} entreprises={entreprises} goToDemarche={goToDemarcheAction} - firstEtapeDate={firstEtapeDateValidator.parse('2022-01-01')} /> ) @@ -505,10 +501,8 @@ export const EtapeCompleteEnregistrableAvecDocumentNonRenseigne: StoryFn = () => return Promise.resolve(values) }, }} - demarcheId={demarcheIdValidator.parse('demarcheId')} - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlugValidator.parse('titre-slug')} - titreTypeId="arm" etape={{ ...etape, perimetre: { @@ -539,7 +533,6 @@ export const EtapeCompleteEnregistrableAvecDocumentNonRenseigne: StoryFn = () => }} entreprises={entreprises} goToDemarche={goToDemarcheAction} - firstEtapeDate={firstEtapeDateValidator.parse('2022-01-01')} /> ) @@ -547,10 +540,8 @@ export const EtapeModification: StoryFn = () => ( <EtapeEditForm initTab="points" apiClient={etapeEditFormApiClient} - demarcheId={demarcheIdValidator.parse('demarcheId')} - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('cxw', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlugValidator.parse('titre-slug')} - titreTypeId="cxw" perimetre={{ sdomZoneIds: [], superposition_alertes: [], communes: [] }} etape={{ ...etape, @@ -576,7 +567,6 @@ export const EtapeModification: StoryFn = () => ( }} entreprises={entreprises} goToDemarche={goToDemarcheAction} - firstEtapeDate={firstEtapeDateValidator.parse('2022-01-01')} /> ) @@ -584,10 +574,8 @@ export const EtapeModificationAvis: StoryFn = () => ( <EtapeEditForm initTab="points" apiClient={etapeEditFormApiClient} - demarcheId={demarcheIdValidator.parse('demarcheId')} - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlugValidator.parse('titre-slug')} - titreTypeId="arm" perimetre={{ sdomZoneIds: [], superposition_alertes: [], communes: [] }} etape={{ ...etape, @@ -600,17 +588,14 @@ export const EtapeModificationAvis: StoryFn = () => ( }} entreprises={entreprises} goToDemarche={goToDemarcheAction} - firstEtapeDate={firstEtapeDateValidator.parse('2022-01-01')} /> ) export const EtapeDecisionAdministration: StoryFn = () => ( <EtapeEditForm initTab="points" apiClient={etapeEditFormApiClient} - demarcheId={demarcheIdValidator.parse('demarcheId')} - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('cxw', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlugValidator.parse('titre-slug')} - titreTypeId="cxw" perimetre={{ sdomZoneIds: [], superposition_alertes: [], communes: [] }} etape={{ ...etape, @@ -625,17 +610,14 @@ export const EtapeDecisionAdministration: StoryFn = () => ( }} entreprises={entreprises} goToDemarche={goToDemarcheAction} - firstEtapeDate={firstEtapeDateValidator.parse('2022-01-01')} /> ) export const EtapeConsultationAdministrationsCentrales: StoryFn = () => ( <EtapeEditForm initTab="points" apiClient={etapeEditFormApiClient} - demarcheId={demarcheIdValidator.parse('demarcheId')} - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('cxw', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlugValidator.parse('titre-slug')} - titreTypeId="cxw" perimetre={{ sdomZoneIds: [], superposition_alertes: [], communes: [] }} etape={{ ...etape, @@ -649,6 +631,5 @@ export const EtapeConsultationAdministrationsCentrales: StoryFn = () => ( }} entreprises={entreprises} goToDemarche={goToDemarcheAction} - firstEtapeDate={firstEtapeDateValidator.parse('2022-01-01')} /> ) diff --git a/packages/ui/src/components/etape/etape-edit-form.tsx b/packages/ui/src/components/etape/etape-edit-form.tsx index 9ce7e8bde0f56bf8ed1b1353b063e174a7e231b6..74955faca00bb421fc4431389ca5f558bac5e359 100644 --- a/packages/ui/src/components/etape/etape-edit-form.tsx +++ b/packages/ui/src/components/etape/etape-edit-form.tsx @@ -7,8 +7,7 @@ import { EtapeDocumentsEdit } from './etape-documents-edit' import { ApiClient } from '../../api/api-client' import { User } from 'camino-common/src/roles' import { ETAPE_IS_NOT_BROUILLON, EtapeAvis, EtapeDocument, EtapeId, TempEtapeAvis, TempEtapeDocument } from 'camino-common/src/etape' -import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' +import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes' import { TitreSlug } from 'camino-common/src/validators/titres' import { SDOMZoneIds, SDOMZones } from 'camino-common/src/static/sdom' import { Nullable, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools' @@ -39,30 +38,28 @@ import { import { EtapeAlerte, PureFormSaveBtn } from './pure-form-save-btn' import { TitresStatuts } from 'camino-common/src/static/titresStatuts' import { EtapeAvisEdit } from './etape-avis-edit' -import { EtapeTypeId, canBeBrouillon } from 'camino-common/src/static/etapesTypes' +import { ETAPES_TYPES, EtapeTypeId, canBeBrouillon } from 'camino-common/src/static/etapesTypes' import { CoreEtapeCreationOrModification, GetEtapeHeritagePotentiel } from './etape-api-client' import { FlattenedContenuElement, FlattenEtape, RestEtapeCreation } from 'camino-common/src/etape-form' import { AsyncData } from '@/api/client-rest' -import { CaminoDate, FirstEtapeDate, firstEtapeDateValidator } from 'camino-common/src/date' +import { CaminoDate, firstEtapeDateValidator, getCurrent } from 'camino-common/src/date' import { EtapeStatutId } from 'camino-common/src/static/etapesStatuts' import { LoadingElement } from '../_ui/functional-loader' import { isEtapeComplete, isEtapeDeposable, isEtapeValid } from 'camino-common/src/permissions/titres-etapes' import { getSections } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/sections' import { DsfrInputCheckbox } from '../_ui/dsfr-input-checkbox' import { CaminoError } from 'camino-common/src/zod-tools' +import { MachineInfo } from 'camino-common/src/machines' export type Props = { etape: Pick<Nullable<FlattenEtape>, 'id' | 'date' | 'typeId' | 'statutId' | 'slug'> & Omit<FlattenEtape, 'date' | 'typeId' | 'statutId' | 'id' | 'slug'> - demarcheId: DemarcheId - demarcheTypeId: DemarcheTypeId - titreTypeId: TitreTypeId + machineInfo: MachineInfo titreSlug: TitreSlug user: User entreprises: Entreprise[] perimetre: PerimetreInformations initTab?: 'points' | 'carte' goToDemarche: (demarcheId: DemarcheId) => void - firstEtapeDate: FirstEtapeDate | null apiClient: Pick< ApiClient, | 'getEntrepriseDocuments' @@ -86,13 +83,8 @@ type EtapeDocumentEdit = (EtapeDocument | TempEtapeDocument)[] type EntrepriseDocumentEdit = SelectedEntrepriseDocument[] type EtapeAvisEdit = (EtapeAvis | TempEtapeAvis)[] -const mergeFlattenEtapeWithNewHeritage = ( - etape: CoreEtapeCreationOrModification, - titreTypeId: TitreTypeId, - demarcheTypeId: DemarcheTypeId, - heritageData: GetEtapeHeritagePotentiel -): CoreEtapeCreationOrModification => { - const sections = getSections(titreTypeId, demarcheTypeId, etape.typeId) +const mergeFlattenEtapeWithNewHeritage = (etape: CoreEtapeCreationOrModification, machineInfo: MachineInfo, heritageData: GetEtapeHeritagePotentiel): CoreEtapeCreationOrModification => { + const sections = getSections(machineInfo, etape.typeId) const flattenEtape: CoreEtapeCreationOrModification = { ...etape, contenu: sections.reduce<FlattenEtape['contenu']>((accSection, section) => { @@ -237,8 +229,8 @@ export const EtapeEditForm = defineComponent<Props>(props => { statutId, isBrouillon: isNotNullNorUndefined(currentEtape.id) ? currentEtape.isBrouillon : canBeBrouillon(typeId), } - const value = await props.apiClient.getEtapeHeritagePotentiel(etape, props.demarcheId) - setEtape({ status: 'LOADED', value: mergeFlattenEtapeWithNewHeritage(etape, props.titreTypeId, props.demarcheTypeId, value) }) + const value = await props.apiClient.getEtapeHeritagePotentiel(etape, props.machineInfo.demarcheId) + setEtape({ status: 'LOADED', value: mergeFlattenEtapeWithNewHeritage(etape, props.machineInfo, value) }) } catch (e: any) { console.error('error', e) setEtape({ @@ -271,7 +263,12 @@ export const EtapeEditForm = defineComponent<Props>(props => { } // si c’est une demande d’AXM, on doit afficher une alerte si on est en zone 0 ou 1 du Sdom - if (etape.value.status === 'LOADED' && isNotNullNorUndefined(etape.value.value) && ['mfr', 'mcr'].includes(etape.value.value.typeId) && props.titreTypeId === 'axm') { + if ( + etape.value.status === 'LOADED' && + isNotNullNorUndefined(etape.value.value) && + [ETAPES_TYPES.demande, ETAPES_TYPES.recevabiliteDeLaDemande].includes(etape.value.value.typeId) && + props.machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX + ) { const zoneId = perimetreInfos.value.sdomZoneIds.find(id => [SDOMZoneIds.Zone0, SDOMZoneIds.Zone0Potentielle, SDOMZoneIds.Zone1].includes(id)) if (zoneId) { alertes.push({ message: `Le périmètre renseigné est dans une zone du Sdom interdite à l’exploitation minière : ${SDOMZones[zoneId].nom}` }) @@ -282,9 +279,25 @@ export const EtapeEditForm = defineComponent<Props>(props => { return alertes }) + const machineInfo = computed(() => { + if (isNotNullNorUndefined(props.machineInfo.machineId)) { + return props.machineInfo + } else { + if (etape.value.status === 'LOADED') { + return MachineInfo.withDate( + props.machineInfo.titreTypeId, + props.machineInfo.demarcheTypeId, + props.machineInfo.demarcheId, + firstEtapeDateValidator.parse(etape.value.value?.date ?? getCurrent()) + ) + } else { + return MachineInfo.withDate(props.machineInfo.titreTypeId, props.machineInfo.demarcheTypeId, props.machineInfo.demarcheId, firstEtapeDateValidator.parse(getCurrent())) + } + } + }) const canSave = computed<boolean>(() => { if (etape.value.status === 'LOADED' && isNotNullNorUndefined(etape.value.value)) { - const etapeValid = isEtapeValid(etape.value.value, props.titreTypeId, props.demarcheTypeId, props.demarcheId, props.firstEtapeDate ?? firstEtapeDateValidator.parse(etape.value.value.date)) + const etapeValid = isEtapeValid(etape.value.value, machineInfo.value) if (!etapeValid.valid) { return false } @@ -292,16 +305,13 @@ export const EtapeEditForm = defineComponent<Props>(props => { if (etape.value.value.isBrouillon === ETAPE_IS_NOT_BROUILLON) { const { valid } = isEtapeComplete( etape.value.value, - props.titreTypeId, - props.demarcheId, - props.demarcheTypeId, + machineInfo.value, etapeDocuments.value, entrepriseDocuments.value.map(e => ({ entreprise_document_type_id: e.documentTypeId, entreprise_id: e.entrepriseId })), props.perimetre.sdomZoneIds, props.perimetre.communes, etapeAvis.value, - props.user, - props.firstEtapeDate ?? firstEtapeDateValidator.parse(etape.value.value.date) + props.user ) return valid } @@ -314,16 +324,13 @@ export const EtapeEditForm = defineComponent<Props>(props => { if (etape.value.status === 'LOADED' && isNotNullNorUndefined(etape.value.value)) { return isEtapeDeposable( props.user, - props.titreTypeId, - props.demarcheId, - props.demarcheTypeId, + machineInfo.value, etape.value.value, etapeDocuments.value, entrepriseDocuments.value.map(({ documentTypeId, entrepriseId }) => ({ entreprise_document_type_id: documentTypeId, entreprise_id: entrepriseId })), props.perimetre.sdomZoneIds, props.perimetre.communes, - etapeAvis.value, - props.firstEtapeDate ?? firstEtapeDateValidator.parse(etape.value.value.date) + etapeAvis.value ) } @@ -382,7 +389,7 @@ export const EtapeEditForm = defineComponent<Props>(props => { etapeId = await props.apiClient.etapeModifier({ ...etape.value.value, id: props.etape.id, - titreDemarcheId: props.demarcheId, + titreDemarcheId: props.machineInfo.demarcheId, etapeAvis: etapeAvis.value, etapeDocuments: etapeDocuments.value, entrepriseDocumentIds: entrepriseDocuments.value.map(({ id }) => id), @@ -391,7 +398,7 @@ export const EtapeEditForm = defineComponent<Props>(props => { } else { etapeId = await props.apiClient.etapeCreer({ ...etape.value.value, - titreDemarcheId: props.demarcheId, + titreDemarcheId: props.machineInfo.demarcheId, etapeAvis: etapeAvis.value, etapeDocuments: etapeDocuments.value.filter(value => 'temp_document_name' in value), entrepriseDocumentIds: entrepriseDocuments.value.map(({ id }) => id), @@ -408,7 +415,7 @@ export const EtapeEditForm = defineComponent<Props>(props => { const saveAndReroute = async () => { const etapeId = await save() if (isNotNullNorUndefined(etapeId) && !('message' in etapeId)) { - props.goToDemarche(props.demarcheId) + props.goToDemarche(props.machineInfo.demarcheId) } return etapeId } @@ -425,7 +432,7 @@ export const EtapeEditForm = defineComponent<Props>(props => { return value } - props.goToDemarche(props.demarcheId) + props.goToDemarche(props.machineInfo.demarcheId) } return { message: "L'étape ne peut pas être sauvegardée" } @@ -449,7 +456,7 @@ export const EtapeEditForm = defineComponent<Props>(props => { ).valid } > - <DateTypeEdit etape={props.etape} apiClient={props.apiClient} completeUpdate={dateTypeCompleteUpdate} demarcheId={props.demarcheId} /> + <DateTypeEdit etape={props.etape} apiClient={props.apiClient} completeUpdate={dateTypeCompleteUpdate} demarcheId={props.machineInfo.demarcheId} /> </Bloc> ) : null} <LoadingElement @@ -460,6 +467,7 @@ export const EtapeEditForm = defineComponent<Props>(props => { <> <EtapeEditFormInternal {...props} + machineInfo={machineInfo.value} perimetre={perimetreInfos.value} etape={etapeLoaded} setEtape={setEtapeInternal} @@ -502,16 +510,13 @@ const EtapeEditFormInternal = defineComponent< setEntrepriseDocuments: (values: EntrepriseDocumentEdit) => void setEtapeAvis: (values: EtapeAvisEdit) => void alertesUpdate: (alertes: PerimetreInformations) => void + machineInfo: MachineInfo } & Omit<Props, 'etape'> >(props => { const documentsCompleteUpdate = (etapeDocuments: (EtapeDocument | TempEtapeDocument)[]) => { props.setEtapeDocuments(etapeDocuments) } - const firstEtapeDate = computed<FirstEtapeDate>(() => { - return props.firstEtapeDate ?? firstEtapeDateValidator.parse(props.etape.date) - }) - const avisCompleteUpdate = (etapeAvis: (EtapeAvis | TempEtapeAvis)[]) => { props.setEtapeAvis(etapeAvis) } @@ -578,43 +583,36 @@ const EtapeEditFormInternal = defineComponent< }) const isHelpVisible = computed<boolean>(() => { - return props.etape.typeId === 'mfr' && ['arm', 'axm'].includes(props.titreTypeId) + return ( + props.etape.typeId === ETAPES_TYPES.demande && [TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX].includes(props.machineInfo.titreTypeId) + ) }) return () => ( <div> {fondamentaleStepIsVisible(props.etape.typeId) ? ( - <Bloc step={{ name: 'Propriétés', help: null }} complete={fondamentaleStepIsComplete(props.etape, props.demarcheTypeId, props.titreTypeId, props.user).valid}> - <FondamentalesEdit - etape={props.etape} - demarcheTypeId={props.demarcheTypeId} - titreTypeId={props.titreTypeId} - user={props.user} - entreprises={props.entreprises} - completeUpdate={fondamentalesCompleteUpdate} - firstEtapeDate={firstEtapeDate.value} - /> + <Bloc step={{ name: 'Propriétés', help: null }} complete={fondamentaleStepIsComplete(props.etape, props.machineInfo, props.user).valid}> + <FondamentalesEdit etape={props.etape} machineInfo={props.machineInfo} user={props.user} entreprises={props.entreprises} completeUpdate={fondamentalesCompleteUpdate} /> </Bloc> ) : null} - {sectionsStepIsVisible(props.etape, props.demarcheTypeId, props.titreTypeId) ? ( + {sectionsStepIsVisible(props.etape, props.machineInfo) ? ( <Bloc step={{ name: 'Propriétés spécifiques', help: isHelpVisible.value ? 'Ce bloc permet de savoir si la prospection est mécanisée ou non et s’il y a des franchissements de cours d’eau (si oui, combien ?)' : null, }} - complete={sectionsStepIsComplete(props.etape, props.demarcheTypeId, props.titreTypeId).valid} + complete={sectionsStepIsComplete(props.etape, props.machineInfo).valid} > - <SectionsEdit etape={props.etape} titreTypeId={props.titreTypeId} demarcheTypeId={props.demarcheTypeId} completeUpdate={sectionCompleteUpdate} /> + <SectionsEdit etape={props.etape} machineInfo={props.machineInfo} completeUpdate={sectionCompleteUpdate} /> </Bloc> ) : null} - {perimetreStepIsVisible(props.etape, props.demarcheTypeId) ? ( - <Bloc step={{ name: 'Périmètre', help: null }} complete={perimetreStepIsComplete(props.etape, props.demarcheTypeId).valid}> + {perimetreStepIsVisible(props.etape, props.machineInfo) ? ( + <Bloc step={{ name: 'Périmètre', help: null }} complete={perimetreStepIsComplete(props.etape, props.machineInfo).valid}> <PerimetreEdit etape={props.etape} - titreTypeId={props.titreTypeId} - demarcheTypeId={props.demarcheTypeId} + machineInfo={props.machineInfo} titreSlug={props.titreSlug} apiClient={props.apiClient} initTab={props.initTab} @@ -622,24 +620,17 @@ const EtapeEditFormInternal = defineComponent< onPointsChange={onEtapePointsChange} onForagesChange={onEtapeForagesChange} onHeritageChange={onEtapePerimetreHeritageChange} - firstEtapeDate={firstEtapeDate.value} /> </Bloc> ) : null} {etapeDocumentsStepIsVisible() ? ( - <Bloc - step={{ name: 'Liste des documents', help: null }} - complete={etapeDocumentsStepIsComplete(props.etape, props.demarcheTypeId, props.titreTypeId, props.demarcheId, props.etapeDocuments, props.perimetre.sdomZoneIds, firstEtapeDate.value).valid} - > + <Bloc step={{ name: 'Liste des documents', help: null }} complete={etapeDocumentsStepIsComplete(props.etape, props.machineInfo, props.etapeDocuments, props.perimetre.sdomZoneIds).valid}> <EtapeDocumentsEdit apiClient={props.apiClient} tde={{ - titreTypeId: props.titreTypeId, - demarcheTypeId: props.demarcheTypeId, + machineInfo: props.machineInfo, etapeTypeId: props.etape.typeId, - demarcheId: props.demarcheId, - firstEtapeDate: firstEtapeDate.value, }} etapeId={props.etape.id} completeUpdate={documentsCompleteUpdate} @@ -651,19 +642,13 @@ const EtapeEditFormInternal = defineComponent< </Bloc> ) : null} - {etapeAvisStepIsVisible(props.etape, props.titreTypeId, props.demarcheTypeId, props.demarcheId, firstEtapeDate.value, props.perimetre.communes) ? ( - <Bloc - step={{ name: 'Liste des avis', help: null }} - complete={etapeAvisStepIsComplete(props.etape, props.etapeAvis, props.titreTypeId, props.demarcheTypeId, props.demarcheId, firstEtapeDate.value, props.perimetre.communes).valid} - > + {etapeAvisStepIsVisible(props.etape, props.machineInfo, props.perimetre.communes) ? ( + <Bloc step={{ name: 'Liste des avis', help: null }} complete={etapeAvisStepIsComplete(props.etape, props.etapeAvis, props.machineInfo, props.perimetre.communes).valid}> <EtapeAvisEdit apiClient={props.apiClient} tde={{ - titreTypeId: props.titreTypeId, - demarcheTypeId: props.demarcheTypeId, + machineInfo: props.machineInfo, etapeTypeId: props.etape.typeId, - demarcheId: props.demarcheId, - firstEtapeDate: firstEtapeDate.value, }} etapeId={props.etape.id} contenu={props.etape.contenu} @@ -674,7 +659,7 @@ const EtapeEditFormInternal = defineComponent< </Bloc> ) : null} - {entrepriseDocumentsStepIsVisible(props.etape, props.demarcheTypeId, props.titreTypeId) ? ( + {entrepriseDocumentsStepIsVisible(props.etape, props.machineInfo) ? ( <Bloc step={{ name: 'Documents d’entreprise', @@ -683,12 +668,12 @@ const EtapeEditFormInternal = defineComponent< ? "Les documents d’entreprise sont des documents propres à l'entreprise, et pourront être réutilisés pour la création d'un autre dossier et mis à jour si nécessaire. Ces documents d’entreprise sont consultables dans la fiche entreprise de votre société. Cette section permet de protéger et de centraliser les informations d'ordre privé relatives à la société et à son personnel." : null, }} - complete={entrepriseDocumentsStepIsComplete(props.etape, props.demarcheTypeId, props.titreTypeId, props.entrepriseDocuments).valid} + complete={entrepriseDocumentsStepIsComplete(props.etape, props.machineInfo, props.entrepriseDocuments).valid} > <EntrepriseDocumentsEdit entreprises={titulairesAndAmodiataires.value} apiClient={props.apiClient} - tde={{ titreTypeId: props.titreTypeId, demarcheTypeId: props.demarcheTypeId, etapeTypeId: props.etape.typeId }} + tde={{ machineInfo: props.machineInfo, etapeTypeId: props.etape.typeId }} etapeId={props.etape.id} completeUpdate={entrepriseDocumentsCompleteUpdate} /> @@ -707,13 +692,11 @@ const EtapeEditFormInternal = defineComponent< }) // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 -EtapeEditForm.props = ['etape', 'demarcheId', 'demarcheTypeId', 'titreTypeId', 'titreSlug', 'user', 'perimetre', 'entreprises', 'apiClient', 'initTab', 'goToDemarche', 'firstEtapeDate'] +EtapeEditForm.props = ['etape', 'titreSlug', 'user', 'perimetre', 'entreprises', 'apiClient', 'initTab', 'goToDemarche', 'machineInfo'] // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 EtapeEditFormInternal.props = [ 'etape', - 'demarcheId', - 'demarcheTypeId', 'etapeDocuments', 'entrepriseDocuments', 'etapeAvis', @@ -721,7 +704,6 @@ EtapeEditFormInternal.props = [ 'setEtapeDocuments', 'setEntrepriseDocuments', 'setEtapeAvis', - 'titreTypeId', 'titreSlug', 'user', 'perimetre', @@ -731,5 +713,5 @@ EtapeEditFormInternal.props = [ 'initTab', 'setEtape', 'documents', - 'firstEtapeDate', + 'machineInfo', ] diff --git a/packages/ui/src/components/etape/fondamentales-edit.stories.tsx b/packages/ui/src/components/etape/fondamentales-edit.stories.tsx index 9e4cfdab9af56dda5c52894290e7363cc7b4a3e4..bc29f4ca23d5dcbca9b46574234b6132ddb459f6 100644 --- a/packages/ui/src/components/etape/fondamentales-edit.stories.tsx +++ b/packages/ui/src/components/etape/fondamentales-edit.stories.tsx @@ -7,7 +7,7 @@ import { testBlankUser } from 'camino-common/src/tests-utils' import { action } from '@storybook/addon-actions' import { FlattenEtape } from 'camino-common/src/etape-form' import { demarcheIdValidator } from 'camino-common/src/demarche' -import { DATE_DEBUT_PROCEDURE_SPECIFIQUE } from 'camino-common/src/machines' +import { DATE_DEBUT_PROCEDURE_SPECIFIQUE, MachineInfo } from 'camino-common/src/machines' const meta: Meta = { title: 'Components/Etape/FondamentalesEdit', @@ -88,19 +88,18 @@ const entreprises = [ const completeUpdate = action('completeUpdate') const firstEtapeDate = firstEtapeDateValidator.parse('2022-01-01') +const demarcheId = demarcheIdValidator.parse('demarcheId') export const AxmDemandeSuper: StoryFn = () => ( <FondamentalesEdit etape={etape} completeUpdate={completeUpdate} - demarcheTypeId="oct" - titreTypeId="axm" + machineInfo={MachineInfo.withDate('axm', 'oct', demarcheId, firstEtapeDate)} user={{ role: 'super', ...testBlankUser, }} entreprises={entreprises} - firstEtapeDate={firstEtapeDate} /> ) @@ -108,15 +107,13 @@ export const ArmDemandeONF: StoryFn = () => ( <FondamentalesEdit etape={etape} completeUpdate={completeUpdate} - demarcheTypeId="oct" - titreTypeId="arm" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} user={{ role: 'admin', administrationId: 'ope-onf-973-01', ...testBlankUser, }} entreprises={entreprises} - firstEtapeDate={firstEtapeDate} /> ) @@ -124,11 +121,9 @@ export const ArmDemandeOperateur: StoryFn = () => ( <FondamentalesEdit etape={etape} completeUpdate={completeUpdate} - demarcheTypeId="oct" - titreTypeId="arm" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} user={{ role: 'entreprise', entrepriseIds: [], ...testBlankUser }} entreprises={entreprises} - firstEtapeDate={firstEtapeDate} /> ) @@ -136,11 +131,9 @@ export const ArmJorfONF: StoryFn = () => ( <FondamentalesEdit etape={{ ...etape, typeId: 'dpu' }} completeUpdate={completeUpdate} - demarcheTypeId="oct" - titreTypeId="arm" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} user={{ role: 'admin', administrationId: 'ope-onf-973-01', ...testBlankUser }} entreprises={entreprises} - firstEtapeDate={firstEtapeDate} /> ) @@ -148,11 +141,9 @@ export const AxmDemandeONF: StoryFn = () => ( <FondamentalesEdit etape={etape} completeUpdate={completeUpdate} - demarcheTypeId="oct" - titreTypeId="axm" + machineInfo={MachineInfo.withDate('axm', 'oct', demarcheId, firstEtapeDate)} user={{ role: 'admin', administrationId: 'ope-onf-973-01', ...testBlankUser }} entreprises={entreprises} - firstEtapeDate={firstEtapeDate} /> ) @@ -160,11 +151,9 @@ export const AxmDemandeTropLongue: StoryFn = () => ( <FondamentalesEdit etape={{ ...etape, date: DATE_DEBUT_PROCEDURE_SPECIFIQUE, duree: { value: 120, heritee: false, etapeHeritee: null } }} completeUpdate={completeUpdate} - demarcheTypeId="oct" - titreTypeId="axm" + machineInfo={MachineInfo.withDate('axm', 'oct', demarcheId, firstEtapeDateValidator.parse(DATE_DEBUT_PROCEDURE_SPECIFIQUE))} user={{ role: 'super', ...testBlankUser }} entreprises={entreprises} - firstEtapeDate={firstEtapeDateValidator.parse(DATE_DEBUT_PROCEDURE_SPECIFIQUE)} /> ) @@ -172,11 +161,9 @@ export const PrmDemandeONF: StoryFn = () => ( <FondamentalesEdit etape={etape} completeUpdate={completeUpdate} - demarcheTypeId="oct" - titreTypeId="prm" + machineInfo={MachineInfo.withDate('prm', 'oct', demarcheId, firstEtapeDate)} user={{ role: 'admin', administrationId: 'ope-onf-973-01', ...testBlankUser }} entreprises={entreprises} - firstEtapeDate={firstEtapeDate} /> ) @@ -184,10 +171,8 @@ export const PrmDeplacementDePerimetreONF: StoryFn = () => ( <FondamentalesEdit etape={etape} completeUpdate={completeUpdate} - demarcheTypeId="exp" - titreTypeId="prm" + machineInfo={MachineInfo.withDate('prm', 'exp', demarcheId, firstEtapeDate)} user={{ role: 'admin', administrationId: 'ope-onf-973-01', ...testBlankUser }} entreprises={entreprises} - firstEtapeDate={firstEtapeDate} /> ) diff --git a/packages/ui/src/components/etape/fondamentales-edit.tsx b/packages/ui/src/components/etape/fondamentales-edit.tsx index 2878bb4b8bf36db078d0b9cb4851d480fa3d0d1d..22a59e70e9713e9019fc77d4fbef9134765b83f3 100644 --- a/packages/ui/src/components/etape/fondamentales-edit.tsx +++ b/packages/ui/src/components/etape/fondamentales-edit.tsx @@ -2,12 +2,11 @@ import { useState } from '@/utils/vue-tsx-utils' import { DsfrTag } from '../_ui/tag' import { HeritageEdit } from './heritage-edit' import { AutocompleteEntreprises } from './autocomplete-entreprises' -import { CaminoDate, FirstEtapeDate } from 'camino-common/src/date' +import { CaminoDate } from 'camino-common/src/date' import { SubstancesEdit } from './substances-edit' import { canEditAmodiataires, canEditTitulaires, canEditDuree, canEditDates, InputPresence, InputAbsent, InputPresentOptional, dureeIsValide } from 'camino-common/src/permissions/titres-etapes' import { DomaineId } from 'camino-common/src/static/domaines' -import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' -import { getDomaineId, TitreTypeId } from 'camino-common/src/static/titresTypes' +import { getDomaineId } from 'camino-common/src/static/titresTypes' import { computed, ref, defineComponent } from 'vue' import { Entreprise, EntrepriseId } from 'camino-common/src/entreprise' import { User } from 'camino-common/src/roles' @@ -16,16 +15,15 @@ import { DsfrInput } from '../_ui/dsfr-input' import { FlattenEtape } from 'camino-common/src/etape-form' import { ZERO_KM2 } from 'camino-common/src/number' import { fr } from '@codegouvfr/react-dsfr' +import { MachineInfo } from 'camino-common/src/machines' export type EtapeFondamentaleEdit = Pick<FlattenEtape, 'typeId' | 'dateDebut' | 'dateFin' | 'duree' | 'titulaires' | 'amodiataires' | 'substances' | 'perimetre' | 'date' | 'titreDemarcheId'> interface Props { etape: EtapeFondamentaleEdit - demarcheTypeId: DemarcheTypeId - titreTypeId: TitreTypeId user: User entreprises: Entreprise[] completeUpdate: (etape: Props['etape']) => void - firstEtapeDate: FirstEtapeDate + machineInfo: MachineInfo } const dureeToAns = (duree: number | null | undefined) => { @@ -67,24 +65,14 @@ export const FondamentalesEdit = defineComponent<Props>(props => { updateEtape({ amodiataires }) } - const dureeEdit = computed<InputPresence>(() => canEditDuree(props.titreTypeId, props.demarcheTypeId, props.user)) + const dureeEdit = computed<InputPresence>(() => canEditDuree(props.machineInfo, props.user)) const dureeOptionalCheck = computed<boolean>(() => dureeEdit.value.visibility === 'present' && !dureeEdit.value.required) - const dureeValid = computed(() => - dureeIsValide( - props.titreTypeId, - props.demarcheTypeId, - props.etape.typeId, - { value: mois.value + ans.value * 12 }, - props.etape.perimetre.value?.surface ?? ZERO_KM2, - props.etape.titreDemarcheId, - props.firstEtapeDate - ) - ) + const dureeValid = computed(() => dureeIsValide(props.machineInfo, props.etape.typeId, { value: mois.value + ans.value * 12 }, props.etape.perimetre.value?.surface ?? ZERO_KM2)) - const datesEdit = computed<InputAbsent | InputPresentOptional>(() => canEditDates(props.titreTypeId, props.demarcheTypeId, props.etape.typeId, props.user)) + const datesEdit = computed<InputAbsent | InputPresentOptional>(() => canEditDates(props.machineInfo, props.etape.typeId, props.user)) const datesRequiredCheck = computed<boolean>(() => datesEdit.value.visibility === 'present' && datesEdit.value.required) - const titulairesEdit = computed<InputPresence>(() => canEditTitulaires(props.titreTypeId, props.demarcheTypeId, props.user)) + const titulairesEdit = computed<InputPresence>(() => canEditTitulaires(props.machineInfo, props.user)) const titulairesLabel = computed<string>(() => { if (titulairesEdit.value.visibility === 'present') { return 'Titulaires' @@ -94,7 +82,7 @@ export const FondamentalesEdit = defineComponent<Props>(props => { const titulairesRequiredCheck = computed<boolean>(() => titulairesEdit.value.visibility === 'present' && titulairesEdit.value.required) const amodiatairesRequiredCheck = computed<boolean>(() => amodiatairesEdit.value.visibility === 'present' && amodiatairesEdit.value.required) - const amodiatairesEdit = computed<InputPresence>(() => canEditAmodiataires(props.titreTypeId, props.demarcheTypeId, props.user)) + const amodiatairesEdit = computed<InputPresence>(() => canEditAmodiataires(props.machineInfo, props.user)) const amodiatairesLabel = computed<string>(() => { if (amodiatairesEdit.value.visibility === 'present') { return 'Amodiataires' @@ -102,7 +90,7 @@ export const FondamentalesEdit = defineComponent<Props>(props => { return '' }) - const domaineId = computed<DomaineId>(() => getDomaineId(props.titreTypeId)) + const domaineId = computed<DomaineId>(() => getDomaineId(props.machineInfo.titreTypeId)) const titulairesUpdate = (titulaireIds: EntrepriseId[]) => { updateEtape({ titulaires: { ...editedEtape.value.titulaires, value: titulaireIds } }) @@ -329,4 +317,4 @@ export const FondamentalesEdit = defineComponent<Props>(props => { }) // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 -FondamentalesEdit.props = ['etape', 'demarcheTypeId', 'titreTypeId', 'user', 'entreprises', 'completeUpdate', 'firstEtapeDate'] +FondamentalesEdit.props = ['etape', 'machineInfo', 'user', 'entreprises', 'completeUpdate'] diff --git a/packages/ui/src/components/etape/perimetre-edit.stories.tsx b/packages/ui/src/components/etape/perimetre-edit.stories.tsx index 225e377869b986b337edb58a343d95b24d1ac47c..493a0e73cb0b49c84e735ed5cc60af396d010a1d 100644 --- a/packages/ui/src/components/etape/perimetre-edit.stories.tsx +++ b/packages/ui/src/components/etape/perimetre-edit.stories.tsx @@ -10,6 +10,7 @@ import { titreSlugValidator } from 'camino-common/src/validators/titres' import { km2Validator } from 'camino-common/src/number' import { GEO_SYSTEME_IDS } from 'camino-common/src/static/geoSystemes' import { demarcheIdValidator } from 'camino-common/src/demarche' +import { MachineInfo } from 'camino-common/src/machines' const meta: Meta = { title: 'Components/Etape/PerimetreEdit', @@ -100,21 +101,19 @@ const etapeNoHeritage: Props['etape'] = { } const firstEtapeDate = firstEtapeDateValidator.parse('2022-01-01') - +const demarcheId = demarcheIdValidator.parse('demarcheId') const titreSlug = titreSlugValidator.parse('titre-slug') export const EmptyNoHeritage: StoryFn = () => ( <PerimetreEdit initTab="points" apiClient={apiClient} etape={etapeNoHeritage} - titreTypeId="arm" - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlug} onEtapeChange={onEtapeChange} onPointsChange={onPointsChange} onForagesChange={onForagesChange} onHeritageChange={onHeritageChange} - firstEtapeDate={firstEtapeDate} /> ) const etapeEmptyHeritage: Props['etape'] = { @@ -146,13 +145,11 @@ export const EmptyHeritage: StoryFn = () => ( onEtapeChange={onEtapeChange} apiClient={apiClient} etape={etapeEmptyHeritage} - titreTypeId="arm" - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlug} onPointsChange={onPointsChange} onForagesChange={onForagesChange} onHeritageChange={onHeritageChange} - firstEtapeDate={firstEtapeDate} /> ) @@ -194,13 +191,11 @@ export const Heritage: StoryFn = () => ( onEtapeChange={onEtapeChange} apiClient={apiClient} etape={etapeHeritage} - titreTypeId="arm" - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlug} onPointsChange={onPointsChange} onForagesChange={onForagesChange} onHeritageChange={onHeritageChange} - firstEtapeDate={firstEtapeDate} /> ) @@ -229,13 +224,11 @@ export const FilledNoHeritage: StoryFn = () => ( onEtapeChange={onEtapeChange} apiClient={apiClient} etape={etape} - titreTypeId="arm" - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlug} onPointsChange={onPointsChange} onForagesChange={onForagesChange} onHeritageChange={onHeritageChange} - firstEtapeDate={firstEtapeDate} /> ) @@ -264,13 +257,11 @@ export const LegacyGeoSysteme: StoryFn = () => ( onEtapeChange={onEtapeChange} apiClient={apiClient} etape={etapeLegacy} - titreTypeId="arm" - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlug} onPointsChange={onPointsChange} onForagesChange={onForagesChange} onHeritageChange={onHeritageChange} - firstEtapeDate={firstEtapeDate} /> ) @@ -378,12 +369,10 @@ export const WithForages: StoryFn = () => ( onEtapeChange={onEtapeChange} apiClient={apiClient} etape={etapeWithForages} - titreTypeId="pxg" - demarcheTypeId="oct" + machineInfo={MachineInfo.withDate('pxg', 'oct', demarcheId, firstEtapeDate)} titreSlug={titreSlug} onPointsChange={onPointsChange} onForagesChange={onForagesChange} onHeritageChange={onHeritageChange} - firstEtapeDate={firstEtapeDate} /> ) diff --git a/packages/ui/src/components/etape/perimetre-edit.tsx b/packages/ui/src/components/etape/perimetre-edit.tsx index de1d6559d0f9149c6832703fda941a5010d8a855..640aa557faa5bf01988986ed94bc8321dcbdd300 100644 --- a/packages/ui/src/components/etape/perimetre-edit.tsx +++ b/packages/ui/src/components/etape/perimetre-edit.tsx @@ -4,7 +4,6 @@ import { FunctionalComponent, HTMLAttributes, defineComponent, ref } from 'vue' import { DsfrButton } from '../_ui/dsfr-button' import { ApiClient } from '@/api/api-client' import { FeatureCollectionForages, FeatureCollectionPoints, GeojsonInformations } from 'camino-common/src/perimetre' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' import { DsfrPerimetre } from '../_common/dsfr-perimetre' import { TitreSlug } from 'camino-common/src/validators/titres' import { CaminoApiAlert } from '../_ui/alert' @@ -15,27 +14,24 @@ import { canHaveForages } from 'camino-common/src/permissions/titres' import { CoreEtapeCreationOrModification } from './etape-api-client' import { CaminoError } from 'camino-common/src/zod-tools' import { perimetreIsValide } from 'camino-common/src/permissions/titres-etapes' -import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' -import { FirstEtapeDate } from 'camino-common/src/date' +import { MachineInfo } from 'camino-common/src/machines' export interface Props { apiClient: Pick<ApiClient, 'uploadTempDocument' | 'geojsonImport' | 'geojsonPointsImport' | 'geojsonForagesImport'> etape: Pick<CoreEtapeCreationOrModification, 'perimetre' | 'date' | 'typeId' | 'titreDemarcheId'> - titreTypeId: TitreTypeId - demarcheTypeId: DemarcheTypeId + machineInfo: MachineInfo titreSlug: TitreSlug onEtapeChange: (geojsonInformations: GeojsonInformations) => void onHeritageChange: (heritage: Props['etape']['perimetre']) => void onPointsChange: (geojson4326Points: FeatureCollectionPoints, geojsonOriginePoints: FeatureCollectionPoints) => void onForagesChange: (geojson4326Forages: FeatureCollectionForages, geojsonOrigineForages: FeatureCollectionForages) => void initTab?: 'points' | 'carte' - firstEtapeDate: FirstEtapeDate } type DisplayPerimetreProps = { perimetre: Props['etape']['perimetre'] | null titreSlug: TitreSlug - titreTypeId: TitreTypeId + machineInfo: MachineInfo initTab?: 'points' | 'carte' class?: HTMLAttributes['class'] } @@ -61,7 +57,7 @@ const DisplayPerimetre: FunctionalComponent<DisplayPerimetreProps> = props => { surface: props.perimetre.value.surface ?? null, }} titreSlug={props.titreSlug} - titreTypeId={props.titreTypeId} + machineInfo={props.machineInfo} id="perimetre_edit" initTab={props.initTab ?? 'carte'} /> @@ -105,7 +101,7 @@ export const PerimetreEdit = defineComponent<Props>(props => { const result = (value: GeojsonInformations | CaminoError<string>) => { if ('geojson4326_perimetre' in value) { - const isValid = perimetreIsValide(props.titreTypeId, props.demarcheTypeId, props.etape.typeId, value.surface, props.etape.titreDemarcheId, props.firstEtapeDate) + const isValid = perimetreIsValide(props.machineInfo, props.etape.typeId, value.surface) if (!isValid.valid) { importError.value = { message: isValid.message } } else { @@ -152,26 +148,28 @@ export const PerimetreEdit = defineComponent<Props>(props => { {isNotNullNorUndefined(props.etape.perimetre.value?.geojson4326Perimetre) && isNotNullNorUndefined(props.etape.perimetre.value?.geojsonOrigineGeoSystemeId) ? ( <> <DsfrButton class="fr-ml-2w" onClick={openPointsPopup} buttonType="secondary" title="Éditer les points" /> - {canHaveForages(props.titreTypeId) ? <DsfrButton class="fr-ml-2w" onClick={openForagesPopup} buttonType="secondary" title="Éditer les forages" /> : null} + {canHaveForages(props.machineInfo) ? <DsfrButton class="fr-ml-2w" onClick={openForagesPopup} buttonType="secondary" title="Éditer les forages" /> : null} </> ) : null} {isNotNullNorUndefined(importError.value) ? <CaminoApiAlert class="fr-mt-2w" caminoApiError={importError.value} /> : null} - <DisplayPerimetre class="fr-mt-2w" perimetre={props.etape.perimetre} titreSlug={props.titreSlug} initTab={props.initTab} titreTypeId={props.titreTypeId} /> + <DisplayPerimetre class="fr-mt-2w" perimetre={props.etape.perimetre} titreSlug={props.titreSlug} initTab={props.initTab} machineInfo={props.machineInfo} /> </div> )} read={heritage => ( <DisplayPerimetre perimetre={isNotNullNorUndefined(heritage) ? { ...props.etape.perimetre, value: heritage.value } : null} titreSlug={props.titreSlug} - titreTypeId={props.titreTypeId} + machineInfo={props.machineInfo} initTab={props.initTab} /> )} /> - {importPerimetrePopup.value ? <PerimetreImportPopup close={closePerimetrePopup} result={result} apiClient={props.apiClient} titreTypeId={props.titreTypeId} titreSlug={props.titreSlug} /> : null} + {importPerimetrePopup.value ? ( + <PerimetreImportPopup close={closePerimetrePopup} result={result} apiClient={props.apiClient} titreTypeId={props.machineInfo.titreTypeId} titreSlug={props.titreSlug} /> + ) : null} {importPointsPopup.value && isNotNullNorUndefined(props.etape.perimetre.value?.geojsonOrigineGeoSystemeId) ? ( <PointsImportPopup close={closePointsPopup} result={resultPoints} geoSystemeId={props.etape.perimetre.value.geojsonOrigineGeoSystemeId} apiClient={props.apiClient} /> @@ -185,4 +183,4 @@ export const PerimetreEdit = defineComponent<Props>(props => { }) // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 -PerimetreEdit.props = ['etape', 'apiClient', 'titreTypeId', 'demarcheTypeId', 'titreSlug', 'onEtapeChange', 'initTab', 'onPointsChange', 'onForagesChange', 'onHeritageChange', 'firstEtapeDate'] +PerimetreEdit.props = ['etape', 'apiClient', 'machineInfo', 'titreSlug', 'onEtapeChange', 'initTab', 'onPointsChange', 'onForagesChange', 'onHeritageChange'] diff --git a/packages/ui/src/components/etape/sections-edit.stories.tsx b/packages/ui/src/components/etape/sections-edit.stories.tsx index 35ded23dc1b5ec01886116f1bf54b951376d6964..f94e3febd56769db48f60406a821efb350940381 100644 --- a/packages/ui/src/components/etape/sections-edit.stories.tsx +++ b/packages/ui/src/components/etape/sections-edit.stories.tsx @@ -1,7 +1,9 @@ import { SectionsEdit } from './sections-edit' import { Meta, StoryFn } from '@storybook/vue3' import { action } from '@storybook/addon-actions' -import { toCaminoDate } from 'camino-common/src/date' +import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' +import { MachineInfo } from 'camino-common/src/machines' +import { demarcheIdValidator } from 'camino-common/src/demarche' const meta: Meta = { title: 'Components/Etape/SectionsEdit', @@ -12,11 +14,11 @@ export default meta const completeUpdate = action('completeUpdate') +const demarcheId = demarcheIdValidator.parse('demarcheId') export const SansHeritage: StoryFn = () => ( <SectionsEdit completeUpdate={completeUpdate} - demarcheTypeId="oct" - titreTypeId="arm" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse('2024-01-01'))} etape={{ typeId: 'mfr', contenu: { arm: { mecanise: { value: true, heritee: false, etapeHeritee: null }, franchissements: { value: null, heritee: false, etapeHeritee: null } } }, @@ -28,8 +30,7 @@ export const SansHeritage: StoryFn = () => ( export const AvecHeritageActif: StoryFn = () => ( <SectionsEdit completeUpdate={completeUpdate} - demarcheTypeId="oct" - titreTypeId="arm" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse('2024-01-01'))} etape={{ date: toCaminoDate('2024-01-01'), typeId: 'mod', @@ -46,8 +47,7 @@ export const AvecHeritageActif: StoryFn = () => ( export const AvecHeritage: StoryFn = () => ( <SectionsEdit completeUpdate={completeUpdate} - demarcheTypeId="oct" - titreTypeId="arm" + machineInfo={MachineInfo.withDate('arm', 'oct', demarcheId, firstEtapeDateValidator.parse('2024-01-01'))} etape={{ date: toCaminoDate('2024-01-01'), typeId: 'mod', @@ -64,8 +64,7 @@ export const AvecHeritage: StoryFn = () => ( export const DecisionJorf: StoryFn = () => ( <SectionsEdit completeUpdate={completeUpdate} - demarcheTypeId="pro" - titreTypeId="pcc" + machineInfo={MachineInfo.withDate('pcc', 'pro', demarcheId, firstEtapeDateValidator.parse('2000-05-16'))} etape={{ date: toCaminoDate('2000-05-16'), typeId: 'dpu', diff --git a/packages/ui/src/components/etape/sections-edit.tsx b/packages/ui/src/components/etape/sections-edit.tsx index f610aa6b979c2b9d18d2aff3479471387f065b5c..9172806f23c83008291e8821c445f039cd72a294 100644 --- a/packages/ui/src/components/etape/sections-edit.tsx +++ b/packages/ui/src/components/etape/sections-edit.tsx @@ -1,17 +1,15 @@ import { computed, defineComponent } from 'vue' -import { TitreTypeId } from 'camino-common/src/static/titresTypes' -import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' import { getSections, getSectionsWithValue } from 'camino-common/src/static/titresTypes_demarchesTypes_etapesTypes/sections' import { isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools' import { useState } from '../../utils/vue-tsx-utils' import { SectionWithValue } from 'camino-common/src/sections' import { SectionElementWithValueEdit } from './section-element-with-value-edit' import { FlattenedContenuElement, FlattenEtape } from 'camino-common/src/etape-form' +import { MachineInfo } from 'camino-common/src/machines' export type SectionsEditEtape = Pick<FlattenEtape, 'typeId' | 'contenu' | 'date'> type Props = { - titreTypeId: TitreTypeId - demarcheTypeId: DemarcheTypeId + machineInfo: MachineInfo etape: SectionsEditEtape completeUpdate: (etape: Props['etape']) => void } @@ -29,7 +27,7 @@ export const SectionsEdit = defineComponent<Props>(props => { } const sections = computed(() => { - return getSections(props.titreTypeId, props.demarcheTypeId, props.etape.typeId) + return getSections(props.machineInfo, props.etape.typeId) }) const sectionsWithValue = computed<SectionWithValue[]>(() => { if (isNotNullNorUndefined(editedEtape.value.contenu)) { @@ -63,4 +61,4 @@ export const SectionsEdit = defineComponent<Props>(props => { }) // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 -SectionsEdit.props = ['etape', 'titreTypeId', 'demarcheTypeId', 'completeUpdate'] +SectionsEdit.props = ['etape', 'machineInfo', 'completeUpdate'] diff --git a/packages/ui/src/components/titre.stories.tsx b/packages/ui/src/components/titre.stories.tsx index e611c50c3a9fabfd56e5c7ade50fcd886789ef96..d829c06a40218ccdd1d6f1c6f3df5d86521daa86 100644 --- a/packages/ui/src/components/titre.stories.tsx +++ b/packages/ui/src/components/titre.stories.tsx @@ -132,6 +132,7 @@ const titre = { id: demarcheIdValidator.parse('id-demarche-1'), demarche_type_id: 'oct', slug: demarcheSlug, + machine_id: 'ProcedureSpecifique', demarche_date_debut: toCaminoDate('4000-01-01'), demarche_date_fin: toCaminoDate('4000-01-01'), demarche_statut_id: 'acc', @@ -380,7 +381,7 @@ const chantePieApiClient: PropsApiClient = { getTitreAction(titreIdOrSlug) // prettier-ignore - const chantepieData = titreGetValidator.parse({"id":"Ju80kBYMoDstD5J6H8wqWRdo","titre_visibilite":"Publique","nom":"Chantepie","slug":"m-cx-chantepie-1988","titre_type_id":"cxm","titre_statut_id":"val","titre_doublon":null,"references":[{"nom":"2013-0224-MI","referenceTypeId":"deb"}],"titre_last_modified_date":"2023-10-12","demarches":[{"id":"PpD4be1fwbWJ7TZCdwvZj0vQ","demarche_visibilite":"Publique","slug":"m-cx-chantepie-1988-oct01","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":600,"substances":["auru","arge","cuiv","ferx","plom","souf","zinc","scoc"],"titulaireIds":["fr-632022711"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-0.105658320330431,48.1489209342693],[-0.115003633563279,48.1398379979624],[-0.0996023094257926,48.1209828190687],[-0.0852402595925762,48.1212930049111],[-0.0616864580218711,48.1486971325525],[-0.105658320330431,48.1489209342693]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.105658320330431,48.1489209342693]},"properties":{"nom":"A","description":"Intersection de l'axe de la route départementale n° 103, joignant Rouez et Crissé et de la droite joignant l'intersection de l'axe de la rivière La Vègre avec la limite des communes de Sillé-le-Guillaume et de Rouez, d'une part, au sommet B défini ci-après"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0616864580218711,48.1486971325525]},"properties":{"nom":"B","description":"Intersection de l'axe de la route départementale n° 304 allant de Sillé-le-Guillaume à Conlie et de l'axe de la route départementale n° 167 allant à Rouez"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0852402595925762,48.1212930049111]},"properties":{"nom":"C","description":"Intersection de la droite joignant l'axe du clocher de Sillé-le-Guillaume et l'axe du clocher de Tennie, et de la droite joignant l'axe du clocher de Parennes et l'axe du clocher de Conlie"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0996023094257926,48.1209828190687]},"properties":{"nom":"D","description":"Intersection de la droite joignant l'axe du clocher de Parennes et l'axe du clocher de Conlie et de la droite joignant l'axe du clocher de Rouez et l'axe du clocher de Bernay"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.115003633563279,48.1398379979624]},"properties":{"nom":"E","description":"Axe du clocher de Rouez"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[418280,1052710],[421550,1052580],[419700,1049590],[418630,1049590],[417552,1051723],[418280,1052710]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[418280,1052710]},"properties":{"nom":"A","description":"Intersection de l’axe de la route départementale n° 103, joignant Rouez et Crissé et de la droite joignant l’intersection de l’axe de la rivière La Vègre avec la limite des communes de Sillé-le-Guillaume et de Rouez, d’une part, au sommet B défini ci-après"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[421550,1052580]},"properties":{"nom":"B","description":"Intersection de l’axe de la route départementale n° 304 allant de Sillé-le-Guillaume à Conlie et de l’axe de la route départementale n° 167 allant à Rouez"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[419700,1049590]},"properties":{"nom":"C","description":"Intersection de la droite joignant l’axe du clocher de Sillé-le-Guillaume et l’axe du clocher de Tennie, et de la droite joignant l’axe du clocher de Parennes et l’axe du clocher de Conlie"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[418630,1049590]},"properties":{"nom":"D","description":"Intersection de la droite joignant l’axe du clocher de Parennes et l’axe du clocher de Conlie et de la droite joignant l’axe du clocher de Rouez et l’axe du clocher de Bernay"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[417552,1051723]},"properties":{"nom":"E","description":"Axe du clocher de Rouez"}}]},"geojson_origine_geo_systeme_id":"27571","geojson4326_forages":null,"geojson_origine_forages":null,"surface":8,"communes":[{"id":"72256","nom":"Rouez"},{"id":"72351","nom":"Tennie"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_statut_id":"fai","is_brouillon":false,"date":"1988-09-01","id":"OxqtxQwW0B3AUIHFR7k32Ycl","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-chantepie-1988-oct01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000000681488"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"INDE8800659D"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":600,"substances":["auru","arge","cuiv","ferx","plom","souf","zinc","scoc"],"titulaireIds":["fr-632022711"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-0.105658320330431,48.1489209342693],[-0.115003633563279,48.1398379979624],[-0.0996023094257926,48.1209828190687],[-0.0852402595925762,48.1212930049111],[-0.0616864580218711,48.1486971325525],[-0.105658320330431,48.1489209342693]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.105658320330431,48.1489209342693]},"properties":{"nom":"A","description":"Intersection de l'axe de la route départementale n° 103, joignant Rouez et Crissé et de la droite joignant l'intersection de l'axe de la rivière La Vègre avec la limite des communes de Sillé-le-Guillaume et de Rouez, d'une part, au sommet B défini ci-après"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0616864580218711,48.1486971325525]},"properties":{"nom":"B","description":"Intersection de l'axe de la route départementale n° 304 allant de Sillé-le-Guillaume à Conlie et de l'axe de la route départementale n° 167 allant à Rouez"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0852402595925762,48.1212930049111]},"properties":{"nom":"C","description":"Intersection de la droite joignant l'axe du clocher de Sillé-le-Guillaume et l'axe du clocher de Tennie, et de la droite joignant l'axe du clocher de Parennes et l'axe du clocher de Conlie"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0996023094257926,48.1209828190687]},"properties":{"nom":"D","description":"Intersection de la droite joignant l'axe du clocher de Parennes et l'axe du clocher de Conlie et de la droite joignant l'axe du clocher de Rouez et l'axe du clocher de Bernay"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.115003633563279,48.1398379979624]},"properties":{"nom":"E","description":"Axe du clocher de Rouez"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[418280,1052710],[421550,1052580],[419700,1049590],[418630,1049590],[417552,1051723],[418280,1052710]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[418280,1052710]},"properties":{"nom":"A","description":"Intersection de l’axe de la route départementale n° 103, joignant Rouez et Crissé et de la droite joignant l’intersection de l’axe de la rivière La Vègre avec la limite des communes de Sillé-le-Guillaume et de Rouez, d’une part, au sommet B défini ci-après"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[421550,1052580]},"properties":{"nom":"B","description":"Intersection de l’axe de la route départementale n° 304 allant de Sillé-le-Guillaume à Conlie et de l’axe de la route départementale n° 167 allant à Rouez"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[419700,1049590]},"properties":{"nom":"C","description":"Intersection de la droite joignant l’axe du clocher de Sillé-le-Guillaume et l’axe du clocher de Tennie, et de la droite joignant l’axe du clocher de Parennes et l’axe du clocher de Conlie"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[418630,1049590]},"properties":{"nom":"D","description":"Intersection de la droite joignant l’axe du clocher de Parennes et l’axe du clocher de Conlie et de la droite joignant l’axe du clocher de Rouez et l’axe du clocher de Bernay"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[417552,1051723]},"properties":{"nom":"E","description":"Axe du clocher de Rouez"}}]},"geojson_origine_geo_systeme_id":"27571","geojson4326_forages":null,"geojson_origine_forages":null,"surface":8,"communes":[{"id":"72256","nom":"Rouez"},{"id":"72351","nom":"Tennie"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_statut_id":"acc","is_brouillon":false,"date":"1988-08-24","id":"XkNmBmjc6YYY6OEncdCAldnU","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-chantepie-1988-oct01-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"1988-09-01","demarche_date_fin":"2038-09-01","ordre":1},{"id":"mkPvJYXFO2InPppXamCRo2Cv","demarche_visibilite":"Publique","slug":"m-cx-chantepie-1988-mut01","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":["fr-409160132"],"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"2000-06-06","id":"lc3diJKRphb029ufvF73FlSn","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-chantepie-1988-mut01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000000765254"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOI0000251A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":["fr-409160132"],"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"2000-05-25","id":"2n1RaQcCxZMVta2Qfv1pUIRS","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-chantepie-1988-mut01-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"ordre":2}],"nb_activites_to_do":null}) + const chantepieData = titreGetValidator.parse({"id":"Ju80kBYMoDstD5J6H8wqWRdo","nom":"Chantepie","slug":"m-cx-chantepie-1988","titre_type_id":"cxm","titre_statut_id":"val","titre_visibilite":"Publique","titre_doublon":null,"references":[{"nom":"2013-0224-MI","referenceTypeId":"deb"}],"titre_last_modified_date":null,"demarches":[{"id":"PpD4be1fwbWJ7TZCdwvZj0vQ","slug":"m-cx-chantepie-1988-oct01","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"1988-09-01","id":"OxqtxQwW0B3AUIHFR7k32Ycl","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-chantepie-1988-oct01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000000681488"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"INDE8800659D"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":600,"substances":["auru","arge","cuiv","ferx","plom","souf","zinc","scoc"],"titulaireIds":["fr-632022711"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-0.105658320330431,48.1489209342693],[-0.115003633563279,48.1398379979624],[-0.0996023094257926,48.1209828190687],[-0.0852402595925762,48.1212930049111],[-0.0616864580218711,48.1486971325525],[-0.105658320330431,48.1489209342693]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.105658320330431,48.1489209342693]},"properties":{"nom":"A","description":"Intersection de l'axe de la route départementale n° 103, joignant Rouez et Crissé et de la droite joignant l'intersection de l'axe de la rivière La Vègre avec la limite des communes de Sillé-le-Guillaume et de Rouez, d'une part, au sommet B défini ci-après"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0616864580218711,48.1486971325525]},"properties":{"nom":"B","description":"Intersection de l'axe de la route départementale n° 304 allant de Sillé-le-Guillaume à Conlie et de l'axe de la route départementale n° 167 allant à Rouez"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0852402595925762,48.1212930049111]},"properties":{"nom":"C","description":"Intersection de la droite joignant l'axe du clocher de Sillé-le-Guillaume et l'axe du clocher de Tennie, et de la droite joignant l'axe du clocher de Parennes et l'axe du clocher de Conlie"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0996023094257926,48.1209828190687]},"properties":{"nom":"D","description":"Intersection de la droite joignant l'axe du clocher de Parennes et l'axe du clocher de Conlie et de la droite joignant l'axe du clocher de Rouez et l'axe du clocher de Bernay"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.115003633563279,48.1398379979624]},"properties":{"nom":"E","description":"Axe du clocher de Rouez"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[418280,1052710],[421550,1052580],[419700,1049590],[418630,1049590],[417552,1051723],[418280,1052710]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[418280,1052710]},"properties":{"nom":"A","description":"Intersection de l’axe de la route départementale n° 103, joignant Rouez et Crissé et de la droite joignant l’intersection de l’axe de la rivière La Vègre avec la limite des communes de Sillé-le-Guillaume et de Rouez, d’une part, au sommet B défini ci-après"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[421550,1052580]},"properties":{"nom":"B","description":"Intersection de l’axe de la route départementale n° 304 allant de Sillé-le-Guillaume à Conlie et de l’axe de la route départementale n° 167 allant à Rouez"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[419700,1049590]},"properties":{"nom":"C","description":"Intersection de la droite joignant l’axe du clocher de Sillé-le-Guillaume et l’axe du clocher de Tennie, et de la droite joignant l’axe du clocher de Parennes et l’axe du clocher de Conlie"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[418630,1049590]},"properties":{"nom":"D","description":"Intersection de la droite joignant l’axe du clocher de Parennes et l’axe du clocher de Conlie et de la droite joignant l’axe du clocher de Rouez et l’axe du clocher de Bernay"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[417552,1051723]},"properties":{"nom":"E","description":"Axe du clocher de Rouez"}}]},"geojson_origine_geo_systeme_id":"27571","geojson4326_forages":null,"geojson_origine_forages":null,"surface":8,"communes":[{"id":"72256","nom":"Rouez"},{"id":"72351","nom":"Tennie"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"1988-08-24","id":"XkNmBmjc6YYY6OEncdCAldnU","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-chantepie-1988-oct01-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":600,"substances":["auru","arge","cuiv","ferx","plom","souf","zinc","scoc"],"titulaireIds":["fr-632022711"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-0.105658320330431,48.1489209342693],[-0.115003633563279,48.1398379979624],[-0.0996023094257926,48.1209828190687],[-0.0852402595925762,48.1212930049111],[-0.0616864580218711,48.1486971325525],[-0.105658320330431,48.1489209342693]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.105658320330431,48.1489209342693]},"properties":{"nom":"A","description":"Intersection de l'axe de la route départementale n° 103, joignant Rouez et Crissé et de la droite joignant l'intersection de l'axe de la rivière La Vègre avec la limite des communes de Sillé-le-Guillaume et de Rouez, d'une part, au sommet B défini ci-après"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0616864580218711,48.1486971325525]},"properties":{"nom":"B","description":"Intersection de l'axe de la route départementale n° 304 allant de Sillé-le-Guillaume à Conlie et de l'axe de la route départementale n° 167 allant à Rouez"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0852402595925762,48.1212930049111]},"properties":{"nom":"C","description":"Intersection de la droite joignant l'axe du clocher de Sillé-le-Guillaume et l'axe du clocher de Tennie, et de la droite joignant l'axe du clocher de Parennes et l'axe du clocher de Conlie"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.0996023094257926,48.1209828190687]},"properties":{"nom":"D","description":"Intersection de la droite joignant l'axe du clocher de Parennes et l'axe du clocher de Conlie et de la droite joignant l'axe du clocher de Rouez et l'axe du clocher de Bernay"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.115003633563279,48.1398379979624]},"properties":{"nom":"E","description":"Axe du clocher de Rouez"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[418280,1052710],[421550,1052580],[419700,1049590],[418630,1049590],[417552,1051723],[418280,1052710]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[418280,1052710]},"properties":{"nom":"A","description":"Intersection de l’axe de la route départementale n° 103, joignant Rouez et Crissé et de la droite joignant l’intersection de l’axe de la rivière La Vègre avec la limite des communes de Sillé-le-Guillaume et de Rouez, d’une part, au sommet B défini ci-après"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[421550,1052580]},"properties":{"nom":"B","description":"Intersection de l’axe de la route départementale n° 304 allant de Sillé-le-Guillaume à Conlie et de l’axe de la route départementale n° 167 allant à Rouez"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[419700,1049590]},"properties":{"nom":"C","description":"Intersection de la droite joignant l’axe du clocher de Sillé-le-Guillaume et l’axe du clocher de Tennie, et de la droite joignant l’axe du clocher de Parennes et l’axe du clocher de Conlie"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[418630,1049590]},"properties":{"nom":"D","description":"Intersection de la droite joignant l’axe du clocher de Parennes et l’axe du clocher de Conlie et de la droite joignant l’axe du clocher de Rouez et l’axe du clocher de Bernay"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[417552,1051723]},"properties":{"nom":"E","description":"Axe du clocher de Rouez"}}]},"geojson_origine_geo_systeme_id":"27571","geojson4326_forages":null,"geojson_origine_forages":null,"surface":8,"communes":[{"id":"72256","nom":"Rouez"},{"id":"72351","nom":"Tennie"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_type_id":"dex"}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"1988-09-01","demarche_date_fin":"2038-09-01","demarche_visibilite":"Publique","machine_id":null,"ordre":1},{"id":"mkPvJYXFO2InPppXamCRo2Cv","slug":"m-cx-chantepie-1988-mut01","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2000-06-06","id":"lc3diJKRphb029ufvF73FlSn","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-chantepie-1988-mut01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000000765254"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOI0000251A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":["fr-409160132"],"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2000-05-25","id":"2n1RaQcCxZMVta2Qfv1pUIRS","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-chantepie-1988-mut01-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":["fr-409160132"],"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":2}],"nb_activites_to_do":null}) chantepieData.nom = 'Chantepie avec un titre assez long' chantepieData.nb_activites_to_do = 2 @@ -433,7 +434,7 @@ const criqueAdolpheApiClient: PropsApiClient = { getTitreAction(titreIdOrSlug) // prettier-ignore - const criqueAdolpheData = titreGetValidator.parse({"id":"tbFvGIDboAzxTb54GQyghTyc","titre_visibilite":"Publique","nom":"Crique Adolphe","slug":"m-ar-crique-adolphe-2023","titre_type_id":"arm","titre_statut_id":"ech","titre_doublon":null,"references":[{"nom":"2022-032","referenceTypeId":"ptm"},{"nom":"AR 2022-027","referenceTypeId":"onf"}],"titre_last_modified_date":"2023-10-20","demarches":[{"id":"yAvBOMdHDsyES7phbS5hRKLA","demarche_visibilite":"Publique","slug":"m-ar-crique-adolphe-2023-oct01","description":null,"etapes":[{"etape_type_id":"sco","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"2023-09-19","id":"5649942721fd9f3478381ae9","ordre":15,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-sco01","sections_with_values":[{"id":"suivi","nom":"Suivi de la démarche","elements":[{"id":"signataire","nom":"Signataire ONF","description":"Prénom et nom du représentant légal du titulaire de l'ONF","optionnel":true,"type":"text","value":null},{"id":"titulaire","nom":"Signataire titulaire","description":"Prénom et nom du représentant légal du titulaire de l'autorisation","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"sca","etape_statut_id":"fai","is_brouillon":false,"date":"2023-01-11","id":"WLXKWB9Fv17gm2gTJYIXnTyX","ordre":10,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-sca01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"aca","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fav","is_brouillon":false,"date":"2023-01-11","id":"oXXG5ToIYbw8MvdYPX7sMMAP","ordre":11,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-aca01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"rde","etape_statut_id":"fav","is_brouillon":false,"date":"2022-12-29","id":"y0SCXGJ1OBYSthcWyojyOLZX","ordre":8,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-rde01","sections_with_values":[{"id":"deal","nom":"DEAL","elements":[{"id":"numero-dossier-deal-eau","nom":"Numéro de dossier","description":"Numéro de dossier DEAL Service eau","optionnel":true,"type":"text","value":""},{"id":"numero-recepisse","nom":"Numéro de récépissé","description":"Numéro de récépissé émis par la DEAL Service eau","optionnel":true,"type":"text","value":"R03-2022-12-29-00005"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"mcr","etape_statut_id":"fav","is_brouillon":false,"date":"2022-12-05","id":"0vdB4jaJbpIpyUnIZkKPsmCm","ordre":7,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-mcr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"mfr", "demarche_id_en_concurrence": null, "demarches_consentement": [],"fondamentale":{"date_debut":null,"date_fin":null,"duree":4,"substances":["auru"],"titulaireIds":["fr-794312231"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.58181013905019,3.8309654861273],[-53.58178306390299,3.8219278216269807],[-53.572785590706495,3.82195493825841],[-53.57281257175149,3.8309926670647294],[-53.58181013905019,3.8309654861273]]],[[[-53.60031408473134,3.8224780986447566],[-53.59891645305842,3.8181831495446303],[-53.58181205656814,3.82379854768971],[-53.58320964990986,3.828093576227541],[-53.60031408473134,3.8224780986447566]]],[[[-53.583861926103765,3.8502114455117433],[-53.592379712320195,3.834289122043602],[-53.588417035915334,3.8321501920354253],[-53.57989914401643,3.8480725119510217],[-53.583861926103765,3.8502114455117433]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58181013905019,3.8309654861273]},"properties":{"nom":"S1","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.57281257175149,3.8309926670647294]},"properties":{"nom":"S2","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.572785590706495,3.82195493825841]},"properties":{"nom":"S3","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58178306390299,3.8219278216269807]},"properties":{"nom":"S4","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.60031408473134,3.8224780986447566]},"properties":{"nom":"S5","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58320964990986,3.828093576227541]},"properties":{"nom":"S6","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58181205656814,3.82379854768971]},"properties":{"nom":"S7","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.59891645305842,3.8181831495446303]},"properties":{"nom":"S8","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.583861926103765,3.8502114455117433]},"properties":{"nom":"S9","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.57989914401643,3.8480725119510217]},"properties":{"nom":"S10","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.588417035915334,3.8321501920354253]},"properties":{"nom":"S11","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.592379712320195,3.834289122043602]},"properties":{"nom":"S12","description":"ARM3.3"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[213250,423875],[214250,423875],[214250,422875],[213250,422875],[213250,423875]]],[[[211190.6,422942.1],[213093.5,423557.7],[213247.4,423082],[211344.5,422466.4],[211190.6,422942.1]]],[[[213028.4,426005.2],[213468.1,425767.2],[212516.1,424008.3],[212076.4,424246.3],[213028.4,426005.2]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[213250,423875]},"properties":{"nom":"S1","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[214250,423875]},"properties":{"nom":"S2","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[214250,422875]},"properties":{"nom":"S3","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[213250,422875]},"properties":{"nom":"S4","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[211190.6,422942.1]},"properties":{"nom":"S5","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[213093.5,423557.7]},"properties":{"nom":"S6","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[213247.4,423082]},"properties":{"nom":"S7","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[211344.5,422466.4]},"properties":{"nom":"S8","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[213028.4,426005.2]},"properties":{"nom":"S9","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[213468.1,425767.2]},"properties":{"nom":"S10","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[212516.1,424008.3]},"properties":{"nom":"S11","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[212076.4,424246.3]},"properties":{"nom":"S12","description":"ARM3.3"}}]},"geojson_origine_geo_systeme_id":"2972","geojson4326_forages":null,"geojson_origine_forages":null,"surface":3,"communes":[{"id":"97353","nom":"Maripasoula"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_statut_id":"fai","is_brouillon":false,"date":"2022-11-08","id":"pwqOEAsAmaWi0o24QiVeVZ40","ordre":3,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-mfr01","sections_with_values":[{"id":"arm","nom":"Caractéristiques ARM","elements":[{"id":"mecanise","nom":"Prospection mécanisée","description":"","optionnel":false,"type":"radio","value":true},{"id":"franchissements","nom":"Franchissements de cours d'eau","description":"Nombre de franchissements de cours d'eau","optionnel":true,"type":"integer","value":12}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"men","etape_statut_id":"fai","is_brouillon":false,"date":"2022-11-08","id":"pF4UG6UrCOJmKjtgmtpwthTQ","ordre":4,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dae","etape_statut_id":"exe","is_brouillon":false,"date":"2022-09-26","id":"KA7tyvIdlqQmmVOuVjEl0Hdt","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-dae01","sections_with_values":[{"id":"mea","nom":"Mission autorité environnementale","elements":[{"id":"arrete","nom":"Arrêté préfectoral","description":"Numéro de l'arrêté préfectoral portant décision dans le cadre de l’examen au cas par cas du projet d’autorisation de recherche minière","optionnel":true,"type":"text","value":"R03-2022-09-26-00002"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"2023-09-19","demarche_date_fin":"2024-01-19","ordre":1}],"nb_activites_to_do":null}) + const criqueAdolpheData = titreGetValidator.parse({"id":"tbFvGIDboAzxTb54GQyghTyc","nom":"Crique Adolphe","slug":"m-ar-crique-adolphe-2023","titre_type_id":"arm","titre_statut_id":"ech","titre_visibilite":"Publique","titre_doublon":null,"references":[{"nom":"2022-032","referenceTypeId":"ptm"},{"nom":"AR 2022-027","referenceTypeId":"onf"}],"titre_last_modified_date":null,"demarches":[{"id":"yAvBOMdHDsyES7phbS5hRKLA","slug":"m-ar-crique-adolphe-2023-oct01","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2023-09-19","id":"5649942721fd9f3478381ae9","ordre":15,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-sco01","sections_with_values":[{"id":"suivi","nom":"Suivi de la démarche","elements":[{"id":"signataire","nom":"Signataire ONF","description":"Prénom et nom du représentant légal du titulaire de l'ONF","optionnel":true,"type":"text","value":null},{"id":"titulaire","nom":"Signataire titulaire","description":"Prénom et nom du représentant légal du titulaire de l'autorisation","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"sco"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2023-01-11","id":"WLXKWB9Fv17gm2gTJYIXnTyX","ordre":10,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-sca01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"sca"},{"etape_statut_id":"fav","is_brouillon":false,"date":"2023-01-11","id":"oXXG5ToIYbw8MvdYPX7sMMAP","ordre":11,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-aca01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"aca"},{"etape_statut_id":"fav","is_brouillon":false,"date":"2022-12-29","id":"y0SCXGJ1OBYSthcWyojyOLZX","ordre":8,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-rde01","sections_with_values":[{"id":"deal","nom":"DEAL","elements":[{"id":"numero-dossier-deal-eau","nom":"Numéro de dossier","description":"Numéro de dossier DEAL Service eau","optionnel":true,"type":"text","value":""},{"id":"numero-recepisse","nom":"Numéro de récépissé","description":"Numéro de récépissé émis par la DEAL Service eau","optionnel":true,"type":"text","value":"R03-2022-12-29-00005"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"rde"},{"etape_statut_id":"fav","is_brouillon":false,"date":"2022-12-05","id":"0vdB4jaJbpIpyUnIZkKPsmCm","ordre":7,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-mcr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"mcr"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2022-11-08","id":"pF4UG6UrCOJmKjtgmtpwthTQ","ordre":4,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"men"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2022-11-08","id":"pwqOEAsAmaWi0o24QiVeVZ40","ordre":3,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-mfr01","sections_with_values":[{"id":"arm","nom":"Caractéristiques ARM","elements":[{"id":"mecanise","nom":"Prospection mécanisée","description":"","optionnel":false,"type":"radio","value":true},{"id":"franchissements","nom":"Franchissements de cours d'eau","description":"Nombre de franchissements de cours d'eau","optionnel":true,"type":"integer","value":12}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"demarches_consentement":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":4,"substances":["auru"],"titulaireIds":["fr-794312231"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.58181013905019,3.8309654861273],[-53.58178306390299,3.8219278216269807],[-53.572785590706495,3.82195493825841],[-53.57281257175149,3.8309926670647294],[-53.58181013905019,3.8309654861273]]],[[[-53.60031408473134,3.8224780986447566],[-53.59891645305842,3.8181831495446303],[-53.58181205656814,3.82379854768971],[-53.58320964990986,3.828093576227541],[-53.60031408473134,3.8224780986447566]]],[[[-53.583861926103765,3.8502114455117433],[-53.592379712320195,3.834289122043602],[-53.588417035915334,3.8321501920354253],[-53.57989914401643,3.8480725119510217],[-53.583861926103765,3.8502114455117433]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58181013905019,3.8309654861273]},"properties":{"nom":"S1","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.57281257175149,3.8309926670647294]},"properties":{"nom":"S2","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.572785590706495,3.82195493825841]},"properties":{"nom":"S3","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58178306390299,3.8219278216269807]},"properties":{"nom":"S4","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.60031408473134,3.8224780986447566]},"properties":{"nom":"S5","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58320964990986,3.828093576227541]},"properties":{"nom":"S6","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.58181205656814,3.82379854768971]},"properties":{"nom":"S7","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.59891645305842,3.8181831495446303]},"properties":{"nom":"S8","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.583861926103765,3.8502114455117433]},"properties":{"nom":"S9","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.57989914401643,3.8480725119510217]},"properties":{"nom":"S10","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.588417035915334,3.8321501920354253]},"properties":{"nom":"S11","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.592379712320195,3.834289122043602]},"properties":{"nom":"S12","description":"ARM3.3"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[213250,423875],[214250,423875],[214250,422875],[213250,422875],[213250,423875]]],[[[211190.6,422942.1],[213093.5,423557.7],[213247.4,423082],[211344.5,422466.4],[211190.6,422942.1]]],[[[213028.4,426005.2],[213468.1,425767.2],[212516.1,424008.3],[212076.4,424246.3],[213028.4,426005.2]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[213250,423875]},"properties":{"nom":"S1","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[214250,423875]},"properties":{"nom":"S2","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[214250,422875]},"properties":{"nom":"S3","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[213250,422875]},"properties":{"nom":"S4","description":"ARM1.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[211190.6,422942.1]},"properties":{"nom":"S5","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[213093.5,423557.7]},"properties":{"nom":"S6","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[213247.4,423082]},"properties":{"nom":"S7","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[211344.5,422466.4]},"properties":{"nom":"S8","description":"ARM2.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[213028.4,426005.2]},"properties":{"nom":"S9","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[213468.1,425767.2]},"properties":{"nom":"S10","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[212516.1,424008.3]},"properties":{"nom":"S11","description":"ARM3.3"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[212076.4,424246.3]},"properties":{"nom":"S12","description":"ARM3.3"}}]},"geojson_origine_geo_systeme_id":"2972","geojson4326_forages":null,"geojson_origine_forages":null,"surface":3,"communes":[{"id":"97353","nom":"Maripasoula"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_type_id":"mfr","demarche_id_en_concurrence":null},{"etape_statut_id":"exe","is_brouillon":false,"date":"2022-09-26","id":"KA7tyvIdlqQmmVOuVjEl0Hdt","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-crique-adolphe-2023-oct01-dae01","sections_with_values":[{"id":"mea","nom":"Mission autorité environnementale","elements":[{"id":"arrete","nom":"Arrêté préfectoral","description":"Numéro de l'arrêté préfectoral portant décision dans le cadre de l'examen au cas par cas du projet d'autorisation de recherche minière","optionnel":true,"type":"text","value":"R03-2022-09-26-00002"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"dae"}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"2023-09-19","demarche_date_fin":"2024-01-19","demarche_visibilite":"Publique","machine_id":"AncienLogigrammeOctroiARM","ordre":1}],"nb_activites_to_do":null}) criqueAdolpheData.nb_activites_to_do = 0 return Promise.resolve(criqueAdolpheData) @@ -459,7 +460,7 @@ const abattisKoticaApiClient: PropsApiClient = { getTitreAction(titreIdOrSlug) // prettier-ignore - const abattisData = titreGetValidator.parse({"id":"ooyCY2eGMXLunjmwPbBYyQcf","titre_visibilite":"Publique","nom":"Abattis Kotika","slug":"m-ar-abattis-kotika-2006","titre_type_id":"arm","titre_statut_id":"ech","titre_doublon":null,"references":[{"nom":"AR2006060","referenceTypeId":"onf"},{"nom":"2006-061","referenceTypeId":"ptm"}],"titre_last_modified_date":null,"demarches":[{"id":"SjKhYLXdqcla1BaN3nmgQhPs","demarche_visibilite":"Publique","slug":"m-ar-abattis-kotika-2006-oct01","description":null,"etapes":[{"etape_type_id":"def","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"2006-11-28","id":"Pw734o5mdB2K2AWaOKQ85Ydz","ordre":4,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-abattis-kotika-2006-oct01-def01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"sco","fondamentale":{"date_debut":null,"date_fin":"2007-03-27","duree":4,"substances":["auru"],"titulaireIds":["fr-480857036"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-54.256565011133,3.95310428827045],[-54.2571944444789,3.94846823388004],[-54.2392714613677,3.9464520807474],[-54.2387665564076,3.95076254570704],[-54.256565011133,3.95310428827045]]],[[[-54.251541223062,3.94479622927321],[-54.251001625524,3.94017377611083],[-54.2330489949186,3.94209562569541],[-54.2335613570663,3.94667311503072],[-54.251541223062,3.94479622927321]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.256565011133,3.95310428827045]},"properties":{"nom":"1","description":"a"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.2387665564076,3.95076254570704]},"properties":{"nom":"2","description":"b"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.2392714613677,3.9464520807474]},"properties":{"nom":"3","description":"c"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.2571944444789,3.94846823388004]},"properties":{"nom":"4","description":"d"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.251541223062,3.94479622927321]},"properties":{"nom":"1","description":"e"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.2335613570663,3.94667311503072]},"properties":{"nom":"2","description":"f"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.2330489949186,3.94209562569541]},"properties":{"nom":"3","description":"g"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.251001625524,3.94017377611083]},"properties":{"nom":"4","description":"h"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[138288,437653],[140266,437386],[140208,436909],[138216,437140],[138288,437653]]],[[[138843,436731],[140843,436931],[140898,436424],[138901,436219],[138843,436731]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[138288,437653]},"properties":{"nom":"1","description":"a"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[140266,437386]},"properties":{"nom":"2","description":"b"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[140208,436909]},"properties":{"nom":"3","description":"c"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[138216,437140]},"properties":{"nom":"4","description":"d"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[138843,436731]},"properties":{"nom":"1","description":"e"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[140843,436931]},"properties":{"nom":"2","description":"f"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[140898,436424]},"properties":{"nom":"3","description":"g"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[138901,436219]},"properties":{"nom":"4","description":"h"}}]},"geojson_origine_geo_systeme_id":"2972","geojson4326_forages":null,"geojson_origine_forages":null,"surface":2,"communes":[{"id":"97362","nom":"Papaichton"}],"secteurs_maritimes":[],"sdom_zones":["0_potentielle","2"],"forets":[]}},"etape_statut_id":"fai","is_brouillon":false,"date":"2006-11-28","id":"1iF8kbcg0oGaEMAJxgUZYk8W","ordre":5,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-abattis-kotika-2006-oct01-sco01","sections_with_values":[{"id":"arm","nom":"Caractéristiques ARM","elements":[{"id":"mecanise","nom":"Prospection mécanisée","optionnel":false,"type":"radio","value":null}]},{"id":"suivi","nom":"Suivi de la démarche","elements":[{"id":"signataire","nom":"Signataire ONF","description":"Prénom et nom du représentant légal du titulaire de l'ONF","optionnel":true,"type":"text","value":"Michel Borderes"},{"id":"titulaire","nom":"Signataire titulaire","description":"Prénom et nom du représentant légal du titulaire de l'autorisation","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"men","etape_statut_id":"fai","is_brouillon":false,"date":"2006-10-16","id":"TMWQQo20x3j7BJ8Sboaq1B20","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-abattis-kotika-2006-oct01-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"2006-11-28","demarche_date_fin":"2007-03-27","ordre":1}],"nb_activites_to_do":null}) + const abattisData = titreGetValidator.parse({"id":"ooyCY2eGMXLunjmwPbBYyQcf","nom":"Abattis Kotika","slug":"m-ar-abattis-kotika-2006","titre_type_id":"arm","titre_statut_id":"ech","titre_visibilite":"Publique","titre_doublon":null,"references":[{"nom":"AR2006060","referenceTypeId":"onf"},{"nom":"2006-061","referenceTypeId":"ptm"}],"titre_last_modified_date":null,"demarches":[{"id":"SjKhYLXdqcla1BaN3nmgQhPs","slug":"m-ar-abattis-kotika-2006-oct01","description":null,"etapes":[{"etape_statut_id":"acc","is_brouillon":false,"date":"2006-11-28","id":"Pw734o5mdB2K2AWaOKQ85Ydz","ordre":4,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-abattis-kotika-2006-oct01-def01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"def"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2006-11-28","id":"1iF8kbcg0oGaEMAJxgUZYk8W","ordre":5,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-abattis-kotika-2006-oct01-sco01","sections_with_values":[{"id":"arm","nom":"Caractéristiques ARM","elements":[{"id":"mecanise","nom":"Prospection mécanisée","optionnel":false,"type":"radio","value":null}]},{"id":"suivi","nom":"Suivi de la démarche","elements":[{"id":"signataire","nom":"Signataire ONF","description":"Prénom et nom du représentant légal du titulaire de l'ONF","optionnel":true,"type":"text","value":"Michel Borderes"},{"id":"titulaire","nom":"Signataire titulaire","description":"Prénom et nom du représentant légal du titulaire de l'autorisation","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":"2007-03-27","duree":4,"substances":["auru"],"titulaireIds":["fr-480857036"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-54.256565011133,3.95310428827045],[-54.2571944444789,3.94846823388004],[-54.2392714613677,3.9464520807474],[-54.2387665564076,3.95076254570704],[-54.256565011133,3.95310428827045]]],[[[-54.251541223062,3.94479622927321],[-54.251001625524,3.94017377611083],[-54.2330489949186,3.94209562569541],[-54.2335613570663,3.94667311503072],[-54.251541223062,3.94479622927321]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.256565011133,3.95310428827045]},"properties":{"nom":"1","description":"a"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.2387665564076,3.95076254570704]},"properties":{"nom":"2","description":"b"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.2392714613677,3.9464520807474]},"properties":{"nom":"3","description":"c"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.2571944444789,3.94846823388004]},"properties":{"nom":"4","description":"d"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.251541223062,3.94479622927321]},"properties":{"nom":"1","description":"e"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.2335613570663,3.94667311503072]},"properties":{"nom":"2","description":"f"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.2330489949186,3.94209562569541]},"properties":{"nom":"3","description":"g"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-54.251001625524,3.94017377611083]},"properties":{"nom":"4","description":"h"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[138288,437653],[140266,437386],[140208,436909],[138216,437140],[138288,437653]]],[[[138843,436731],[140843,436931],[140898,436424],[138901,436219],[138843,436731]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[138288,437653]},"properties":{"nom":"1","description":"a"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[140266,437386]},"properties":{"nom":"2","description":"b"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[140208,436909]},"properties":{"nom":"3","description":"c"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[138216,437140]},"properties":{"nom":"4","description":"d"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[138843,436731]},"properties":{"nom":"1","description":"e"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[140843,436931]},"properties":{"nom":"2","description":"f"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[140898,436424]},"properties":{"nom":"3","description":"g"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[138901,436219]},"properties":{"nom":"4","description":"h"}}]},"geojson_origine_geo_systeme_id":"2972","geojson4326_forages":null,"geojson_origine_forages":null,"surface":2,"communes":[{"id":"97362","nom":"Papaichton"}],"secteurs_maritimes":[],"sdom_zones":["0_potentielle","2"],"forets":[]}},"etape_type_id":"sco"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2006-10-16","id":"TMWQQo20x3j7BJ8Sboaq1B20","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-ar-abattis-kotika-2006-oct01-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"men"}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"2006-11-28","demarche_date_fin":"2007-03-27","demarche_visibilite":"Publique","machine_id":null,"ordre":1}],"nb_activites_to_do":null}) abattisData.nb_activites_to_do = 0 return Promise.resolve(abattisData) @@ -485,16 +486,15 @@ const bonEspoirApiClient: PropsApiClient = { getTitreAction(titreIdOrSlug) // prettier-ignore - const bonEspoirData = titreGetValidator.parse({"id":"sJorD6pQomXTN7oRpyGwLijB","titre_visibilite":"Publique","nom":"Bon Espoir","slug":"m-pr-bon-espoir-2001","titre_type_id":"prm","titre_statut_id":"ech","titre_doublon":null,"references":[{"nom":"21/2001","referenceTypeId":"dea"},{"nom":"2013-0033-MI","referenceTypeId":"deb"}],"titre_last_modified_date":"2023-11-30","demarches":[{"id":"ry8fHgRWiKEOE1x1ZANmajh8","demarche_visibilite":"Publique","slug":"m-pr-bon-espoir-2001-oct01","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":"2001-11-01","date_fin":null,"duree":60,"substances":["auru","scoc"],"titulaireIds":null,"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.9579321010744,5.07776938770113],[-53.9575232150351,4.98735333700249],[-53.8673626701318,4.98775355007457],[-53.8672265271601,4.95631734759459],[-53.7770631139658,4.95670276466037],[-53.7769878916108,4.93868722476635],[-53.5698730075868,4.93952315477954],[-53.5702069576163,5.02537608911083],[-53.759383911755,5.02460196044417],[-53.7596128864516,5.07864912381548],[-53.9579321010744,5.07776938770113]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9579321010744,5.07776938770113]},"properties":{"nom":"1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7596128864516,5.07864912381548]},"properties":{"nom":"2","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.759383911755,5.02460196044417]},"properties":{"nom":"3","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.5702069576163,5.02537608911083]},"properties":{"nom":"4","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.5698730075868,4.93952315477954]},"properties":{"nom":"5","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7769878916108,4.93868722476635]},"properties":{"nom":"6","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7770631139658,4.95670276466037]},"properties":{"nom":"7","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8672265271601,4.95631734759459]},"properties":{"nom":"8","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8673626701318,4.98775355007457]},"properties":{"nom":"9","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9575232150351,4.98735333700249]},"properties":{"nom":"10","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.957932101,5.077769388],[-53.957523215,4.987353337],[-53.86736267,4.98775355],[-53.867226527,4.956317348],[-53.777063114,4.956702765],[-53.776987892,4.938687225],[-53.569873008,4.939523155],[-53.570206958,5.025376089],[-53.759383912,5.02460196],[-53.759612886,5.078649124],[-53.957932101,5.077769388]]]]}},"geojson_origine_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9579321010744,5.07776938770113]},"properties":{"nom":"1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7596128864516,5.07864912381548]},"properties":{"nom":"2","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.759383911755,5.02460196044417]},"properties":{"nom":"3","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.5702069576163,5.02537608911083]},"properties":{"nom":"4","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.5698730075868,4.93952315477954]},"properties":{"nom":"5","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7769878916108,4.93868722476635]},"properties":{"nom":"6","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7770631139658,4.95670276466037]},"properties":{"nom":"7","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8672265271601,4.95631734759459]},"properties":{"nom":"8","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8673626701318,4.98775355007457]},"properties":{"nom":"9","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9575232150351,4.98735333700249]},"properties":{"nom":"10","description":null}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":465.5,"communes":[{"id":"97306","nom":"Mana"},{"id":"97311","nom":"Saint-Laurent-du-Maroni"}],"secteurs_maritimes":[],"sdom_zones":["0","2"],"forets":["LDD","MDF","PAUL"]}},"etape_statut_id":"fai","is_brouillon":false,"date":"2001-10-26","id":"CRVhvEIQAc319vUd8BfZoH5W","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-oct01-dpu01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":3201430},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":"EUR"}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000000774145"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOI0100462D"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"2001-10-24","id":"Ce4K8goEZzjqXRJLL051jcpD","ordre":1,"note":{"valeur":"Décret du 24 octobre 2001 accordant un permis de recherches A en Guyane","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-oct01-dex01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"2001-11-01","demarche_date_fin":"2006-11-01","ordre":1},{"demarche_visibilite":"Publique","id":"PnFewl8P4Zt5Vm49zXqyn7Ml","slug":"m-pr-bon-espoir-2001-pr101","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["auru"],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"2010-03-02","id":"qtn2a3DNPx258VZgSjqXGKf6","ordre":4,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr101-dpu02","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":560000},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":"EUR"}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000021889053"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"DEVO1003938A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"2010-02-17","id":"tjOMgkb83wksMc6DFuqrecbu","ordre":3,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr101-dex02","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"id":"2010-02-17-arr-a26ea089","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"arr","description":"Arrêté du 17 février 2010 modifiant l'arrêté du 6 mai 2009 prolongeant la validité du permis exclusif de recherches de mines d'or dit « Permis de Bon Espoir » et réduisant sa surface (Guyane)"}],"avis_documents":[]},{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":"2011-10-31","duree":null,"substances":["auru"],"titulaireIds":null,"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.9577777777778,5.07666666666667],[-53.9575,5.0325],[-53.8944444444444,5.00055555555556],[-53.8208333333333,4.97972222222222],[-53.7138888888889,4.96388888888889],[-53.7322222222222,5.02361111111111],[-53.8763888888889,5.02277777777778],[-53.9577777777778,5.07666666666667]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9577777777778,5.07666666666667]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8763888888889,5.02277777777778]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7322222222222,5.02361111111111]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7138888888889,4.96388888888889]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8208333333333,4.97972222222222]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8944444444444,5.00055555555556]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9575,5.0325]},"properties":{"nom":"G","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.957777778,5.076666667],[-53.9575,5.0325],[-53.894444444,5.000555556],[-53.820833333,4.979722222],[-53.713888889,4.963888889],[-53.732222222,5.023611111],[-53.876388889,5.022777778],[-53.957777778,5.076666667]]]]}},"geojson_origine_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9577777777778,5.07666666666667]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8763888888889,5.02277777777778]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7322222222222,5.02361111111111]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7138888888889,4.96388888888889]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8208333333333,4.97972222222222]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8944444444444,5.00055555555556]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9575,5.0325]},"properties":{"nom":"G","description":null}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":122.275,"communes":[{"id":"97306","nom":"Mana"},{"id":"97311","nom":"Saint-Laurent-du-Maroni"}],"secteurs_maritimes":[],"sdom_zones":["0","2"],"forets":["LDD","PAUL"]}},"etape_statut_id":"fai","is_brouillon":false,"date":"2009-05-16","id":"07cbyPCYcOtKYkw4kOqg2Sed","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr101-dpu01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":837000},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":"EUR"}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000020616467"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"DEVO0909004A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"2009-05-06","id":"orsPMmIfX4kSgVus0HTrBxAo","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr101-dex01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"id":"2009-05-06-arr-54f88e41","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"arr","description":"Arrêté du 6 mai 2009 prolongeant la validité du permis exclusif de recherches de mines d'or dit « Permis Bon Espoir » et réduisant sa superficie (Guyane)"}],"avis_documents":[]}],"demarche_type_id":"pr1","demarche_statut_id":"acc","demarche_date_debut":"2006-11-01","demarche_date_fin":"2011-10-31","ordre":2},{"demarche_visibilite":"Publique","id":"EMFAv33wlGqMcjd6DwKzQBvr","slug":"m-pr-bon-espoir-2001-pr201","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":"2016-10-31","duree":60,"substances":["auru","scoc"],"titulaireIds":["fr-401802863"],"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"2015-08-15","id":"Qp5DRYEN3Nc9n4CIwEYW7evs","ordre":9,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr201-dpu01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":1250000},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":"EUR"}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000031053068"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"EINL1518062A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":60,"substances":["auru","scoc"],"titulaireIds":["fr-401802863"],"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"2015-08-03","id":"ABvgimvovFWeEhoMOrKi4wAy","ordre":8,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr201-dex01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"id":"2015-08-03-arm-8bf71a65","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"arm","description":"Arrêté du 3 août 2015 prolongeant la durée de validité du permis exclusif de recherches de mines d'or et de substances connexes dit « Permis de Bon Espoir » attribué à la société Armina Ressources Minières dans le département de Guyane"}],"avis_documents":[]},{"etape_type_id":"men","etape_statut_id":"fai","is_brouillon":false,"date":"2011-06-30","id":"nLXaR7H78V43GB47ypDoqvKz","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr201-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"mfr", "demarche_id_en_concurrence": null, "demarches_consentement": [],"fondamentale":{"date_debut":null,"date_fin":null,"duree":60,"substances":["auru","arge","cuiv"],"titulaireIds":["fr-401802863"],"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"2011-06-29","id":"iV47juaOeL4EAUsOqiWN6gOO","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr201-mfr01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"pr2","demarche_statut_id":"acc","demarche_date_debut":"2011-10-31","demarche_date_fin":"2016-10-31","ordre":3}],"nb_activites_to_do":null}) + const bonEspoirData = titreGetValidator.parse({"id":"sJorD6pQomXTN7oRpyGwLijB","nom":"Bon Espoir","slug":"m-pr-bon-espoir-2001","titre_type_id":"prm","titre_statut_id":"ech","titre_visibilite":"Publique","titre_doublon":null,"references":[{"nom":"21/2001","referenceTypeId":"dea"},{"nom":"2013-0033-MI","referenceTypeId":"deb"}],"titre_last_modified_date":null,"demarches":[{"id":"ry8fHgRWiKEOE1x1ZANmajh8","slug":"m-pr-bon-espoir-2001-oct01","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2001-10-26","id":"CRVhvEIQAc319vUd8BfZoH5W","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-oct01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000000774145"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOI0100462D"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":"2001-11-01","date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2001-10-24","id":"Ce4K8goEZzjqXRJLL051jcpD","ordre":1,"note":{"valeur":"Décret du 24 octobre 2001 accordant un permis de recherches A en Guyane","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-oct01-dex01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":3201430},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":"EUR"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":60,"substances":["auru","scoc"],"titulaireIds":["fr-401802863"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.9579321010744,5.07776938770113],[-53.9575232150351,4.98735333700249],[-53.8673626701318,4.98775355007457],[-53.8672265271601,4.95631734759459],[-53.7770631139658,4.95670276466037],[-53.7769878916108,4.93868722476635],[-53.5698730075868,4.93952315477954],[-53.5702069576163,5.02537608911083],[-53.759383911755,5.02460196044417],[-53.7596128864516,5.07864912381548],[-53.9579321010744,5.07776938770113]]]]}},"geojson4326_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9579321010744,5.07776938770113]},"properties":{"nom":"1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7596128864516,5.07864912381548]},"properties":{"nom":"2","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.759383911755,5.02460196044417]},"properties":{"nom":"3","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.5702069576163,5.02537608911083]},"properties":{"nom":"4","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.5698730075868,4.93952315477954]},"properties":{"nom":"5","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7769878916108,4.93868722476635]},"properties":{"nom":"6","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7770631139658,4.95670276466037]},"properties":{"nom":"7","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8672265271601,4.95631734759459]},"properties":{"nom":"8","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8673626701318,4.98775355007457]},"properties":{"nom":"9","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9575232150351,4.98735333700249]},"properties":{"nom":"10","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.9579321010744,5.07776938770113],[-53.9575232150351,4.98735333700249],[-53.8673626701318,4.98775355007457],[-53.8672265271601,4.95631734759459],[-53.7770631139658,4.95670276466037],[-53.7769878916108,4.93868722476635],[-53.5698730075868,4.93952315477954],[-53.5702069576163,5.02537608911083],[-53.759383911755,5.02460196044417],[-53.7596128864516,5.07864912381548],[-53.9579321010744,5.07776938770113]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9579321010744,5.07776938770113]},"properties":{"nom":"1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7596128864516,5.07864912381548]},"properties":{"nom":"2","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.759383911755,5.02460196044417]},"properties":{"nom":"3","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.5702069576163,5.02537608911083]},"properties":{"nom":"4","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.5698730075868,4.93952315477954]},"properties":{"nom":"5","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7769878916108,4.93868722476635]},"properties":{"nom":"6","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7770631139658,4.95670276466037]},"properties":{"nom":"7","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8672265271601,4.95631734759459]},"properties":{"nom":"8","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8673626701318,4.98775355007457]},"properties":{"nom":"9","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9575232150351,4.98735333700249]},"properties":{"nom":"10","description":null}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":464.71,"communes":[{"id":"97306","nom":"Mana"},{"id":"97311","nom":"Saint-Laurent-du-Maroni"}],"secteurs_maritimes":[],"sdom_zones":["0","2"],"forets":["LDD","MDF","PAUL"]}},"etape_type_id":"dex"}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"2001-11-01","demarche_date_fin":"2006-11-01","demarche_visibilite":"Publique","machine_id":null,"ordre":1},{"id":"PnFewl8P4Zt5Vm49zXqyn7Ml","slug":"m-pr-bon-espoir-2001-pr101","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2010-03-02","id":"qtn2a3DNPx258VZgSjqXGKf6","ordre":4,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr101-dpu02","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":560000},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":"EUR"}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000021889053"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"DEVO1003938A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["auru"],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2010-02-17","id":"tjOMgkb83wksMc6DFuqrecbu","ordre":3,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr101-dex02","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[{"type":"DESCRIPTION_OPTIONNELLE","id":"2010-02-17-arr-a26ea089","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"arr","description":"Arrêté du 17 février 2010 modifiant l'arrêté du 6 mai 2009 prolongeant la validité du permis exclusif de recherches de mines d'or dit « Permis de Bon Espoir » et réduisant sa surface (Guyane)"}],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2009-05-16","id":"07cbyPCYcOtKYkw4kOqg2Sed","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr101-dpu01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":837000},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":"EUR"}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000020616467"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"DEVO0909004A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":"2011-10-31","duree":null,"substances":["auru"],"titulaireIds":null,"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.9577777777778,5.07666666666667],[-53.9575,5.0325],[-53.8944444444444,5.00055555555556],[-53.8208333333333,4.97972222222222],[-53.7138888888889,4.96388888888889],[-53.7322222222222,5.02361111111111],[-53.8763888888889,5.02277777777778],[-53.9577777777778,5.07666666666667]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9577777777778,5.07666666666667]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8763888888889,5.02277777777778]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7322222222222,5.02361111111111]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7138888888889,4.96388888888889]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8208333333333,4.97972222222222]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8944444444444,5.00055555555556]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9575,5.0325]},"properties":{"nom":"G","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.9577777777778,5.07666666666667],[-53.9575,5.0325],[-53.8944444444444,5.00055555555556],[-53.8208333333333,4.97972222222222],[-53.7138888888889,4.96388888888889],[-53.7322222222222,5.02361111111111],[-53.8763888888889,5.02277777777778],[-53.9577777777778,5.07666666666667]]]]}},"geojson_origine_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9577777777778,5.07666666666667]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8763888888889,5.02277777777778]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7322222222222,5.02361111111111]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7138888888889,4.96388888888889]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8208333333333,4.97972222222222]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8944444444444,5.00055555555556]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9575,5.0325]},"properties":{"nom":"G","description":null}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":122.275,"communes":[{"id":"97306","nom":"Mana"},{"id":"97311","nom":"Saint-Laurent-du-Maroni"}],"secteurs_maritimes":[],"sdom_zones":["0","2"],"forets":["LDD","PAUL"]}},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2009-05-06","id":"orsPMmIfX4kSgVus0HTrBxAo","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr101-dex01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[{"type":"DESCRIPTION_OPTIONNELLE","id":"2009-05-06-arr-54f88e41","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"arr","description":"Arrêté du 6 mai 2009 prolongeant la validité du permis exclusif de recherches de mines d'or dit « Permis Bon Espoir » et réduisant sa superficie (Guyane)"}],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"}],"demarche_type_id":"pr1","demarche_statut_id":"acc","demarche_date_debut":"2006-11-01","demarche_date_fin":"2011-10-31","demarche_visibilite":"Publique","machine_id":null,"ordre":2},{"id":"EMFAv33wlGqMcjd6DwKzQBvr","slug":"m-pr-bon-espoir-2001-pr201","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2015-08-15","id":"Qp5DRYEN3Nc9n4CIwEYW7evs","ordre":10,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr201-dpu01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":1250000},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":"EUR"}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000031053068"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"EINL1518062A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":"2016-10-31","duree":60,"substances":["auru","scoc"],"titulaireIds":["fr-401802863"],"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2015-08-03","id":"ABvgimvovFWeEhoMOrKi4wAy","ordre":9,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr201-dex01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[{"type":"DESCRIPTION_OPTIONNELLE","id":"2015-08-03-arm-8bf71a65","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"arm","description":"Arrêté du 3 août 2015 prolongeant la durée de validité du permis exclusif de recherches de mines d'or et de substances connexes dit « Permis de Bon Espoir » attribué à la société Armina Ressources Minières dans le département de Guyane"}],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":60,"substances":["auru","scoc"],"titulaireIds":["fr-401802863"],"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2011-06-30","id":"nLXaR7H78V43GB47ypDoqvKz","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr201-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"men"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2011-06-29","id":"iV47juaOeL4EAUsOqiWN6gOO","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-bon-espoir-2001-pr201-mfr01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"demarches_consentement":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":60,"substances":["auru","arge","cuiv"],"titulaireIds":["fr-401802863"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.9577777777778,5.07666666666667],[-53.9575,5.0325],[-53.8944444444444,5.00055555555556],[-53.8208333333333,4.97972222222222],[-53.7138888888889,4.96388888888889],[-53.7322222222222,5.02361111111111],[-53.8763888888889,5.02277777777778],[-53.9577777777778,5.07666666666667]]]]}},"geojson4326_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9577777777778,5.07666666666667]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8763888888889,5.02277777777778]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7322222222222,5.02361111111111]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7138888888889,4.96388888888889]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8208333333333,4.97972222222222]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8944444444444,5.00055555555556]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9575,5.0325]},"properties":{"nom":"G","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.9577777777778,5.07666666666667],[-53.9575,5.0325],[-53.8944444444444,5.00055555555556],[-53.8208333333333,4.97972222222222],[-53.7138888888889,4.96388888888889],[-53.7322222222222,5.02361111111111],[-53.8763888888889,5.02277777777778],[-53.9577777777778,5.07666666666667]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9577777777778,5.07666666666667]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8763888888889,5.02277777777778]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7322222222222,5.02361111111111]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.7138888888889,4.96388888888889]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8208333333333,4.97972222222222]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.8944444444444,5.00055555555556]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.9575,5.0325]},"properties":{"nom":"G","description":null}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":122.14,"communes":[{"id":"97306","nom":"Mana"},{"id":"97311","nom":"Saint-Laurent-du-Maroni"}],"secteurs_maritimes":[],"sdom_zones":["0","2"],"forets":["LDD","PAUL"]}},"etape_type_id":"mfr","demarche_id_en_concurrence":null}],"demarche_type_id":"pr2","demarche_statut_id":"acc","demarche_date_debut":"2011-10-31","demarche_date_fin":"2016-10-31","demarche_visibilite":"Publique","machine_id":null,"ordre":3}],"nb_activites_to_do":null}) bonEspoirData.nb_activites_to_do = 0 // prettier-ignore - bonEspoirData.demarches.push(demarcheGetValidator.parse({"demarche_visibilite":"Publique", - "id": "idtravaux", "ordre": 4, "slug": "m-pr-bon-espoir-2001-dam01", "description": null, "etapes": [{ "etape_type_id": "wpo", "is_brouillon": false, "ordre": 4, note: {valeur: '', is_avertissement: false}, "etape_statut_id": "acc", "date": "2012-07-23", "id": "idEtapeTravaux1", "slug": "m-pr-bon-espoir-2001-dam01-wpo01", "sections_with_values": [], "entreprises_documents": [], "avis_documents": [], "etape_documents": [{ "id": "2012-07-23-apd-607c3aa8","type":"DESCRIPTION_OPTIONNELLE", "description": "N°2012-SPR-DRMSS-1", "etape_document_type_id": "apd", "public_lecture": false, "entreprises_lecture": false }] }, { "etape_type_id": "wpp", is_brouillon: ETAPE_IS_NOT_BROUILLON, "ordre": 3, note: { valeur: 'note importante', is_avertissement: true },"etape_statut_id": "fai","date": "2011-05-04","id": "idEtapeTravaux2","slug": "m-pr-bon-espoir-2001-dam01-wpp01","sections_with_values": [],"entreprises_documents": [],"avis_documents":[],"etape_documents": [{"id": "id_Document","type":"DESCRIPTION_OPTIONNELLE","description": "","etape_document_type_id": "apu","public_lecture": false,"entreprises_lecture": false }]}, {"etape_type_id": "wfd",is_brouillon: ETAPE_IS_NOT_BROUILLON, "ordre": 2,note: {valeur: '', is_avertissement: false}, "etape_statut_id": "fai","date": "2010-10-01","id": "idEtapeTravaux3","slug": "m-pr-bon-espoir-2001-dam01-wfd01","sections_with_values": [],"entreprises_documents": [],"etape_documents": [],"avis_documents":[]}, {"etape_type_id": "mcr",is_brouillon: ETAPE_IS_NOT_BROUILLON,"ordre": 1,note: {valeur: '', is_avertissement: false},"etape_statut_id": "fav","date": "2010-10-01","id": "idEtapeTravaux4","slug": "m-pr-bon-espoir-2001-dam01-mcr01","sections_with_values": [],"entreprises_documents": [],"etape_documents": [],"avis_documents":[]}],"demarche_type_id": "dam","demarche_statut_id": "fpm","demarche_date_debut": null,"demarche_date_fin": null - + bonEspoirData.demarches.push(demarcheGetValidator.parse({ + 'demarche_visibilite':"Publique","machine_id":null,"id": "idtravaux", "ordre": 4, "slug": "m-pr-bon-espoir-2001-dam01", "description": null, "etapes": [{ "etape_type_id": "wpo", "is_brouillon": false, "ordre": 4, note: {valeur: '', is_avertissement: false}, "etape_statut_id": "acc", "date": "2012-07-23", "id": "idEtapeTravaux1", "slug": "m-pr-bon-espoir-2001-dam01-wpo01", "sections_with_values": [], "entreprises_documents": [], "avis_documents": [], "etape_documents": [{ "id": "2012-07-23-apd-607c3aa8","type":"DESCRIPTION_OPTIONNELLE", "description": "N°2012-SPR-DRMSS-1", "etape_document_type_id": "apd", "public_lecture": false, "entreprises_lecture": false }] }, { "etape_type_id": "wpp", is_brouillon: ETAPE_IS_NOT_BROUILLON, "ordre": 3, note: { valeur: 'note importante', is_avertissement: true },"etape_statut_id": "fai","date": "2011-05-04","id": "idEtapeTravaux2","slug": "m-pr-bon-espoir-2001-dam01-wpp01","sections_with_values": [],"entreprises_documents": [],"avis_documents":[],"etape_documents": [{"id": "id_Document","type":"DESCRIPTION_OPTIONNELLE","description": "","etape_document_type_id": "apu","public_lecture": false,"entreprises_lecture": false }]}, {"etape_type_id": "wfd",is_brouillon: ETAPE_IS_NOT_BROUILLON, "ordre": 2,note: {valeur: '', is_avertissement: false}, "etape_statut_id": "fai","date": "2010-10-01","id": "idEtapeTravaux3","slug": "m-pr-bon-espoir-2001-dam01-wfd01","sections_with_values": [],"entreprises_documents": [],"etape_documents": [],"avis_documents":[]}, {"etape_type_id": "mcr",is_brouillon: ETAPE_IS_NOT_BROUILLON,"ordre": 1,note: {valeur: '', is_avertissement: false},"etape_statut_id": "fav","date": "2010-10-01","id": "idEtapeTravaux4","slug": "m-pr-bon-espoir-2001-dam01-mcr01","sections_with_values": [],"entreprises_documents": [],"etape_documents": [],"avis_documents":[]}],"demarche_type_id": "dam","demarche_statut_id": "fpm","demarche_date_debut": null,"demarche_date_fin": null })) // prettier-ignore - bonEspoirData.demarches.push(demarcheGetValidator.parse({"demarche_visibilite":"Publique","id":"KxHulLhT5XtziPhZDWpFuyA9", "ordre": 5, "slug":"m-pr-bon-espoir-2001-vct01","description":null,"etapes":[{"etape_type_id":"mcr",is_brouillon: ETAPE_IS_NOT_BROUILLON,"etape_statut_id":"fav","date":"2017-08-07","id":"OOKaEetpmAhDX17hcLEFWTZ1","ordre":4,note: {valeur: '', is_avertissement: false},"slug":"m-pr-bon-espoir-2001-vct01-mcr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"men",is_brouillon: ETAPE_IS_NOT_BROUILLON,"etape_statut_id":"fai","date":"2016-11-07","id":"fNt0G9CmdMc6iIG9x239wZ5E","ordre":2,note: {valeur: '', is_avertissement: false},"slug":"m-pr-bon-espoir-2001-vct01-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"mfr", "demarche_id_en_concurrence": null, "demarches_consentement": [],is_brouillon: ETAPE_IS_NOT_BROUILLON,"fondamentale":{"date_debut":null,"date_fin":null,"duree":180,"substances":["auru","scoc"],"titulaireIds":["fr-401802863"],"amodiataireIds":null,"perimetre":{"geojson4326_points": null,"geojson4326_forages":null,"geojson_origine_forages":null,"geojson_origine_points": null, "geojson4326_perimetre":{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-53.95781742722346,5.076877972864504],[-53.95761604147164,5.032517695391918],[-53.894654620091046,5.000735152488521],[-53.82094960753945,4.97999409410299],[-53.71414492282594,4.963998224562106],[-53.73241245985785,5.023653513799631],[-53.87657715038456,5.023033474690702],[-53.95781742722346,5.076877972864504]]]]},"properties":null}, "geojson_origine_perimetre":{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-53.95781742722346,5.076877972864504],[-53.95761604147164,5.032517695391918],[-53.894654620091046,5.000735152488521],[-53.82094960753945,4.97999409410299],[-53.71414492282594,4.963998224562106],[-53.73241245985785,5.023653513799631],[-53.87657715038456,5.023033474690702],[-53.95781742722346,5.076877972864504]]]]},"properties":null},"geojson_origine_geo_systeme_id":"4326","surface":122.275,"communes":[{"id":"97311","nom":"Saint-Laurent-du-Maroni"},{"id":"97306","nom":"Mana"}],"secteurs_maritimes":[],"sdom_zones":["0","2"],"forets":["LDD","PAUL"]}},"etape_statut_id":"fai","date":"2016-10-28","id":"VqBn5DzAtcMQWFY0CIiO6X1A","ordre":1,note: {valeur: '', is_avertissement: false},"slug":"m-pr-bon-espoir-2001-vct01-mfr01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[], "avis_documents":[]}],"demarche_type_id":"vct","demarche_statut_id":"ins","demarche_date_debut":"2016-10-31","demarche_date_fin":null})) + bonEspoirData.demarches.push(demarcheGetValidator.parse({'demarche_visibilite':"Publique","machine_id":null,"id":"KxHulLhT5XtziPhZDWpFuyA9", "ordre": 5, "slug":"m-pr-bon-espoir-2001-vct01","description":null,"etapes":[{"etape_type_id":"mcr",is_brouillon: ETAPE_IS_NOT_BROUILLON,"etape_statut_id":"fav","date":"2017-08-07","id":"OOKaEetpmAhDX17hcLEFWTZ1","ordre":4,note: {valeur: '', is_avertissement: false},"slug":"m-pr-bon-espoir-2001-vct01-mcr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"men",is_brouillon: ETAPE_IS_NOT_BROUILLON,"etape_statut_id":"fai","date":"2016-11-07","id":"fNt0G9CmdMc6iIG9x239wZ5E","ordre":2,note: {valeur: '', is_avertissement: false},"slug":"m-pr-bon-espoir-2001-vct01-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"mfr", "demarche_id_en_concurrence": null, "demarches_consentement": [],is_brouillon: ETAPE_IS_NOT_BROUILLON,"fondamentale":{"date_debut":null,"date_fin":null,"duree":180,"substances":["auru","scoc"],"titulaireIds":["fr-401802863"],"amodiataireIds":null,"perimetre":{"geojson4326_points": null,"geojson4326_forages":null,"geojson_origine_forages":null,"geojson_origine_points": null, "geojson4326_perimetre":{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-53.95781742722346,5.076877972864504],[-53.95761604147164,5.032517695391918],[-53.894654620091046,5.000735152488521],[-53.82094960753945,4.97999409410299],[-53.71414492282594,4.963998224562106],[-53.73241245985785,5.023653513799631],[-53.87657715038456,5.023033474690702],[-53.95781742722346,5.076877972864504]]]]},"properties":null}, "geojson_origine_perimetre":{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-53.95781742722346,5.076877972864504],[-53.95761604147164,5.032517695391918],[-53.894654620091046,5.000735152488521],[-53.82094960753945,4.97999409410299],[-53.71414492282594,4.963998224562106],[-53.73241245985785,5.023653513799631],[-53.87657715038456,5.023033474690702],[-53.95781742722346,5.076877972864504]]]]},"properties":null},"geojson_origine_geo_systeme_id":"4326","surface":122.275,"communes":[{"id":"97311","nom":"Saint-Laurent-du-Maroni"},{"id":"97306","nom":"Mana"}],"secteurs_maritimes":[],"sdom_zones":["0","2"],"forets":["LDD","PAUL"]}},"etape_statut_id":"fai","date":"2016-10-28","id":"VqBn5DzAtcMQWFY0CIiO6X1A","ordre":1,note: {valeur: '', is_avertissement: false},"slug":"m-pr-bon-espoir-2001-vct01-mfr01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[], "avis_documents":[]}],"demarche_type_id":"vct","demarche_statut_id":"ins","demarche_date_debut":"2016-10-31","demarche_date_fin":null})) return Promise.resolve(bonEspoirData) }, @@ -545,7 +545,7 @@ const basseManaApiClient: PropsApiClient = { getTitreAction(titreIdOrSlug) // prettier-ignore - const basseManaData = titreGetValidator.parse({ "id": "ORKjSbwrb87xE53MsYClV8OF","titre_visibilite":"Publique", "nom": "Basse Mana", "slug": "m-pr-basse-mana-2018", "titre_type_id": "prm", "titre_statut_id": "sup", "titre_doublon": null, "references": [{ "nom": "22/2018", "referenceTypeId": "dea" }, { "nom": "2016-0010-MI", "referenceTypeId": "deb" }], "titre_last_modified_date": "2023-12-19", "demarches": [{"demarche_visibilite":"Publique", "id": "GnIerujOWqlS3U06Xcbc1Dr0", "slug": "m-pr-basse-mana-2018-oct01", "description": null, "etapes": [{ "etape_type_id": "dpu", "fondamentale": { "date_debut": null, "date_fin": null, "duree": 36, "substances": ["tant", "niob", "lith", "bery", "etai", "wolf", "tita", "auru"], "titulaireIds": ["fr-790856850"], "amodiataireIds": null, "perimetre": { "geojson4326_perimetre": { "type": "Feature", "properties": {}, "geometry": { "type": "MultiPolygon", "coordinates": [[[[-53.699125239725, 5.29137675727333], [-53.735659753333, 5.24333287037071], [-53.6847736578144, 5.232646225266], [-53.664223513371, 5.23752353831223], [-53.6554344678131, 5.25034817283726], [-53.6402449164671, 5.25044876137938], [-53.6331053301638, 5.26979119871868], [-53.6650166925488, 5.27353207619541], [-53.699125239725, 5.29137675727333]]]] } }, "geojson4326_points": { "type": "FeatureCollection", "properties": {}, "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.699125239725, 5.29137675727333] }, "properties": { "nom": "A", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.6650166925488, 5.27353207619541] }, "properties": { "nom": "B", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.6331053301638, 5.26979119871868] }, "properties": { "nom": "C", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.6402449164671, 5.25044876137938] }, "properties": { "nom": "D", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.6554344678131, 5.25034817283726] }, "properties": { "nom": "E", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.664223513371, 5.23752353831223] }, "properties": { "nom": "F", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.6847736578144, 5.232646225266] }, "properties": { "nom": "G", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.735659753333, 5.24333287037071] }, "properties": { "nom": "H", "description": null } }] }, "geojson_origine_perimetre": { "type": "Feature", "properties": {}, "geometry": { "type": "MultiPolygon", "coordinates": [[[[200814, 585525], [204589, 583534], [208127, 583105], [207326, 580968], [205641, 580964], [204660, 579549], [202378, 579019], [196738, 580226], [200814, 585525]]]] } }, "geojson_origine_points": { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [200814, 585525] }, "properties": { "nom": "A" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [204589, 583534] }, "properties": { "nom": "B" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [208127, 583105] }, "properties": { "nom": "C" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [207326, 580968] }, "properties": { "nom": "D" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [205641, 580964] }, "properties": { "nom": "E" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [204660, 579549] }, "properties": { "nom": "F" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [202378, 579019] }, "properties": { "nom": "G" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [196738, 580226] }, "properties": { "nom": "H" } }] }, "geojson_origine_geo_systeme_id": "2972", "geojson4326_forages": null, "geojson_origine_forages": null, "surface": 48, "communes": [{ "id": "97306", "nom": "Mana" }], "secteurs_maritimes": [], "sdom_zones": ["2"], "forets": ["BSM"] } }, "etape_statut_id": "fai", "is_brouillon": false, "date": "2018-09-11", "id": "ooH6ZbECJPcDPFsE0McnKvUm", "ordre": 9, "note": { "valeur": "", "is_avertissement": false }, "slug": "m-pr-basse-mana-2018-oct01-dpu01", "sections_with_values": [{ "id": "prx", "nom": "Propriétés du permis exclusif de recherches", "elements": [{ "id": "engagement", "nom": "Engagement", "optionnel": true, "type": "number", "value": 150000 }, { "id": "engagementDeviseId", "nom": "Devise de l'engagement", "description": "", "optionnel": true, "type": "select", "options": [{ "id": "EUR", "nom": "Euros" }, { "id": "FRF", "nom": "Francs" }, { "id": "XPF", "nom": "Francs Pacifique" }], "value": "EUR" }] }, { "id": "publication", "nom": "Références Légifrance", "elements": [{ "id": "jorf", "nom": "Numéro JORF", "description": "", "optionnel": false, "type": "text", "value": "JORFTEXT000037382008" }, { "id": "nor", "nom": "Numéro NOR", "description": "", "optionnel": true, "type": "text", "value": "ECOL1816264A" }] }], "entreprises_documents": [], "etape_documents": [], "avis_documents": [] }, { "etape_type_id": "dex", "fondamentale": { "date_debut": null, "date_fin": null, "duree": 36, "substances": ["tant", "niob", "lith", "bery", "etai", "wolf", "tita", "auru"], "titulaireIds": ["fr-790856850"], "amodiataireIds": null, "perimetre": { "geojson4326_perimetre": { "type": "Feature", "properties": {}, "geometry": { "type": "MultiPolygon", "coordinates": [[[[-53.699125239725, 5.29137675727333], [-53.735659753333, 5.24333287037071], [-53.6847736578144, 5.232646225266], [-53.664223513371, 5.23752353831223], [-53.6554344678131, 5.25034817283726], [-53.6402449164671, 5.25044876137938], [-53.6331053301638, 5.26979119871868], [-53.6650166925488, 5.27353207619541], [-53.699125239725, 5.29137675727333]]]] } }, "geojson4326_points": { "type": "FeatureCollection", "properties": {}, "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.699125239725, 5.29137675727333] }, "properties": { "nom": "A", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.6650166925488, 5.27353207619541] }, "properties": { "nom": "B", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.6331053301638, 5.26979119871868] }, "properties": { "nom": "C", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.6402449164671, 5.25044876137938] }, "properties": { "nom": "D", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.6554344678131, 5.25034817283726] }, "properties": { "nom": "E", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.664223513371, 5.23752353831223] }, "properties": { "nom": "F", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.6847736578144, 5.232646225266] }, "properties": { "nom": "G", "description": null } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-53.735659753333, 5.24333287037071] }, "properties": { "nom": "H", "description": null } }] }, "geojson_origine_perimetre": { "type": "Feature", "properties": {}, "geometry": { "type": "MultiPolygon", "coordinates": [[[[200814, 585525], [204589, 583534], [208127, 583105], [207326, 580968], [205641, 580964], [204660, 579549], [202378, 579019], [196738, 580226], [200814, 585525]]]] } }, "geojson_origine_points": { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [200814, 585525] }, "properties": { "nom": "A" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [204589, 583534] }, "properties": { "nom": "B" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [208127, 583105] }, "properties": { "nom": "C" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [207326, 580968] }, "properties": { "nom": "D" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [205641, 580964] }, "properties": { "nom": "E" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [204660, 579549] }, "properties": { "nom": "F" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [202378, 579019] }, "properties": { "nom": "G" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [196738, 580226] }, "properties": { "nom": "H" } }] }, "geojson_origine_geo_systeme_id": "2972", "geojson4326_forages": null, "geojson_origine_forages": null, "surface": 48, "communes": [{ "id": "97306", "nom": "Mana" }], "secteurs_maritimes": [], "sdom_zones": ["2"], "forets": ["BSM"] } }, "etape_statut_id": "acc", "is_brouillon": false, "date": "2018-08-31", "id": "KJtV68vswF5ewUyF2jTuLGhS", "ordre": 8, "note": { "valeur": "", "is_avertissement": false }, "slug": "m-pr-basse-mana-2018-oct01-dex01", "sections_with_values": [{ "id": "prx", "nom": "Propriétés du permis exclusif de recherches", "elements": [{ "id": "engagement", "nom": "Engagement", "optionnel": true, "type": "number", "value": 150000 }, { "id": "engagementDeviseId", "nom": "Devise de l'engagement", "description": "", "optionnel": true, "type": "select", "options": [{ "id": "EUR", "nom": "Euros" }, { "id": "FRF", "nom": "Francs" }, { "id": "XPF", "nom": "Francs Pacifique" }], "value": "EUR" }] }, { "id": "publication", "nom": "Références Légifrance", "elements": [{ "id": "jorf", "nom": "Numéro JORF", "description": "", "optionnel": true, "type": "text", "value": "JORFTEXT000037382008" }, { "id": "nor", "nom": "Numéro NOR", "description": "", "optionnel": true, "type": "text", "value": "ECOL1816264A" }] }], "entreprises_documents": [], "etape_documents": [], "avis_documents": [] }, { "etape_type_id": "men", "etape_statut_id": "fai", "is_brouillon": false, "date": "2016-08-28", "id": "qVJM9zS6hWyIr3My5OoubQA3", "ordre": 2, "note": { "valeur": "", "is_avertissement": false }, "slug": "m-pr-basse-mana-2018-oct01-men01", "sections_with_values": [], "entreprises_documents": [], "etape_documents": [], "avis_documents": [] }, { "etape_type_id": "mfr", "demarche_id_en_concurrence": null, "demarches_consentement": [], "fondamentale": { "date_debut": null, "date_fin": null, "duree": 36, "substances": ["tant", "niob", "scoc"], "titulaireIds": null, "amodiataireIds": null, "perimetre": null }, "etape_statut_id": "fai", "is_brouillon": false, "date": "2016-06-19", "id": "abABihashClZP0lL3NUPELNV", "ordre": 1, "note": { "valeur": "", "is_avertissement": false }, "slug": "m-pr-basse-mana-2018-oct01-mfr01", "sections_with_values": [{ "id": "prx", "nom": "Propriétés du permis exclusif de recherches", "elements": [{ "id": "engagement", "nom": "Engagement", "optionnel": true, "type": "number", "value": null }, { "id": "engagementDeviseId", "nom": "Devise de l'engagement", "description": "", "optionnel": true, "type": "select", "options": [{ "id": "EUR", "nom": "Euros" }, { "id": "FRF", "nom": "Francs" }, { "id": "XPF", "nom": "Francs Pacifique" }], "value": null }] }], "entreprises_documents": [], "etape_documents": [], "avis_documents": [] }], "demarche_type_id": "oct", "demarche_statut_id": "acc", "demarche_date_debut": "2018-09-11", "demarche_date_fin": "2021-09-11", "ordre": 1 }, {"demarche_visibilite":"Publique", "id": "mZAUVvPyznbzpj3e3grjFmlJ", "slug": "m-pr-basse-mana-2018-pr101", "description": null, "etapes": [{ "etape_type_id": "rpu", "fondamentale": { "date_debut": null, "date_fin": null, "duree": null, "substances": null, "titulaireIds": null, "amodiataireIds": null, "perimetre": null }, "etape_statut_id": "fai", "is_brouillon": false, "date": "2023-11-17", "id": "f76c17ab21ca966988390d92", "ordre": 11, "note": { "valeur": "", "is_avertissement": false }, "slug": "m-pr-basse-mana-2018-pr101-rpu01", "sections_with_values": [], "entreprises_documents": [], "etape_documents": [], "avis_documents": [] }, { "etape_type_id": "dpu", "fondamentale": { "date_debut": null, "date_fin": null, "duree": null, "substances": null, "titulaireIds": null, "amodiataireIds": null, "perimetre": null }, "etape_statut_id": "fai", "is_brouillon": false, "date": "2023-11-15", "id": "71f6497117b21325d53d8e56", "ordre": 10, "note": { "valeur": "", "is_avertissement": false }, "slug": "m-pr-basse-mana-2018-pr101-dpu01", "sections_with_values": [{ "id": "publication", "nom": "Références Légifrance", "elements": [{ "id": "jorf", "nom": "Numéro JORF", "description": "", "optionnel": false, "type": "text", "value": "Texte 3 sur 160" }] }], "entreprises_documents": [], "etape_documents": [{ "id": "2023-11-15-pub-4d420801", "type": "DESCRIPTION_OPTIONNELLE", "public_lecture": true, "entreprises_lecture": true, "etape_document_type_id": "pub", "description": "" }], "avis_documents": [] }, { "etape_type_id": "dex", "fondamentale": { "date_debut": null, "date_fin": null, "duree": 30, "substances": null, "titulaireIds": null, "amodiataireIds": null, "perimetre": null }, "etape_statut_id": "acc", "is_brouillon": false, "date": "2023-11-07", "id": "590f6dd2f808eeadf51b820e", "ordre": 9, "note": { "valeur": "", "is_avertissement": false }, "slug": "m-pr-basse-mana-2018-pr101-dex01", "sections_with_values": [{ "id": "publication", "nom": "Références Légifrance", "elements": [{ "id": "jorf", "nom": "Numéro JORF", "description": "", "optionnel": true, "type": "text", "value": null }, { "id": "nor", "nom": "Numéro NOR", "description": "", "optionnel": true, "type": "text", "value": null }] }], "entreprises_documents": [], "etape_documents": [], "avis_documents": [] }, { "etape_type_id": "ppu", "etape_statut_id": "ter", "is_brouillon": false, "date": "2023-03-27", "id": "M1mK0vhAHH5CTaUwq4cJzK49", "ordre": 5, "note": { "valeur": "", "is_avertissement": false }, "slug": "m-pr-basse-mana-2018-pr101-ppu01", "sections_with_values": [{ "id": "opdp", "elements": [{ "id": "lien", "nom": "Lien public externe", "description": "", "optionnel": true, "type": "url", "value": null }, {"id": "duree", "nom": "Durée en jours de la consultation du public", "description": "", "optionnel": false, "type": "number", "value": 15}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"men","etape_statut_id":"fai","is_brouillon":false,"date":"2021-04-30","id":"wFb34sxGyHoRNOByPffQZyAF","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr101-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"mfr", "demarche_id_en_concurrence": null, "demarches_consentement": [],"fondamentale":{"date_debut":null,"date_fin":null,"duree":60,"substances":["tant","niob","lith","bery","etai","wolf","tita","auru"],"titulaireIds":["fr-790856850"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.699150462397206,5.291394409468797],[-53.73568497160258,5.2433505257409125],[-53.684798879087204,5.232663883719148],[-53.664248736219285,5.2375411971227654],[-53.65545969176547,5.250365830767107],[-53.64027014144058,5.250466419912988],[-53.633130556393525,5.269808855679936],[-53.66511918689031,5.291623119512839],[-53.699150462397206,5.291394409468797]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.699150462397206,5.291394409468797]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.66511918689031,5.291623119512839]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.633130556393525,5.269808855679936]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.64027014144058,5.250466419912988]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.65545969176547,5.250365830767107]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.664248736219285,5.2375411971227654]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.684798879087204,5.232663883719148]},"properties":{"nom":"G","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.73568497160258,5.2433505257409125]},"properties":{"nom":"H","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[200814,585525],[204589,585534],[208127,583105],[207326,580968],[205641,580964],[204660,579549],[202378,579019],[196738,580226],[200814,585525]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[200814,585525]},"properties":{"nom":"A"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204589,585534]},"properties":{"nom":"B"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[208127,583105]},"properties":{"nom":"C"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[207326,580968]},"properties":{"nom":"D"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[205641,580964]},"properties":{"nom":"E"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204660,579549]},"properties":{"nom":"F"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[202378,579019]},"properties":{"nom":"G"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[196738,580226]},"properties":{"nom":"H"}}]},"geojson_origine_geo_systeme_id":"2972","geojson4326_forages":null,"geojson_origine_forages":null,"surface":48.06,"communes":[{"id":"97306","nom":"Mana"}],"secteurs_maritimes":[],"sdom_zones":["2"],"forets":["BSM"]}},"etape_statut_id":"fai","is_brouillon":false,"date":"2021-04-30","id":"NKW0jIKc5cPBIp2dwu2VceCG","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr101-mfr01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"pr1","demarche_statut_id":"acc","demarche_date_debut":"2021-09-11","demarche_date_fin":"2024-03-11","ordre":2},{"demarche_visibilite":"Publique","id":"5df48d3536a38dd1dab542d7","slug":"m-pr-basse-mana-2018-pr201","description":"","etapes":[{"etape_type_id":"men","etape_statut_id":"fai","is_brouillon":false,"date":"2023-10-30","id":"37a1752da216067fc73328f9","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr201-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"mfr", "demarche_id_en_concurrence": null, "demarches_consentement": [],"fondamentale":{"date_debut":null,"date_fin":null,"duree":60,"substances":["tant","niob","lith","bery","etai","wolf","tita","auru"],"titulaireIds":null,"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.695977302723314,5.258026897118486],[-53.69166175320614,5.243894120712839],[-53.691207934852734,5.238962048893827],[-53.66947244758239,5.236434510036549],[-53.66426676493007,5.2375411203489115],[-53.655468706369525,5.250365792413383],[-53.64027010339901,5.25045738302719],[-53.63422022259896,5.267391338838475],[-53.64933956522329,5.274005464773927],[-53.66943759690406,5.2748050575845875],[-53.66988205803166,5.281761503749559],[-53.671594626284566,5.281690874443703],[-53.67432345044184,5.276844434310086],[-53.67742349010169,5.274481516415551],[-53.68523182828244,5.270616251350751],[-53.695977302723314,5.258026897118486]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.695977302723314,5.258026897118486]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.68523182828244,5.270616251350751]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.67742349010169,5.274481516415551]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.67432345044184,5.276844434310086]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.671594626284566,5.281690874443703]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.66988205803166,5.281761503749559]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.66943759690406,5.2748050575845875]},"properties":{"nom":"G","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.64933956522329,5.274005464773927]},"properties":{"nom":"H","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.63422022259896,5.267391338838475]},"properties":{"nom":"I","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.64027010339901,5.25045738302719]},"properties":{"nom":"J","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.655468706369525,5.250365792413383]},"properties":{"nom":"K","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.66426676493007,5.2375411203489115]},"properties":{"nom":"L","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.66947244758239,5.236434510036549]},"properties":{"nom":"M","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.691207934852734,5.238962048893827]},"properties":{"nom":"N","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.69166175320614,5.243894120712839]},"properties":{"nom":"O","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[201150,581831],[202348,583219],[203216,583643],[203561,583903],[203866,584438],[204056,584445],[204102,583675],[206331,583577],[208005,582838],[207326,580967],[205640,580964],[204658,579549],[204080,579429],[201670,579719],[201622,580265],[201150,581831]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[201150,581831]},"properties":{"nom":"A"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[202348,583219]},"properties":{"nom":"B"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[203216,583643]},"properties":{"nom":"C"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[203561,583903]},"properties":{"nom":"D"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[203866,584438]},"properties":{"nom":"E"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204056,584445]},"properties":{"nom":"F"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204102,583675]},"properties":{"nom":"G"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[206331,583577]},"properties":{"nom":"H"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[208005,582838]},"properties":{"nom":"I"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[207326,580967]},"properties":{"nom":"J"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[205640,580964]},"properties":{"nom":"K"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204658,579549]},"properties":{"nom":"L"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204080,579429]},"properties":{"nom":"M"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[201670,579719]},"properties":{"nom":"N"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[201622,580265]},"properties":{"nom":"O"}}]},"geojson_origine_geo_systeme_id":"2972","geojson4326_forages":null,"geojson_origine_forages":null,"surface":20.69,"communes":[{"id":"97306","nom":"Mana"}],"secteurs_maritimes":[],"sdom_zones":["2"],"forets":["BSM"]}},"etape_statut_id":"fai","is_brouillon":false,"date":"2023-10-30","id":"47a22a6ca44891d40e2f4149","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr201-mfr01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"pr2","demarche_statut_id":"dep","demarche_date_debut":"2024-03-11","demarche_date_fin":null,"ordre":3}],"nb_activites_to_do":null}) + const basseManaData = titreGetValidator.parse({"id":"ORKjSbwrb87xE53MsYClV8OF","nom":"Basse Mana","slug":"m-pr-basse-mana-2018","titre_type_id":"prm","titre_statut_id":"sup","titre_visibilite":"Publique","titre_doublon":null,"references":[{"nom":"22/2018","referenceTypeId":"dea"},{"nom":"2016-0010-MI","referenceTypeId":"deb"},{"nom":"R16-08","referenceTypeId":"dea"},{"nom":"R23-02","referenceTypeId":"dea"}],"titre_last_modified_date":null,"demarches":[{"id":"GnIerujOWqlS3U06Xcbc1Dr0","slug":"m-pr-basse-mana-2018-oct01","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2018-09-11","id":"ooH6ZbECJPcDPFsE0McnKvUm","ordre":9,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-oct01-dpu01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":150000},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":"EUR"}]},{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000037382008"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOL1816264A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":36,"substances":["tant","niob","lith","bery","etai","wolf","tita","auru"],"titulaireIds":["fr-790856850"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.699125239725,5.29137675727333],[-53.735659753333,5.24333287037071],[-53.6847736578144,5.232646225266],[-53.664223513371,5.23752353831223],[-53.6554344678131,5.25034817283726],[-53.6402449164671,5.25044876137938],[-53.6331053301638,5.26979119871868],[-53.6650166925488,5.27353207619541],[-53.699125239725,5.29137675727333]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.699125239725,5.29137675727333]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.6650166925488,5.27353207619541]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.6331053301638,5.26979119871868]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.6402449164671,5.25044876137938]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.6554344678131,5.25034817283726]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.664223513371,5.23752353831223]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.6847736578144,5.232646225266]},"properties":{"nom":"G","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.735659753333,5.24333287037071]},"properties":{"nom":"H","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[200814,585525],[204589,583534],[208127,583105],[207326,580968],[205641,580964],[204660,579549],[202378,579019],[196738,580226],[200814,585525]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[200814,585525]},"properties":{"nom":"A"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204589,583534]},"properties":{"nom":"B"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[208127,583105]},"properties":{"nom":"C"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[207326,580968]},"properties":{"nom":"D"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[205641,580964]},"properties":{"nom":"E"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204660,579549]},"properties":{"nom":"F"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[202378,579019]},"properties":{"nom":"G"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[196738,580226]},"properties":{"nom":"H"}}]},"geojson_origine_geo_systeme_id":"2972","geojson4326_forages":null,"geojson_origine_forages":null,"surface":48,"communes":[{"id":"97306","nom":"Mana"}],"secteurs_maritimes":[],"sdom_zones":["2"],"forets":["BSM"]}},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2018-08-31","id":"KJtV68vswF5ewUyF2jTuLGhS","ordre":8,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-oct01-dex01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":150000},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":"EUR"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":36,"substances":["tant","niob","lith","bery","etai","wolf","tita","auru"],"titulaireIds":["fr-790856850"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.699125239725,5.29137675727333],[-53.735659753333,5.24333287037071],[-53.6847736578144,5.232646225266],[-53.664223513371,5.23752353831223],[-53.6554344678131,5.25034817283726],[-53.6402449164671,5.25044876137938],[-53.6331053301638,5.26979119871868],[-53.6650166925488,5.27353207619541],[-53.699125239725,5.29137675727333]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.699125239725,5.29137675727333]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.6650166925488,5.27353207619541]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.6331053301638,5.26979119871868]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.6402449164671,5.25044876137938]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.6554344678131,5.25034817283726]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.664223513371,5.23752353831223]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.6847736578144,5.232646225266]},"properties":{"nom":"G","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.735659753333,5.24333287037071]},"properties":{"nom":"H","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[200814,585525],[204589,583534],[208127,583105],[207326,580968],[205641,580964],[204660,579549],[202378,579019],[196738,580226],[200814,585525]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[200814,585525]},"properties":{"nom":"A"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204589,583534]},"properties":{"nom":"B"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[208127,583105]},"properties":{"nom":"C"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[207326,580968]},"properties":{"nom":"D"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[205641,580964]},"properties":{"nom":"E"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204660,579549]},"properties":{"nom":"F"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[202378,579019]},"properties":{"nom":"G"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[196738,580226]},"properties":{"nom":"H"}}]},"geojson_origine_geo_systeme_id":"2972","geojson4326_forages":null,"geojson_origine_forages":null,"surface":48,"communes":[{"id":"97306","nom":"Mana"}],"secteurs_maritimes":[],"sdom_zones":["2"],"forets":["BSM"]}},"etape_type_id":"dex"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2016-08-28","id":"qVJM9zS6hWyIr3My5OoubQA3","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-oct01-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"men"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2016-06-19","id":"abABihashClZP0lL3NUPELNV","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-oct01-mfr01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"demarches_consentement":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":36,"substances":["tant","niob","scoc"],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"mfr","demarche_id_en_concurrence":null}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"2018-09-11","demarche_date_fin":"2021-09-11","demarche_visibilite":"Publique","machine_id":null,"ordre":1},{"id":"mZAUVvPyznbzpj3e3grjFmlJ","slug":"m-pr-basse-mana-2018-pr101","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2023-11-17","id":"f76c17ab21ca966988390d92","ordre":9,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr101-rpu01","sections_with_values":[{"id":"praa","nom":"Propriétés de la publication","elements":[{"id":"numeroRAA","nom":"Numéro de RAA ","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"rpu"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2023-11-15","id":"71f6497117b21325d53d8e56","ordre":8,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr101-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"Texte 3 sur 160"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"type":"DESCRIPTION_OPTIONNELLE","id":"2023-11-15-pub-4d420801","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"pub","description":""}],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2023-11-07","id":"590f6dd2f808eeadf51b820e","ordre":7,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr101-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":30,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"},{"etape_statut_id":"ter","is_brouillon":false,"date":"2023-03-27","id":"M1mK0vhAHH5CTaUwq4cJzK49","ordre":5,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr101-ppu01","sections_with_values":[{"id":"opdp","elements":[{"id":"lien","nom":"Lien public externe","description":"","optionnel":true,"type":"url","value":null},{"id":"duree","nom":"Durée en jours de la consultation du public","optionnel":false,"type":"number","value":18}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"ppu"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2021-04-30","id":"NKW0jIKc5cPBIp2dwu2VceCG","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr101-mfr01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"demarches_consentement":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":60,"substances":["tant","niob","lith","bery","etai","wolf","tita","auru"],"titulaireIds":["fr-790856850"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.699150462397206,5.291394409468797],[-53.73568497160258,5.2433505257409125],[-53.684798879087204,5.232663883719148],[-53.664248736219285,5.2375411971227654],[-53.65545969176547,5.250365830767107],[-53.64027014144058,5.250466419912988],[-53.633130556393525,5.269808855679936],[-53.66511918689031,5.291623119512839],[-53.699150462397206,5.291394409468797]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.699150462397206,5.291394409468797]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.66511918689031,5.291623119512839]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.633130556393525,5.269808855679936]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.64027014144058,5.250466419912988]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.65545969176547,5.250365830767107]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.664248736219285,5.2375411971227654]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.684798879087204,5.232663883719148]},"properties":{"nom":"G","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.73568497160258,5.2433505257409125]},"properties":{"nom":"H","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[200814,585525],[204589,585534],[208127,583105],[207326,580968],[205641,580964],[204660,579549],[202378,579019],[196738,580226],[200814,585525]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[200814,585525]},"properties":{"nom":"A"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204589,585534]},"properties":{"nom":"B"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[208127,583105]},"properties":{"nom":"C"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[207326,580968]},"properties":{"nom":"D"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[205641,580964]},"properties":{"nom":"E"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204660,579549]},"properties":{"nom":"F"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[202378,579019]},"properties":{"nom":"G"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[196738,580226]},"properties":{"nom":"H"}}]},"geojson_origine_geo_systeme_id":"2972","geojson4326_forages":null,"geojson_origine_forages":null,"surface":48.06,"communes":[{"id":"97306","nom":"Mana"}],"secteurs_maritimes":[],"sdom_zones":["2"],"forets":["BSM"]}},"etape_type_id":"mfr","demarche_id_en_concurrence":null},{"etape_statut_id":"fai","is_brouillon":false,"date":"2021-04-30","id":"wFb34sxGyHoRNOByPffQZyAF","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr101-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"men"}],"demarche_type_id":"pr1","demarche_statut_id":"acc","demarche_date_debut":"2021-09-11","demarche_date_fin":"2024-03-11","demarche_visibilite":"Publique","machine_id":null,"ordre":2},{"id":"5df48d3536a38dd1dab542d7","slug":"m-pr-basse-mana-2018-pr201","description":"","etapes":[{"etape_statut_id":"fav","is_brouillon":false,"date":"2024-05-17","id":"e72a53fdb3bdffacf1f4fdef","ordre":5,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr201-mcr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"mcr"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2023-10-30","id":"37a1752da216067fc73328f9","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr201-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"men"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2023-10-30","id":"47a22a6ca44891d40e2f4149","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-pr-basse-mana-2018-pr201-mfr01","sections_with_values":[{"id":"prx","nom":"Propriétés du permis exclusif de recherches","elements":[{"id":"engagement","nom":"Engagement","optionnel":true,"type":"number","value":null},{"id":"engagementDeviseId","nom":"Devise de l'engagement","description":"","optionnel":true,"type":"select","options":[{"id":"EUR","nom":"Euros"},{"id":"FRF","nom":"Francs"},{"id":"XPF","nom":"Francs Pacifique"}],"value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"demarches_consentement":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":60,"substances":["tant","niob","lith","bery","etai","wolf","tita","auru"],"titulaireIds":null,"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.695977302723314,5.258026897118486],[-53.69166175320614,5.243894120712839],[-53.691207934852734,5.238962048893827],[-53.66947244758239,5.236434510036549],[-53.66426676493007,5.2375411203489115],[-53.655468706369525,5.250365792413383],[-53.64027010339901,5.25045738302719],[-53.63422022259896,5.267391338838475],[-53.64933956522329,5.274005464773927],[-53.66943759690406,5.2748050575845875],[-53.66988205803166,5.281761503749559],[-53.671594626284566,5.281690874443703],[-53.67432345044184,5.276844434310086],[-53.67742349010169,5.274481516415551],[-53.68523182828244,5.270616251350751],[-53.695977302723314,5.258026897118486]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.695977302723314,5.258026897118486]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.68523182828244,5.270616251350751]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.67742349010169,5.274481516415551]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.67432345044184,5.276844434310086]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.671594626284566,5.281690874443703]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.66988205803166,5.281761503749559]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.66943759690406,5.2748050575845875]},"properties":{"nom":"G","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.64933956522329,5.274005464773927]},"properties":{"nom":"H","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.63422022259896,5.267391338838475]},"properties":{"nom":"I","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.64027010339901,5.25045738302719]},"properties":{"nom":"J","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.655468706369525,5.250365792413383]},"properties":{"nom":"K","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.66426676493007,5.2375411203489115]},"properties":{"nom":"L","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.66947244758239,5.236434510036549]},"properties":{"nom":"M","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.691207934852734,5.238962048893827]},"properties":{"nom":"N","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-53.69166175320614,5.243894120712839]},"properties":{"nom":"O","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[201150,581831],[202348,583219],[203216,583643],[203561,583903],[203866,584438],[204056,584445],[204102,583675],[206331,583577],[208005,582838],[207326,580967],[205640,580964],[204658,579549],[204080,579429],[201670,579719],[201622,580265],[201150,581831]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[201150,581831]},"properties":{"nom":"A"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[202348,583219]},"properties":{"nom":"B"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[203216,583643]},"properties":{"nom":"C"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[203561,583903]},"properties":{"nom":"D"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[203866,584438]},"properties":{"nom":"E"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204056,584445]},"properties":{"nom":"F"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204102,583675]},"properties":{"nom":"G"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[206331,583577]},"properties":{"nom":"H"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[208005,582838]},"properties":{"nom":"I"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[207326,580967]},"properties":{"nom":"J"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[205640,580964]},"properties":{"nom":"K"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204658,579549]},"properties":{"nom":"L"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[204080,579429]},"properties":{"nom":"M"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[201670,579719]},"properties":{"nom":"N"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[201622,580265]},"properties":{"nom":"O"}}]},"geojson_origine_geo_systeme_id":"2972","geojson4326_forages":null,"geojson_origine_forages":null,"surface":20.69,"communes":[{"id":"97306","nom":"Mana"}],"secteurs_maritimes":[],"sdom_zones":["2"],"forets":["BSM"]}},"etape_type_id":"mfr","demarche_id_en_concurrence":null}],"demarche_type_id":"pr2","demarche_statut_id":"ins","demarche_date_debut":"2024-03-11","demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":3}],"nb_activites_to_do":null}) return Promise.resolve(basseManaData) }, @@ -736,7 +736,7 @@ const lenoncourtApiClient: PropsApiClient = { getTitreAction(titreIdOrSlug) // prettier-ignore - const lenoncourtData = titreGetValidator.parse({"id":"s7RvqvCAgKs4DxkQBYV93cVx","titre_visibilite":"Publique","nom":"Lenoncourt","slug":"m-cx-lenoncourt-1968","titre_type_id":"cxm","titre_statut_id":"val","titre_doublon":null,"references":[{"nom":"2013-0275-MI","referenceTypeId":"deb"},{"nom":"54TM0153","referenceTypeId":"rnt"}],"titre_last_modified_date":"2024-03-21","demarches":[{"demarche_visibilite":"Publique","id":"ozYnUjy40eru81jUnXz5snv2","slug":"m-cx-lenoncourt-1968-oct01","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"1968-01-24","id":"SG2zAN9QaKBN1hZKqKEgQGpI","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-oct01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"id":"1968-01-24-dec-89a94bb2","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":"Décret du 13 janvier 1968 instituant la concession de mines de sels de sodium de Lenoncourt (Meurthe-et-Moselle) au profit de la société Les Soudières réunies - La Madeleine-Varangéville"}],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"1968-01-13","id":"LM2Zk3PwAjrduc4EqmucOjeB","ordre":1,"note":{"valeur":"Décret du 13 janvier 1968 instituant la concession de mines de sels de sodium de Lenoncourt (Meurthe-et-Moselle) au profit de la société Les Soudières réunies - La Madeleine-Varangéville","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-oct01-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"1968-01-24","demarche_date_fin":"2024-03-01","ordre":1},{"demarche_visibilite":"Publique","id":"wM0cpipWSef9lDAHDurJxxhk","slug":"m-cx-lenoncourt-1968-mut01","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["selg","selh"],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"1970-11-19","id":"XScxzwDKFxmYtDnkJ7X7qZBi","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"id":"1970-11-19-dec-8a77b142","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":"Décret du 16 novembre 1970 autorisant la mutation de propriété de cinq concessions de mines de sel gemme et de sources salées au profit de la société Produits chimiques Pechlney-Saint-Gobaln."}],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":["fr-606320471"],"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"1970-11-16","id":"ejAqTpzBj82jgF0ShiwMRQmW","ordre":1,"note":{"valeur":"Décret du 16 novembre 1970 autorisant la mutation de propriété de cinq concessions de mines de sel gemme et de sources salées au profit de la société Produits chimiques Pechlney-Saint-Gobaln.","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut01-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"ordre":2},{"demarche_visibilite":"Publique","id":"1UC2b0ORsm2ezCh6whHzbOKR","slug":"m-cx-lenoncourt-1968-mut02","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["selg","selh"],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"1975-11-27","id":"TjimKkEETzF0yGBG2m085on9","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut02-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"id":"1975-11-27-dec-b50a06f5","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":"Décret du 24 novembre 1975 autorisant la mutation de cinq concessions de mines de sel gemme et de sources salées au profit de la Compagnie industrielle et minière"}],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":["fr-712025048"],"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"1975-11-24","id":"aYO0zwBFBOZP7VN11JaJDhzI","ordre":1,"note":{"valeur":"Décret du 24 novembre 1975 autorisant la mutation de cinq concessions de mines de sel gemme et de sources salées au profit de la Compagnie industrielle et minière","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut02-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"ordre":3},{"demarche_visibilite":"Publique","id":"H5eANAZPKhY9eFQtCyLYjCvp","slug":"m-cx-lenoncourt-1968-exp01","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":["fr-712025048"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.275644095814427,48.6854960696669],[6.255874124806144,48.675237870291575],[6.295319143383101,48.66801114312286],[6.316241924966296,48.676189123934925],[6.315656943097024,48.680413137182065],[6.307671761547864,48.69027442550079],[6.302487495007789,48.68919858322589],[6.296317613859298,48.68917495187758],[6.290997693817669,48.68780534512822],[6.285653764289864,48.68913324659737],[6.281744418990354,48.68911774206666],[6.275644095814427,48.6854960696669]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[6.275644095814427,48.6854960696669]},"properties":{"nom":"A","description":"Point situé sur la ligne joignant les clochers de Saulxures-lès-Nancy et de Buissoncourt, à son intersection avec la limite des communes de Saulxures-lès-Nancy et de Lenoncourt, soit à environ 2040 mètres à l'Est-Sud-Est du clocher de Saulxures-lès-Nancy"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.281744418990354,48.68911774206666]},"properties":{"nom":"B1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.285653764289864,48.68913324659737]},"properties":{"nom":"C1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.290997693817669,48.68780534512822]},"properties":{"nom":"D1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.296317613859298,48.68917495187758]},"properties":{"nom":"E1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.302487495007789,48.68919858322589]},"properties":{"nom":"F1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.307671761547864,48.69027442550079]},"properties":{"nom":"G1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.315656943097024,48.680413137182065]},"properties":{"nom":"B","description":"Point situé sur la ligne joignant les clochers de Saulxures-lès-Nancy et de Buissoncourt, à son intersection avec la limite Ouest de la concession de Cercueil-Buissoncourt, soit à environ 2 150 mètres au Nord-Nord-Ouest du clocher de Buissoncourt"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.316241924966296,48.676189123934925]},"properties":{"nom":"C","description":"Borne commune aux concessions d'Art-sur-Meurthe et de Cercueil-Buissoncourt"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.295319143383101,48.66801114312286]},"properties":{"nom":"D","description":"Sommet A de la concession d'Art-sur-Meurthe:"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.255874124806144,48.675237870291575]},"properties":{"nom":"E","description":"Sommet M de la concession d'Art-sur•Meurthe:"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[889907.42,1117010.26],[890334.9,1117435.93],[890622.24,1117452.72],[891022.89,1117325.88],[891406.04,1117498.53],[891859.53,1117525.03],[892234.39,1117664.59],[892879.34,1116600.52],[892947.15,1116133.73],[891456.2,1115144.46],[888513.03,1115795.21],[889907.42,1117010.26]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[889907.42,1117010.26]},"properties":{"nom":"A","description":"Point situé sur la ligne joignant les clochers de Saulxures-lès-Nancy et de Buissoncourt, à son intersection avec la limite des communes de Saulxures-lès-Nancy et de Lenoncourt, soit à environ 2040 mètres à l’Est-Sud-Est du clocher de Saulxures-lès-Nancy"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[890334.9,1117435.93]},"properties":{"nom":"B1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[890622.24,1117452.72]},"properties":{"nom":"C1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[891022.89,1117325.88]},"properties":{"nom":"D1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[891406.04,1117498.53]},"properties":{"nom":"E1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[891859.53,1117525.03]},"properties":{"nom":"F1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[892234.39,1117664.59]},"properties":{"nom":"G1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[892879.34,1116600.52]},"properties":{"nom":"B","description":"Point situé sur la ligne joignant les clochers de Saulxures-lès-Nancy et de Buissoncourt, à son intersection avec la limite Ouest de la concession de Cercueil-Buissoncourt, soit à environ 2 150 mètres au Nord-Nord-Ouest du clocher de Buissoncourt"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[892947.15,1116133.73]},"properties":{"nom":"C","description":"Borne commune aux concessions d’Art-sur-Meurthe et de Cercueil-Buissoncourt"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[891456.2,1115144.46]},"properties":{"nom":"D","description":"Sommet A de la concession d’Art-sur-Meurthe:"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[888513.03,1115795.21]},"properties":{"nom":"E","description":"Sommet M de la concession d’Art-sur•Meurthe:"}}]},"geojson_origine_geo_systeme_id":"27571","geojson4326_forages":null,"geojson_origine_forages":null,"surface":6.75,"communes":[{"id":"54495","nom":"Saulxures-lès-Nancy"},{"id":"54311","nom":"Lenoncourt"},{"id":"54110","nom":"Cerville"},{"id":"54025","nom":"Art-sur-Meurthe"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_statut_id":"fai","is_brouillon":false,"date":"1981-09-13","id":"C6UHWZDSFnLbwuaeksXG1SEj","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-exp01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"N"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"id":"1981-09-13-dec-8bf8fa4c","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":"Décret du 9 septembre 1981 portant extension de superficie de la concession des mines de sels de sodium de Lenoncourt (Meurthe-et-Moselle) et modifiant les conditions auxquelles est soumise ladite concession"}],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"1981-09-09","id":"xHxKuYk5goClAaZr1hxGaCyr","ordre":1,"note":{"valeur":"Décret du 9 septembre 1981 portant extension de superficie de la concession des mines de sels de sodium de Lenoncourt (Meurthe-et-Moselle) et modifiant les conditions auxquelles est soumise ladite concession","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-exp01-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"exp","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"ordre":4},{"demarche_visibilite":"Publique","id":"W9IX7VanFA5iYxYAGulcA0CY","slug":"m-cx-lenoncourt-1968-mut03","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":["fr-442993283"],"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"2000-10-06","id":"wuYTEAQ5UUAUZxiowQIthgkg","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut03-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000000208330"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOI0000456A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"2000-09-26","id":"f2iSnn7XPrOXDIrbmYFKUiz1","ordre":1,"note":{"valeur":"Arrêté du 26 septembre 2000 autorisant la mutation de concessions de mines","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut03-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"ordre":6},{"demarche_visibilite":"Publique","id":"md9yLbhZSOqdcOANAAyUPTur","slug":"m-cx-lenoncourt-1968-mut04","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":["fr-642014526"],"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"2003-01-08","id":"yuMPprDNtN6mZzdmlVTDd25I","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut04-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000000228627"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"INDI0200856A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"2002-12-24","id":"jZRW7aZo5DmTABnQCe35wVrh","ordre":1,"note":{"valeur":"Arrêté du 24 décembre 2002 autorisant la mutation de concessions de mines","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut04-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"ordre":7},{"demarche_visibilite":"Publique","id":"3W0rdHS1VqDSIQjZ1mLD8b9L","slug":"m-cx-lenoncourt-1968-mut05","description":null,"etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":["fr-442993283"],"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"2004-02-28","id":"isgwwZGJwv7UDuJvtxAaj3T4","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut05-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000000434866"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"INDI0402498A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"2004-02-13","id":"Full4Vnptm6czWaJ4b6kZR6W","ordre":1,"note":{"valeur":"Arrêté du 13 février 2004 autorisant la mutation d’une concession de mines de sels de sodium","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut05-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"ordre":8},{"demarche_visibilite":"Publique","id":"fA9NJsMZ78XyG402LUdm2Szi","slug":"m-cx-lenoncourt-1968-pro01","description":"prolongation et extension de périmètre","etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"2024-03-01","id":"a0af6a2e56cd046cd72c71cf","ordre":16,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000049219226"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOL2320431D"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"acc","is_brouillon":false,"date":"2024-02-29","id":"aa23dc021366330e04383eba","ordre":15,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"id":"2024-02-29-dec-12df6369","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":""},{"id":"2024-02-29-dec-4bb7fd91","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":""}],"avis_documents":[]},{"etape_type_id":"adc","etape_statut_id":"fai","is_brouillon":false,"date":"2021-06-01","id":"ryW6mbg2cC906CimQRgdVhvd","ordre":7,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-adc01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"epu","etape_statut_id":"ter","is_brouillon":false,"date":"2021-04-20","id":"d1PRxUd0F9JHQSziUQ3skOem","ordre":6,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-epu01","sections_with_values":[{"id":"epu","elements":[{"id":"lien","nom":"Lien public externe","description":"","optionnel":true,"type":"url","value":null},{"id":"duree","nom":"Durée en jours de l'enquête publique","description":"","optionnel":false,"type":"number","value":43}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"mcr","etape_statut_id":"fav","is_brouillon":false,"date":"2021-01-27","id":"pHf3m1Hygp8kz8d7G0j2TKgZ","ordre":4,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-mcr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"men","etape_statut_id":"fai","is_brouillon":false,"date":"2020-08-04","id":"mQnOvtSGpc1T83bSvOOorVOa","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"mfr", "demarche_id_en_concurrence": null, "demarches_consentement": [],"fondamentale":{"date_debut":null,"date_fin":null,"duree":300,"substances":["nacl"],"titulaireIds":["fr-442993283"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.255869021711159,48.675202067410254],[6.263459497281365,48.6611397799328],[6.274477936823362,48.661530617274785],[6.29531036181682,48.66798716858568],[6.3162302722649795,48.67616624512283],[6.31565519531486,48.68038643555574],[6.307660371971501,48.69025022534333],[6.302480013569365,48.68917854238857],[6.2963188041374485,48.68915103738882],[6.290983811108587,48.68777705995633],[6.285642745098623,48.68911271820202],[6.281739260684181,48.68909422269382],[6.275638319504659,48.68547207905551],[6.255869021711159,48.675202067410254]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[6.255869021711159,48.675202067410254]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.275638319504659,48.68547207905551]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.281739260684181,48.68909422269382]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.285642745098623,48.68911271820202]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.290983811108587,48.68777705995633]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2963188041374485,48.68915103738882]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.302480013569365,48.68917854238857]},"properties":{"nom":"G","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.307660371971501,48.69025022534333]},"properties":{"nom":"H","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.31565519531486,48.68038643555574]},"properties":{"nom":"I","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3162302722649795,48.67616624512283]},"properties":{"nom":"J","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.29531036181682,48.66798716858568]},"properties":{"nom":"K","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.274477936823362,48.661530617274785]},"properties":{"nom":"L","description":"Nouveau sommet « d’extension » défini par NOVACARB"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.263459497281365,48.6611397799328]},"properties":{"nom":"M","description":"Nouveau sommet « d’extension » défini par NOVACARB"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[939659,6846613],[941066,6847814],[941498,6848235],[941785,6848249],[942184,6848117],[942570,6848286],[943023,6848308],[943399,6848443],[944033,6847372],[944095,6846905],[942594,6845932],[941091,6845151],[940282,6845074],[939659,6846613]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[939659,6846613]},"properties":{"nom":"A"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[941066,6847814]},"properties":{"nom":"B"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[941498,6848235]},"properties":{"nom":"C"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[941785,6848249]},"properties":{"nom":"D"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[942184,6848117]},"properties":{"nom":"E"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[942570,6848286]},"properties":{"nom":"F"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[943023,6848308]},"properties":{"nom":"G"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[943399,6848443]},"properties":{"nom":"H"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[944033,6847372]},"properties":{"nom":"I"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[944095,6846905]},"properties":{"nom":"J"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[942594,6845932]},"properties":{"nom":"K"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[941091,6845151]},"properties":{"nom":"L","description":"Nouveau sommet « d’extension » défini par NOVACARB"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[940282,6845074]},"properties":{"nom":"M","description":"Nouveau sommet « d’extension » défini par NOVACARB"}}]},"geojson_origine_geo_systeme_id":"2154","geojson4326_forages":null,"geojson_origine_forages":null,"surface":9.05,"communes":[{"id":"54495","nom":"Saulxures-lès-Nancy"},{"id":"54311","nom":"Lenoncourt"},{"id":"54110","nom":"Cerville"},{"id":"54025","nom":"Art-sur-Meurthe"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_statut_id":"fai","is_brouillon":false,"date":"2020-07-06","id":"mh70cpBA8jOZWCEDJKupM4Rs","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-mfr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]}],"demarche_type_id":"pro","demarche_statut_id":"acc","demarche_date_debut":"2024-03-01","demarche_date_fin":"2049-03-01","ordre":11},{"demarche_visibilite":"Publique","id":"b7586ad241a658ae1eb42b08","slug":"m-cx-lenoncourt-1968-exp02","description":"","etapes":[{"etape_type_id":"dpu","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_statut_id":"fai","is_brouillon":false,"date":"2024-03-01","id":"e48a19b86d090feadc67a893","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-exp02-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":false,"type":"text","value":"JORFTEXT000049219226"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOL2320431D"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[]},{"etape_type_id":"dex","fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":["fr-442993283"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.2559,48.6752],[6.2756,48.6855],[6.2817,48.6891],[6.2856,48.6891],[6.291,48.6878],[6.2963,48.6892],[6.3025,48.6892],[6.3076,48.689],[6.3157,48.6804],[6.3162,48.6762],[6.2953,48.668],[6.2794,48.6631],[6.2614,48.6649],[6.2559,48.6752]]]]}},"geojson4326_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2559,48.6752]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2756,48.6855]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2817,48.6891]},"properties":{"nom":"B1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2856,48.6891]},"properties":{"nom":"C1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.291,48.6878]},"properties":{"nom":"D1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2963,48.6892]},"properties":{"nom":"E1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3025,48.6892]},"properties":{"nom":"F1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3076,48.689]},"properties":{"nom":"G1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3157,48.6804]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3162,48.6762]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2953,48.668]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2794,48.6631]},"properties":{"nom":"Da","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2614,48.6649]},"properties":{"nom":"Db","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2559,48.6752]},"properties":{"nom":"E","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.2559,48.6752],[6.2756,48.6855],[6.2817,48.6891],[6.2856,48.6891],[6.291,48.6878],[6.2963,48.6892],[6.3025,48.6892],[6.3076,48.689],[6.3157,48.6804],[6.3162,48.6762],[6.2953,48.668],[6.2794,48.6631],[6.2614,48.6649],[6.2559,48.6752]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2559,48.6752]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2756,48.6855]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2817,48.6891]},"properties":{"nom":"B1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2856,48.6891]},"properties":{"nom":"C1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.291,48.6878]},"properties":{"nom":"D1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2963,48.6892]},"properties":{"nom":"E1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3025,48.6892]},"properties":{"nom":"F1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3076,48.689]},"properties":{"nom":"G1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3157,48.6804]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3162,48.6762]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2953,48.668]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2794,48.6631]},"properties":{"nom":"Da","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2614,48.6649]},"properties":{"nom":"Db","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2559,48.6752]},"properties":{"nom":"E","description":null}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":8.65,"communes":[{"id":"54495","nom":"Saulxures-lès-Nancy"},{"id":"54311","nom":"Lenoncourt"},{"id":"54110","nom":"Cerville"},{"id":"54025","nom":"Art-sur-Meurthe"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_statut_id":"acc","is_brouillon":false,"date":"2024-02-29","id":"c15f4ceaa62a6298a2f8e117","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-exp02-dex01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"","optionnel":true,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"id":"2024-02-29-dec-d9f1e868","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":""},{"id":"2024-02-29-dec-32312304","type":"DESCRIPTION_OPTIONNELLE","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":""}],"avis_documents":[]}],"demarche_type_id":"exp","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"ordre":12}],"nb_activites_to_do":null}) + const lenoncourtData = titreGetValidator.parse({"id":"s7RvqvCAgKs4DxkQBYV93cVx","nom":"Lenoncourt","slug":"m-cx-lenoncourt-1968","titre_type_id":"cxm","titre_statut_id":"val","titre_visibilite":"Publique","titre_doublon":null,"references":[{"nom":"2013-0275-MI","referenceTypeId":"deb"},{"nom":"54TM0153","referenceTypeId":"rnt"}],"titre_last_modified_date":null,"demarches":[{"id":"ozYnUjy40eru81jUnXz5snv2","slug":"m-cx-lenoncourt-1968-oct01","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"1968-01-24","id":"SG2zAN9QaKBN1hZKqKEgQGpI","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-oct01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"type":"DESCRIPTION_OPTIONNELLE","id":"1968-01-24-dec-89a94bb2","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":"Décret du 13 janvier 1968 instituant la concession de mines de sels de sodium de Lenoncourt (Meurthe-et-Moselle) au profit de la société Les Soudières réunies - La Madeleine-Varangéville"}],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"1968-01-13","id":"LM2Zk3PwAjrduc4EqmucOjeB","ordre":1,"note":{"valeur":"Décret du 13 janvier 1968 instituant la concession de mines de sels de sodium de Lenoncourt (Meurthe-et-Moselle) au profit de la société Les Soudières réunies - La Madeleine-Varangéville","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-oct01-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"}],"demarche_type_id":"oct","demarche_statut_id":"acc","demarche_date_debut":"1968-01-24","demarche_date_fin":"2024-03-01","demarche_visibilite":"Publique","machine_id":null,"ordre":1},{"id":"wM0cpipWSef9lDAHDurJxxhk","slug":"m-cx-lenoncourt-1968-mut01","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"1970-11-19","id":"XScxzwDKFxmYtDnkJ7X7qZBi","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"type":"DESCRIPTION_OPTIONNELLE","id":"1970-11-19-dec-8a77b142","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":"Décret du 16 novembre 1970 autorisant la mutation de propriété de cinq concessions de mines de sel gemme et de sources salées au profit de la société Produits chimiques Pechlney-Saint-Gobaln."}],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["selg","selh"],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"1970-11-16","id":"ejAqTpzBj82jgF0ShiwMRQmW","ordre":1,"note":{"valeur":"Décret du 16 novembre 1970 autorisant la mutation de propriété de cinq concessions de mines de sel gemme et de sources salées au profit de la société Produits chimiques Pechlney-Saint-Gobaln.","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut01-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":["fr-606320471"],"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":2},{"id":"1UC2b0ORsm2ezCh6whHzbOKR","slug":"m-cx-lenoncourt-1968-mut02","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"1975-11-27","id":"TjimKkEETzF0yGBG2m085on9","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut02-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":null},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"type":"DESCRIPTION_OPTIONNELLE","id":"1975-11-27-dec-b50a06f5","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":"Décret du 24 novembre 1975 autorisant la mutation de cinq concessions de mines de sel gemme et de sources salées au profit de la Compagnie industrielle et minière"}],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["selg","selh"],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"1975-11-24","id":"aYO0zwBFBOZP7VN11JaJDhzI","ordre":1,"note":{"valeur":"Décret du 24 novembre 1975 autorisant la mutation de cinq concessions de mines de sel gemme et de sources salées au profit de la Compagnie industrielle et minière","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut02-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":["fr-712025048"],"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":3},{"id":"H5eANAZPKhY9eFQtCyLYjCvp","slug":"m-cx-lenoncourt-1968-exp01","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"1981-09-13","id":"C6UHWZDSFnLbwuaeksXG1SEj","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-exp01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"N"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":null}]}],"entreprises_documents":[],"etape_documents":[{"type":"DESCRIPTION_OPTIONNELLE","id":"1981-09-13-dec-8bf8fa4c","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":"Décret du 9 septembre 1981 portant extension de superficie de la concession des mines de sels de sodium de Lenoncourt (Meurthe-et-Moselle) et modifiant les conditions auxquelles est soumise ladite concession"}],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":["fr-712025048"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.275644095814427,48.6854960696669],[6.255874124806144,48.675237870291575],[6.295319143383101,48.66801114312286],[6.316241924966296,48.676189123934925],[6.315656943097024,48.680413137182065],[6.307671761547864,48.69027442550079],[6.302487495007789,48.68919858322589],[6.296317613859298,48.68917495187758],[6.290997693817669,48.68780534512822],[6.285653764289864,48.68913324659737],[6.281744418990354,48.68911774206666],[6.275644095814427,48.6854960696669]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[6.275644095814427,48.6854960696669]},"properties":{"nom":"A","description":"Point situé sur la ligne joignant les clochers de Saulxures-lès-Nancy et de Buissoncourt, à son intersection avec la limite des communes de Saulxures-lès-Nancy et de Lenoncourt, soit à environ 2040 mètres à l'Est-Sud-Est du clocher de Saulxures-lès-Nancy"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.281744418990354,48.68911774206666]},"properties":{"nom":"B1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.285653764289864,48.68913324659737]},"properties":{"nom":"C1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.290997693817669,48.68780534512822]},"properties":{"nom":"D1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.296317613859298,48.68917495187758]},"properties":{"nom":"E1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.302487495007789,48.68919858322589]},"properties":{"nom":"F1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.307671761547864,48.69027442550079]},"properties":{"nom":"G1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.315656943097024,48.680413137182065]},"properties":{"nom":"B","description":"Point situé sur la ligne joignant les clochers de Saulxures-lès-Nancy et de Buissoncourt, à son intersection avec la limite Ouest de la concession de Cercueil-Buissoncourt, soit à environ 2 150 mètres au Nord-Nord-Ouest du clocher de Buissoncourt"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.316241924966296,48.676189123934925]},"properties":{"nom":"C","description":"Borne commune aux concessions d'Art-sur-Meurthe et de Cercueil-Buissoncourt"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.295319143383101,48.66801114312286]},"properties":{"nom":"D","description":"Sommet A de la concession d'Art-sur-Meurthe:"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.255874124806144,48.675237870291575]},"properties":{"nom":"E","description":"Sommet M de la concession d'Art-sur•Meurthe:"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[889907.42,1117010.26],[890334.9,1117435.93],[890622.24,1117452.72],[891022.89,1117325.88],[891406.04,1117498.53],[891859.53,1117525.03],[892234.39,1117664.59],[892879.34,1116600.52],[892947.15,1116133.73],[891456.2,1115144.46],[888513.03,1115795.21],[889907.42,1117010.26]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[889907.42,1117010.26]},"properties":{"nom":"A","description":"Point situé sur la ligne joignant les clochers de Saulxures-lès-Nancy et de Buissoncourt, à son intersection avec la limite des communes de Saulxures-lès-Nancy et de Lenoncourt, soit à environ 2040 mètres à l’Est-Sud-Est du clocher de Saulxures-lès-Nancy"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[890334.9,1117435.93]},"properties":{"nom":"B1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[890622.24,1117452.72]},"properties":{"nom":"C1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[891022.89,1117325.88]},"properties":{"nom":"D1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[891406.04,1117498.53]},"properties":{"nom":"E1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[891859.53,1117525.03]},"properties":{"nom":"F1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[892234.39,1117664.59]},"properties":{"nom":"G1"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[892879.34,1116600.52]},"properties":{"nom":"B","description":"Point situé sur la ligne joignant les clochers de Saulxures-lès-Nancy et de Buissoncourt, à son intersection avec la limite Ouest de la concession de Cercueil-Buissoncourt, soit à environ 2 150 mètres au Nord-Nord-Ouest du clocher de Buissoncourt"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[892947.15,1116133.73]},"properties":{"nom":"C","description":"Borne commune aux concessions d’Art-sur-Meurthe et de Cercueil-Buissoncourt"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[891456.2,1115144.46]},"properties":{"nom":"D","description":"Sommet A de la concession d’Art-sur-Meurthe:"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[888513.03,1115795.21]},"properties":{"nom":"E","description":"Sommet M de la concession d’Art-sur•Meurthe:"}}]},"geojson_origine_geo_systeme_id":"27571","geojson4326_forages":null,"geojson_origine_forages":null,"surface":6.75,"communes":[{"id":"54025","nom":"Art-sur-Meurthe"},{"id":"54110","nom":"Cerville"},{"id":"54311","nom":"Lenoncourt"},{"id":"54495","nom":"Saulxures-lès-Nancy"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"1981-09-09","id":"xHxKuYk5goClAaZr1hxGaCyr","ordre":1,"note":{"valeur":"Décret du 9 septembre 1981 portant extension de superficie de la concession des mines de sels de sodium de Lenoncourt (Meurthe-et-Moselle) et modifiant les conditions auxquelles est soumise ladite concession","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-exp01-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"}],"demarche_type_id":"exp","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":4},{"id":"D9Mo17XmpzCAr4SLdVAKbPPS","slug":"m-cx-lenoncourt-1968-aom01","description":null,"etapes":[{"etape_statut_id":"ter","is_brouillon":false,"date":"2000-06-07","id":"U1ylgIqovJcLUMZwU7MVy9C8","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-aom01-epu01","sections_with_values":[{"id":"epu","elements":[{"id":"lien","nom":"Lien public externe","description":"","optionnel":true,"type":"url","value":null},{"id":"duree","nom":"Durée en jours de l'enquête publique","optionnel":false,"type":"number","value":30}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"epu"}],"demarche_type_id":"aom","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":5},{"id":"W9IX7VanFA5iYxYAGulcA0CY","slug":"m-cx-lenoncourt-1968-mut03","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2000-10-06","id":"wuYTEAQ5UUAUZxiowQIthgkg","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut03-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000000208330"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOI0000456A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":["fr-442993283"],"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2000-09-26","id":"f2iSnn7XPrOXDIrbmYFKUiz1","ordre":1,"note":{"valeur":"Arrêté du 26 septembre 2000 autorisant la mutation de concessions de mines","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut03-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":6},{"id":"md9yLbhZSOqdcOANAAyUPTur","slug":"m-cx-lenoncourt-1968-mut04","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2003-01-08","id":"yuMPprDNtN6mZzdmlVTDd25I","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut04-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000000228627"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"INDI0200856A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":["fr-642014526"],"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2002-12-24","id":"jZRW7aZo5DmTABnQCe35wVrh","ordre":1,"note":{"valeur":"Arrêté du 24 décembre 2002 autorisant la mutation de concessions de mines","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut04-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":7},{"id":"3W0rdHS1VqDSIQjZ1mLD8b9L","slug":"m-cx-lenoncourt-1968-mut05","description":null,"etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2004-02-28","id":"isgwwZGJwv7UDuJvtxAaj3T4","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut05-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000000434866"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"INDI0402498A"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":["fr-442993283"],"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2004-02-13","id":"Full4Vnptm6czWaJ4b6kZR6W","ordre":1,"note":{"valeur":"Arrêté du 13 février 2004 autorisant la mutation d’une concession de mines de sels de sodium","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-mut05-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":[],"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"}],"demarche_type_id":"mut","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":8},{"id":"owienIKBTyuI4fqnMnnxQcr7","slug":"m-cx-lenoncourt-1968-aom02","description":null,"etapes":[{"etape_statut_id":"ter","is_brouillon":false,"date":"2012-05-15","id":"AwMURNmnalaI4nbg9xjGV3Pd","ordre":3,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-aom02-epu01","sections_with_values":[{"id":"epu","elements":[{"id":"lien","nom":"Lien public externe","description":"","optionnel":true,"type":"url","value":null},{"id":"duree","nom":"Durée en jours de l'enquête publique","optionnel":false,"type":"number","value":31}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"epu"},{"etape_statut_id":"fav","is_brouillon":false,"date":"2012-02-29","id":"X4ls8xEATv3kZlpv5DvmSVMD","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-aom02-mcr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"mcr"}],"demarche_type_id":"aom","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":9},{"id":"FadRy9eULBgbbAIZN5SAb8Ko","slug":"m-cx-lenoncourt-1968-aom03","description":null,"etapes":[{"etape_statut_id":"ter","is_brouillon":false,"date":"2019-05-31","id":"pqAQb6FvFPod5sINYb8dFoGI","ordre":3,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-aom03-epu01","sections_with_values":[{"id":"epu","elements":[{"id":"lien","nom":"Lien public externe","description":"","optionnel":true,"type":"url","value":null},{"id":"duree","nom":"Durée en jours de l'enquête publique","optionnel":false,"type":"number","value":42}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"epu"},{"etape_statut_id":"fav","is_brouillon":false,"date":"2019-03-11","id":"BnLPo5p3gS2D4yKWoFCqR3vb","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-aom03-mcr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"mcr"}],"demarche_type_id":"aom","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":10},{"id":"fA9NJsMZ78XyG402LUdm2Szi","slug":"m-cx-lenoncourt-1968-pro01","description":"prolongation et extension de périmètre","etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2024-03-01","id":"a0af6a2e56cd046cd72c71cf","ordre":14,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000049219226"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOL2320431D"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2024-02-29","id":"aa23dc021366330e04383eba","ordre":13,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[{"type":"DESCRIPTION_OPTIONNELLE","id":"2024-02-29-dec-12df6369","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":""},{"type":"DESCRIPTION_OPTIONNELLE","id":"2024-02-29-dec-4bb7fd91","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":""}],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dex"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2021-06-01","id":"ryW6mbg2cC906CimQRgdVhvd","ordre":7,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-adc01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"adc"},{"etape_statut_id":"ter","is_brouillon":false,"date":"2021-04-20","id":"d1PRxUd0F9JHQSziUQ3skOem","ordre":6,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-epu01","sections_with_values":[{"id":"epu","elements":[{"id":"lien","nom":"Lien public externe","description":"","optionnel":true,"type":"url","value":null},{"id":"duree","nom":"Durée en jours de l'enquête publique","optionnel":false,"type":"number","value":43}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"epu"},{"etape_statut_id":"fav","is_brouillon":false,"date":"2021-01-27","id":"pHf3m1Hygp8kz8d7G0j2TKgZ","ordre":4,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-mcr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"mcr"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2020-08-04","id":"mQnOvtSGpc1T83bSvOOorVOa","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-men01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"etape_type_id":"men"},{"etape_statut_id":"fai","is_brouillon":false,"date":"2020-07-06","id":"mh70cpBA8jOZWCEDJKupM4Rs","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-pro01-mfr01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"demarches_consentement":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":300,"substances":["nacl"],"titulaireIds":["fr-442993283"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.255869021711159,48.675202067410254],[6.263459497281365,48.6611397799328],[6.274477936823362,48.661530617274785],[6.29531036181682,48.66798716858568],[6.3162302722649795,48.67616624512283],[6.31565519531486,48.68038643555574],[6.307660371971501,48.69025022534333],[6.302480013569365,48.68917854238857],[6.2963188041374485,48.68915103738882],[6.290983811108587,48.68777705995633],[6.285642745098623,48.68911271820202],[6.281739260684181,48.68909422269382],[6.275638319504659,48.68547207905551],[6.255869021711159,48.675202067410254]]]]}},"geojson4326_points":{"type":"FeatureCollection","properties":{},"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[6.255869021711159,48.675202067410254]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.275638319504659,48.68547207905551]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.281739260684181,48.68909422269382]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.285642745098623,48.68911271820202]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.290983811108587,48.68777705995633]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2963188041374485,48.68915103738882]},"properties":{"nom":"F","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.302480013569365,48.68917854238857]},"properties":{"nom":"G","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.307660371971501,48.69025022534333]},"properties":{"nom":"H","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.31565519531486,48.68038643555574]},"properties":{"nom":"I","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3162302722649795,48.67616624512283]},"properties":{"nom":"J","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.29531036181682,48.66798716858568]},"properties":{"nom":"K","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.274477936823362,48.661530617274785]},"properties":{"nom":"L","description":"Nouveau sommet « d’extension » défini par NOVACARB"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.263459497281365,48.6611397799328]},"properties":{"nom":"M","description":"Nouveau sommet « d’extension » défini par NOVACARB"}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[939659,6846613],[941066,6847814],[941498,6848235],[941785,6848249],[942184,6848117],[942570,6848286],[943023,6848308],[943399,6848443],[944033,6847372],[944095,6846905],[942594,6845932],[941091,6845151],[940282,6845074],[939659,6846613]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[939659,6846613]},"properties":{"nom":"A"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[941066,6847814]},"properties":{"nom":"B"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[941498,6848235]},"properties":{"nom":"C"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[941785,6848249]},"properties":{"nom":"D"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[942184,6848117]},"properties":{"nom":"E"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[942570,6848286]},"properties":{"nom":"F"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[943023,6848308]},"properties":{"nom":"G"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[943399,6848443]},"properties":{"nom":"H"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[944033,6847372]},"properties":{"nom":"I"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[944095,6846905]},"properties":{"nom":"J"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[942594,6845932]},"properties":{"nom":"K"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[941091,6845151]},"properties":{"nom":"L","description":"Nouveau sommet « d’extension » défini par NOVACARB"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[940282,6845074]},"properties":{"nom":"M","description":"Nouveau sommet « d’extension » défini par NOVACARB"}}]},"geojson_origine_geo_systeme_id":"2154","geojson4326_forages":null,"geojson_origine_forages":null,"surface":9.05,"communes":[{"id":"54025","nom":"Art-sur-Meurthe"},{"id":"54110","nom":"Cerville"},{"id":"54311","nom":"Lenoncourt"},{"id":"54495","nom":"Saulxures-lès-Nancy"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_type_id":"mfr","demarche_id_en_concurrence":null}],"demarche_type_id":"pro","demarche_statut_id":"acc","demarche_date_debut":"2024-03-01","demarche_date_fin":"2049-03-01","demarche_visibilite":"Publique","machine_id":null,"ordre":11},{"id":"b7586ad241a658ae1eb42b08","slug":"m-cx-lenoncourt-1968-exp02","description":"","etapes":[{"etape_statut_id":"fai","is_brouillon":false,"date":"2024-03-01","id":"e48a19b86d090feadc67a893","ordre":2,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-exp02-dpu01","sections_with_values":[{"id":"publication","nom":"Références Légifrance","elements":[{"id":"jorf","nom":"Numéro JORF","description":"Le numéro de JORF à rentrer est la dernière partie de l'URL du JORF. <br /> Par exemple dans l'URL https://www.legifrance.gouv.fr/jorf/id/JORFTEXTXXXXXXXXXX le numéro est <b>JORFTEXTXXXXXXXXXX</b>","optionnel":false,"type":"text","value":"JORFTEXT000049219226"},{"id":"nor","nom":"Numéro NOR","description":"","optionnel":true,"type":"text","value":"ECOL2320431D"}]}],"entreprises_documents":[],"etape_documents":[],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":null,"titulaireIds":null,"amodiataireIds":null,"perimetre":null},"etape_type_id":"dpu"},{"etape_statut_id":"acc","is_brouillon":false,"date":"2024-02-29","id":"c15f4ceaa62a6298a2f8e117","ordre":1,"note":{"valeur":"","is_avertissement":false},"slug":"m-cx-lenoncourt-1968-exp02-dex01","sections_with_values":[],"entreprises_documents":[],"etape_documents":[{"type":"DESCRIPTION_OPTIONNELLE","id":"2024-02-29-dec-d9f1e868","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":""},{"type":"DESCRIPTION_OPTIONNELLE","id":"2024-02-29-dec-32312304","public_lecture":true,"entreprises_lecture":true,"etape_document_type_id":"dec","description":""}],"avis_documents":[],"fondamentale":{"date_debut":null,"date_fin":null,"duree":null,"substances":["nacl"],"titulaireIds":["fr-442993283"],"amodiataireIds":null,"perimetre":{"geojson4326_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.2559,48.6752],[6.2756,48.6855],[6.2817,48.6891],[6.2856,48.6891],[6.291,48.6878],[6.2963,48.6892],[6.3025,48.6892],[6.3076,48.689],[6.3157,48.6804],[6.3162,48.6762],[6.2953,48.668],[6.2794,48.6631],[6.2614,48.6649],[6.2559,48.6752]]]]}},"geojson4326_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2559,48.6752]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2756,48.6855]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2817,48.6891]},"properties":{"nom":"B1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2856,48.6891]},"properties":{"nom":"C1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.291,48.6878]},"properties":{"nom":"D1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2963,48.6892]},"properties":{"nom":"E1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3025,48.6892]},"properties":{"nom":"F1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3076,48.689]},"properties":{"nom":"G1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3157,48.6804]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3162,48.6762]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2953,48.668]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2794,48.6631]},"properties":{"nom":"Da","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2614,48.6649]},"properties":{"nom":"Db","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2559,48.6752]},"properties":{"nom":"E","description":null}}]},"geojson_origine_perimetre":{"type":"Feature","properties":{},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.2559,48.6752],[6.2756,48.6855],[6.2817,48.6891],[6.2856,48.6891],[6.291,48.6878],[6.2963,48.6892],[6.3025,48.6892],[6.3076,48.689],[6.3157,48.6804],[6.3162,48.6762],[6.2953,48.668],[6.2794,48.6631],[6.2614,48.6649],[6.2559,48.6752]]]]}},"geojson_origine_points":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2559,48.6752]},"properties":{"nom":"E","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2756,48.6855]},"properties":{"nom":"A","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2817,48.6891]},"properties":{"nom":"B1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2856,48.6891]},"properties":{"nom":"C1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.291,48.6878]},"properties":{"nom":"D1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2963,48.6892]},"properties":{"nom":"E1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3025,48.6892]},"properties":{"nom":"F1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3076,48.689]},"properties":{"nom":"G1","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3157,48.6804]},"properties":{"nom":"B","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.3162,48.6762]},"properties":{"nom":"C","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2953,48.668]},"properties":{"nom":"D","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2794,48.6631]},"properties":{"nom":"Da","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2614,48.6649]},"properties":{"nom":"Db","description":null}},{"type":"Feature","geometry":{"type":"Point","coordinates":[6.2559,48.6752]},"properties":{"nom":"E","description":null}}]},"geojson_origine_geo_systeme_id":"4326","geojson4326_forages":null,"geojson_origine_forages":null,"surface":8.65,"communes":[{"id":"54025","nom":"Art-sur-Meurthe"},{"id":"54110","nom":"Cerville"},{"id":"54311","nom":"Lenoncourt"},{"id":"54495","nom":"Saulxures-lès-Nancy"}],"secteurs_maritimes":[],"sdom_zones":[],"forets":[]}},"etape_type_id":"dex"}],"demarche_type_id":"exp","demarche_statut_id":"acc","demarche_date_debut":null,"demarche_date_fin":null,"demarche_visibilite":"Publique","machine_id":null,"ordre":12}],"nb_activites_to_do":null}) return Promise.resolve(lenoncourtData) }, @@ -802,6 +802,7 @@ export const TitreAvecUnOctroiEnConstructionEtUnTravaux: StoryFn = () => ( { ...titre.demarches[0], demarche_date_debut: null, + machine_id: 'ProcedureSpecifique', }, { id: demarcheIdValidator.parse('idtravaux'), @@ -814,6 +815,7 @@ export const TitreAvecUnOctroiEnConstructionEtUnTravaux: StoryFn = () => ( demarche_date_debut: null, demarche_date_fin: null, demarche_visibilite: 'Confidentielle', + machine_id: null, }, ], }) diff --git a/packages/ui/src/components/titre.stories_snapshots_BasseManaMod.html b/packages/ui/src/components/titre.stories_snapshots_BasseManaMod.html index 2ac6e2f493d0f7188e9a4aae993758aab6adca4a..30d8cd539135e2f9d3d75bf102bce14ca4f54086 100644 --- a/packages/ui/src/components/titre.stories_snapshots_BasseManaMod.html +++ b/packages/ui/src/components/titre.stories_snapshots_BasseManaMod.html @@ -17,6 +17,8 @@ </div> <div class="fr-mt-2w">Références<div style="font-weight: 500;">DEAL : 22/2018</div> <div style="font-weight: 500;">DEB : 2016-0010-MI</div> + <div style="font-weight: 500;">DEAL : R16-08</div> + <div style="font-weight: 500;">DEAL : R23-02</div> </div> <div class="fr-grid-row fr-grid-row--middle fr-mt-4w"> <!----> @@ -39,8 +41,8 @@ <h2>Phases</h2> <ul> <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir la phase Octroi du 11-09-2018" aria-label="Voir la phase Octroi du 11-09-2018" tab-index="-1">Voir la phase Octroi du 11-09-2018</a></li> + <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir l'événement Prolongation 2 du 2024-05-17 lié à la phase Octroi" aria-label="Voir l'événement Prolongation 2 du 2024-05-17 lié à la phase Octroi" tab-index="-1">Voir l'événement Prolongation 2 du 17-05-2024 lié à la phase Octroi</a></li> <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir la phase Prolongation 1 du 11-09-2021" aria-label="Voir la phase Prolongation 1 du 11-09-2021" aria-current="page" tab-index="-1">Voir la phase Prolongation 1 du 11-09-2021</a></li> - <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir l'événement Prolongation 2 du 2023-10-30 lié à la phase Prolongation 1" aria-label="Voir l'événement Prolongation 2 du 2023-10-30 lié à la phase Prolongation 1" tab-index="-1">Voir l'événement Prolongation 2 du 30-10-2023 lié à la phase Prolongation 1</a></li> </ul> <div style="overflow-x: auto;" aria-hidden="true" tabindex="-1"> <div class="fr-mx-4w"> @@ -56,11 +58,11 @@ </div> <div style="display: flex; width: 100%;"> <div style="display: flex; gap: 5px; position: relative; height: 20px; flex: 1;"> - <div class="_phasesContainer_b2e482" style="flex: 1;"><a tabindex="-1" href="/mocked-href" title="Octroi" class="_phase_b2e482" aria-label="Octroi" style="min-width: 200px;"></a></div> - <div style="border: 2px solid black;"></div> - <div class="_phasesContainer_b2e482" style="flex: 1;"><a tabindex="-1" href="/mocked-href" title="Prolongation 1" class="_phase_b2e482" aria-label="Prolongation 1" aria-current="page" style="min-width: 200px;"><a tabindex="-1" href="/mocked-href" title="Prolongation 2" class="_event_b2e482" aria-label="Prolongation 2" aria-describedby="timeline-event-m-pr-basse-mana-2018-pr201"> + <div class="_phasesContainer_b2e482" style="flex: 1;"><a tabindex="-1" href="/mocked-href" title="Octroi" class="_phase_b2e482" aria-label="Octroi" style="min-width: 200px;"><a tabindex="-1" href="/mocked-href" title="Prolongation 2" class="_event_b2e482" aria-label="Prolongation 2" aria-describedby="timeline-event-m-pr-basse-mana-2018-pr201"> <!----> </a></a></div> + <div style="border: 2px solid black;"></div> + <div class="_phasesContainer_b2e482" style="flex: 1;"><a tabindex="-1" href="/mocked-href" title="Prolongation 1" class="_phase_b2e482" aria-label="Prolongation 1" aria-current="page" style="min-width: 200px;"></a></div> <!----> </div> <div style="border-width: 0px 4px 4px 0px; padding: 8px; display: inline-block; transform: rotate(-45deg); margin-left: -20px;"></div> @@ -497,8 +499,8 @@ <div> <div class="fr-text--sm fr-mb-0">Durée en jours de la consultation du public</div> <div class="fr-text--md fr-mb-0" style="font-weight: 500;"> - <p>15 - <!----><span class="fr-info-text fr-mt-0">Du 27-03-2023 au 10-04-2023 (inclus)</span> + <p>18 + <!----><span class="fr-info-text fr-mt-0">Du 27-03-2023 au 13-04-2023 (inclus)</span> </p> </div> </div> diff --git a/packages/ui/src/components/titre.stories_snapshots_BonEspoirOctroi.html b/packages/ui/src/components/titre.stories_snapshots_BonEspoirOctroi.html index 910a4e7c13e0422297b1f9024e357cbead4d6c53..501993d3bc6017452f65d80ee3069dd55f20e53d 100644 --- a/packages/ui/src/components/titre.stories_snapshots_BonEspoirOctroi.html +++ b/packages/ui/src/components/titre.stories_snapshots_BonEspoirOctroi.html @@ -120,7 +120,14 @@ <div class="fr-text--sm fr-mb-0">Substances</div> <div class="fr-text--md fr-mb-0" style="font-weight: 500;">Or, Substances connexes</div> </div> - <!----> + <div> + <div class="fr-text--sm fr-mb-0">Titulaire</div> + <div class="fr-text--md fr-mb-0" style="font-weight: 500;"> + <ul class="fr-m-0 fr-p-0" style="list-style: none;"> + <li><a href="/mocked-href" title="ARMINA RESSOURCES MINIERES SARL" class="fr-link" aria-label="ARMINA RESSOURCES MINIERES SARL">ARMINA RESSOURCES MINIERES SARL</a></li> + </ul> + </div> + </div> <!----> <div> <div class="fr-text--sm fr-mb-0">Administrations</div> @@ -359,7 +366,7 @@ </div> </div> <div style="display: flex;"> - <div class="fr-text--md">Surface : 465.5 Km²</div><a class="fr-btn fr-btn--secondary fr-btn--icon-right fr-icon-download-line" title="Télécharge les points au format csv" href="data:text/csv;charset=utf-8,nom;description;longitude;latitude;x_deg;y_deg%0A1;;-53.9579321010744;5.07776938770113;-53%C2%B057,476';5%C2%B04,666'%0A2;;-53.7596128864516;5.07864912381548;-53%C2%B045,577';5%C2%B04,719'%0A3;;-53.759383911755;5.02460196044417;-53%C2%B045,563';5%C2%B01,476'%0A4;;-53.5702069576163;5.02537608911083;-53%C2%B034,212';5%C2%B01,523'%0A5;;-53.5698730075868;4.93952315477954;-53%C2%B034,192';4%C2%B056,371'%0A6;;-53.7769878916108;4.93868722476635;-53%C2%B046,619';4%C2%B056,321'%0A7;;-53.7770631139658;4.95670276466037;-53%C2%B046,624';4%C2%B057,402'%0A8;;-53.8672265271601;4.95631734759459;-53%C2%B052,034';4%C2%B057,379'%0A9;;-53.8673626701318;4.98775355007457;-53%C2%B052,042';4%C2%B059,265'%0A10;;-53.9575232150351;4.98735333700249;-53%C2%B057,451';4%C2%B059,241'" download="points-m-pr-bon-espoir-2001.csv" style="margin-left: auto;">.csv</a> + <div class="fr-text--md">Surface : 464.71 Km²</div><a class="fr-btn fr-btn--secondary fr-btn--icon-right fr-icon-download-line" title="Télécharge les points au format csv" href="data:text/csv;charset=utf-8,nom;description;longitude;latitude;x_deg;y_deg%0A1;;-53.9579321010744;5.07776938770113;-53%C2%B057,476';5%C2%B04,666'%0A2;;-53.7596128864516;5.07864912381548;-53%C2%B045,577';5%C2%B04,719'%0A3;;-53.759383911755;5.02460196044417;-53%C2%B045,563';5%C2%B01,476'%0A4;;-53.5702069576163;5.02537608911083;-53%C2%B034,212';5%C2%B01,523'%0A5;;-53.5698730075868;4.93952315477954;-53%C2%B034,192';4%C2%B056,371'%0A6;;-53.7769878916108;4.93868722476635;-53%C2%B046,619';4%C2%B056,321'%0A7;;-53.7770631139658;4.95670276466037;-53%C2%B046,624';4%C2%B057,402'%0A8;;-53.8672265271601;4.95631734759459;-53%C2%B052,034';4%C2%B057,379'%0A9;;-53.8673626701318;4.98775355007457;-53%C2%B052,042';4%C2%B059,265'%0A10;;-53.9575232150351;4.98735333700249;-53%C2%B057,451';4%C2%B059,241'" download="points-m-pr-bon-espoir-2001.csv" style="margin-left: auto;">.csv</a> </div> </div> <!----> @@ -405,6 +412,62 @@ <div class="fr-text--sm fr-mb-0">Date de début</div> <div class="fr-text--md fr-mb-0" style="font-weight: 500;">01-11-2001</div> </div> + <!----> + <!----> + <!----> + <!----> + <!----> + <!----> + <div> + <div class="fr-text--sm fr-mb-0">Numéro JORF</div> + <div class="fr-text--md fr-mb-0" style="font-weight: 500;"> + <p><a target="_blank" rel="noopener noreferrer" href="https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000000774145" title="Numéro JORF Légifrance - Lien externe">JORFTEXT000000774145</a></p> + </div> + </div> + <div> + <div class="fr-text--sm fr-mb-0">Numéro NOR</div> + <div class="fr-text--md fr-mb-0" style="font-weight: 500;"> + <p>ECOI0100462D + <!----> + <!----> + </p> + </div> + </div> + <!----> + </div> + <!----> + <!----> + <!----> + <!----> + <!----> + </div> + </div> + <div class="fr-pb-2w"> + <div class="fr-pb-2w fr-pl-2w fr-pr-2w fr-tile--shadow"> + <div class="_sticky_964a6e fr-pt-1w"> + <div style="display: flex; justify-content: space-between; align-items: center;"> + <div style="display: flex;"> + <h4 class="fr-text--lg fr-mb-0" style="color: var(--text-title-blue-france); font-weight: 500;">Décision de l'autorité administrative</h4> + <!----> + </div> + <div style="display: flex; gap: 0.25rem;"> + <!----> + <!----> + <!----> + </div> + </div> + <p style="z-index: unset; margin-bottom: 0px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="fr-badge fr-badge--md fr-badge--green-bourgeon" title="accepté" aria-label="accepté">accepté</p> + <div style="display: flex; justify-content: space-between; align-items: center;"> + <div class="fr-mt-1w"><span class="fr-icon-calendar-line" style="color: var(--text-title-blue-france);" aria-hidden="true"></span> 24-10-2001</div> + <div> + <p style="z-index: unset; margin-bottom: 0px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="fr-badge fr-badge--md fr-badge--green-bourgeon" title="Étape publique" aria-label="Étape publique">Étape publique</p> + </div> + </div> + </div> + <!----> + <div class="fr-mb-3w fr-mt-3w" style="height: 1px; width: 100%; background-color: var(--grey-900-175);"></div> + <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); align-content: flex-start; column-gap: 16px; row-gap: 8px;"> + <!----> <div> <div class="fr-text--sm fr-mb-0">Durée</div> <div class="fr-text--md fr-mb-0" style="font-weight: 500;"><span><span>5 ans</span> @@ -417,11 +480,18 @@ <div class="fr-text--sm fr-mb-0">Substances</div> <div class="fr-text--md fr-mb-0" style="font-weight: 500;">Or, Substances connexes</div> </div> - <!----> + <div> + <div class="fr-text--sm fr-mb-0">Titulaire</div> + <div class="fr-text--md fr-mb-0" style="font-weight: 500;"> + <ul class="fr-m-0 fr-p-0" style="list-style: none;"> + <li><a href="/mocked-href" title="ARMINA RESSOURCES MINIERES SARL" class="fr-link" aria-label="ARMINA RESSOURCES MINIERES SARL">ARMINA RESSOURCES MINIERES SARL</a></li> + </ul> + </div> + </div> <!----> <div> <div class="fr-text--sm fr-mb-0">Surface</div> - <div class="fr-text--md fr-mb-0" style="font-weight: 500;">465,5 km² environ</div> + <div class="fr-text--md fr-mb-0" style="font-weight: 500;">464,71 km² environ</div> </div> <div> <div class="fr-text--sm fr-mb-0">Engagement</div> @@ -441,33 +511,21 @@ </p> </div> </div> - <div> - <div class="fr-text--sm fr-mb-0">Numéro JORF</div> - <div class="fr-text--md fr-mb-0" style="font-weight: 500;"> - <p><a target="_blank" rel="noopener noreferrer" href="https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000000774145" title="Numéro JORF Légifrance - Lien externe">JORFTEXT000000774145</a></p> - </div> - </div> - <div> - <div class="fr-text--sm fr-mb-0">Numéro NOR</div> - <div class="fr-text--md fr-mb-0" style="font-weight: 500;"> - <p>ECOI0100462D - <!----> - <!----> - </p> - </div> + <div style="grid-column: 1 / -1; white-space: pre-line;"> + <div class="fr-text--sm fr-mb-0">Notes</div> + <div class="fr-text--md fr-mb-0" style="font-weight: 500;">Décret du 24 octobre 2001 accordant un permis de recherches A en Guyane</div> </div> - <!----> </div> <div class="fr-pt-2w"> <div class="fr-tabs" style="--tabs-height: 0px;"> <ul class="fr-tabs__list" role="tablist" aria-label="Affichage des titres en vue carte ou tableau"> - <li role="presentation"><button id="tabpanel-carte-CRVhvEIQAc319vUd8BfZoH5W" class="fr-tabs__tab fr-icon-earth-fill fr-tabs__tab--icon-left" tabindex="-1" role="tab" aria-label="Carte" aria-selected="false" aria-controls="tabpanel-carte-CRVhvEIQAc319vUd8BfZoH5W-panel">Carte</button></li> - <li role="presentation"><button id="tabpanel-points-CRVhvEIQAc319vUd8BfZoH5W" class="fr-tabs__tab fr-icon-list-unordered fr-tabs__tab--icon-left" tabindex="0" role="tab" aria-label="Tableau" aria-selected="true" aria-controls="tabpanel-points-CRVhvEIQAc319vUd8BfZoH5W-panel">Tableau</button></li> + <li role="presentation"><button id="tabpanel-carte-Ce4K8goEZzjqXRJLL051jcpD" class="fr-tabs__tab fr-icon-earth-fill fr-tabs__tab--icon-left" tabindex="-1" role="tab" aria-label="Carte" aria-selected="false" aria-controls="tabpanel-carte-Ce4K8goEZzjqXRJLL051jcpD-panel">Carte</button></li> + <li role="presentation"><button id="tabpanel-points-Ce4K8goEZzjqXRJLL051jcpD" class="fr-tabs__tab fr-icon-list-unordered fr-tabs__tab--icon-left" tabindex="0" role="tab" aria-label="Tableau" aria-selected="true" aria-controls="tabpanel-points-Ce4K8goEZzjqXRJLL051jcpD-panel">Tableau</button></li> </ul> - <div id="tabpanel-carte-CRVhvEIQAc319vUd8BfZoH5W-panel" class="fr-tabs__panel fr-tabs__panel--direction-start" role="tabpanel" aria-labelledby="tabpanel-carte-CRVhvEIQAc319vUd8BfZoH5W" tabindex="0"> + <div id="tabpanel-carte-Ce4K8goEZzjqXRJLL051jcpD-panel" class="fr-tabs__panel fr-tabs__panel--direction-start" role="tabpanel" aria-labelledby="tabpanel-carte-Ce4K8goEZzjqXRJLL051jcpD" tabindex="0"> <!----> </div> - <div id="tabpanel-points-CRVhvEIQAc319vUd8BfZoH5W-panel" class="fr-tabs__panel fr-tabs__panel--selected" role="tabpanel" aria-labelledby="tabpanel-points-CRVhvEIQAc319vUd8BfZoH5W" tabindex="0"> + <div id="tabpanel-points-Ce4K8goEZzjqXRJLL051jcpD-panel" class="fr-tabs__panel fr-tabs__panel--selected" role="tabpanel" aria-labelledby="tabpanel-points-Ce4K8goEZzjqXRJLL051jcpD" tabindex="0"> <div style="display: flex; flex-direction: column;"> <div class="fr-select-group"><label class="fr-label" for="4326">Système géographique</label> <div id="4326_wrapper" class="_typeahead_8eddf1"> @@ -655,7 +713,7 @@ </div> </div> <div style="display: flex;"> - <div class="fr-text--md">Surface : 465.5 Km²</div><a class="fr-btn fr-btn--secondary fr-btn--icon-right fr-icon-download-line" title="Télécharge les points au format csv" href="data:text/csv;charset=utf-8,nom;description;longitude;latitude;x_deg;y_deg%0A1;;-53.9579321010744;5.07776938770113;-53%C2%B057,476';5%C2%B04,666'%0A2;;-53.7596128864516;5.07864912381548;-53%C2%B045,577';5%C2%B04,719'%0A3;;-53.759383911755;5.02460196044417;-53%C2%B045,563';5%C2%B01,476'%0A4;;-53.5702069576163;5.02537608911083;-53%C2%B034,212';5%C2%B01,523'%0A5;;-53.5698730075868;4.93952315477954;-53%C2%B034,192';4%C2%B056,371'%0A6;;-53.7769878916108;4.93868722476635;-53%C2%B046,619';4%C2%B056,321'%0A7;;-53.7770631139658;4.95670276466037;-53%C2%B046,624';4%C2%B057,402'%0A8;;-53.8672265271601;4.95631734759459;-53%C2%B052,034';4%C2%B057,379'%0A9;;-53.8673626701318;4.98775355007457;-53%C2%B052,042';4%C2%B059,265'%0A10;;-53.9575232150351;4.98735333700249;-53%C2%B057,451';4%C2%B059,241'" download="points-m-pr-bon-espoir-2001.csv" style="margin-left: auto;">.csv</a> + <div class="fr-text--md">Surface : 464.71 Km²</div><a class="fr-btn fr-btn--secondary fr-btn--icon-right fr-icon-download-line" title="Télécharge les points au format csv" href="data:text/csv;charset=utf-8,nom;description;longitude;latitude;x_deg;y_deg%0A1;;-53.9579321010744;5.07776938770113;-53%C2%B057,476';5%C2%B04,666'%0A2;;-53.7596128864516;5.07864912381548;-53%C2%B045,577';5%C2%B04,719'%0A3;;-53.759383911755;5.02460196044417;-53%C2%B045,563';5%C2%B01,476'%0A4;;-53.5702069576163;5.02537608911083;-53%C2%B034,212';5%C2%B01,523'%0A5;;-53.5698730075868;4.93952315477954;-53%C2%B034,192';4%C2%B056,371'%0A6;;-53.7769878916108;4.93868722476635;-53%C2%B046,619';4%C2%B056,321'%0A7;;-53.7770631139658;4.95670276466037;-53%C2%B046,624';4%C2%B057,402'%0A8;;-53.8672265271601;4.95631734759459;-53%C2%B052,034';4%C2%B057,379'%0A9;;-53.8673626701318;4.98775355007457;-53%C2%B052,042';4%C2%B059,265'%0A10;;-53.9575232150351;4.98735333700249;-53%C2%B057,451';4%C2%B059,241'" download="points-m-pr-bon-espoir-2001.csv" style="margin-left: auto;">.csv</a> </div> </div> <!----> @@ -669,50 +727,6 @@ <!----> </div> </div> - <div class="fr-pb-2w"> - <div class="fr-pb-2w fr-pl-2w fr-pr-2w fr-tile--shadow"> - <div class="_sticky_964a6e fr-pt-1w"> - <div style="display: flex; justify-content: space-between; align-items: center;"> - <div style="display: flex;"> - <h4 class="fr-text--lg fr-mb-0" style="color: var(--text-title-blue-france); font-weight: 500;">Décision de l'autorité administrative</h4> - <!----> - </div> - <div style="display: flex; gap: 0.25rem;"> - <!----> - <!----> - <!----> - </div> - </div> - <p style="z-index: unset; margin-bottom: 0px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="fr-badge fr-badge--md fr-badge--green-bourgeon" title="accepté" aria-label="accepté">accepté</p> - <div style="display: flex; justify-content: space-between; align-items: center;"> - <div class="fr-mt-1w"><span class="fr-icon-calendar-line" style="color: var(--text-title-blue-france);" aria-hidden="true"></span> 24-10-2001</div> - <div> - <p style="z-index: unset; margin-bottom: 0px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="fr-badge fr-badge--md fr-badge--green-bourgeon" title="Étape publique" aria-label="Étape publique">Étape publique</p> - </div> - </div> - </div> - <!----> - <div class="fr-mb-3w fr-mt-3w" style="height: 1px; width: 100%; background-color: var(--grey-900-175);"></div> - <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); align-content: flex-start; column-gap: 16px; row-gap: 8px;"> - <!----> - <!----> - <!----> - <!----> - <!----> - <!----> - <!----> - <div style="grid-column: 1 / -1; white-space: pre-line;"> - <div class="fr-text--sm fr-mb-0">Notes</div> - <div class="fr-text--md fr-mb-0" style="font-weight: 500;">Décret du 24 octobre 2001 accordant un permis de recherches A en Guyane</div> - </div> - </div> - <!----> - <!----> - <!----> - <!----> - <!----> - </div> - </div> </div> </div> <!----> diff --git a/packages/ui/src/components/titre.stories_snapshots_BonEspoirProlongation2.html b/packages/ui/src/components/titre.stories_snapshots_BonEspoirProlongation2.html index fd0a69a2006e51e172fef850e39161937d5aa6fe..7abfc01c77901a5b51a46b9adccaf00c3a8f035a 100644 --- a/packages/ui/src/components/titre.stories_snapshots_BonEspoirProlongation2.html +++ b/packages/ui/src/components/titre.stories_snapshots_BonEspoirProlongation2.html @@ -342,7 +342,7 @@ </div> </div> <div style="display: flex;"> - <div class="fr-text--md">Surface : 122.275 Km²</div><a class="fr-btn fr-btn--secondary fr-btn--icon-right fr-icon-download-line" title="Télécharge les points au format csv" href="data:text/csv;charset=utf-8,nom;description;longitude;latitude;x_deg;y_deg%0AA;;-53.9577777777778;5.07666666666667;-53%C2%B057,467';5%C2%B04,6'%0AB;;-53.8763888888889;5.02277777777778;-53%C2%B052,583';5%C2%B01,367'%0AC;;-53.7322222222222;5.02361111111111;-53%C2%B043,933';5%C2%B01,417'%0AD;;-53.7138888888889;4.96388888888889;-53%C2%B042,833';4%C2%B057,833'%0AE;;-53.8208333333333;4.97972222222222;-53%C2%B049,25';4%C2%B058,783'%0AF;;-53.8944444444444;5.00055555555556;-53%C2%B053,667';5%C2%B00,033'%0AG;;-53.9575;5.0325;-53%C2%B057,45';5%C2%B01,95'" download="points-m-pr-bon-espoir-2001.csv" style="margin-left: auto;">.csv</a> + <div class="fr-text--md">Surface : 122.14 Km²</div><a class="fr-btn fr-btn--secondary fr-btn--icon-right fr-icon-download-line" title="Télécharge les points au format csv" href="data:text/csv;charset=utf-8,nom;description;longitude;latitude;x_deg;y_deg%0AA;;-53.9577777777778;5.07666666666667;-53%C2%B057,467';5%C2%B04,6'%0AB;;-53.8763888888889;5.02277777777778;-53%C2%B052,583';5%C2%B01,367'%0AC;;-53.7322222222222;5.02361111111111;-53%C2%B043,933';5%C2%B01,417'%0AD;;-53.7138888888889;4.96388888888889;-53%C2%B042,833';4%C2%B057,833'%0AE;;-53.8208333333333;4.97972222222222;-53%C2%B049,25';4%C2%B058,783'%0AF;;-53.8944444444444;5.00055555555556;-53%C2%B053,667';5%C2%B00,033'%0AG;;-53.9575;5.0325;-53%C2%B057,45';5%C2%B01,95'" download="points-m-pr-bon-espoir-2001.csv" style="margin-left: auto;">.csv</a> </div> </div> <!----> @@ -609,10 +609,193 @@ </div> </div> <!----> - <!----> + <div> + <div class="fr-text--sm fr-mb-0">Surface</div> + <div class="fr-text--md fr-mb-0" style="font-weight: 500;">122,14 km² environ</div> + </div> <!----> </div> - <!----> + <div class="fr-pt-2w"> + <div class="fr-tabs" style="--tabs-height: 0px;"> + <ul class="fr-tabs__list" role="tablist" aria-label="Affichage des titres en vue carte ou tableau"> + <li role="presentation"><button id="tabpanel-carte-iV47juaOeL4EAUsOqiWN6gOO" class="fr-tabs__tab fr-icon-earth-fill fr-tabs__tab--icon-left" tabindex="-1" role="tab" aria-label="Carte" aria-selected="false" aria-controls="tabpanel-carte-iV47juaOeL4EAUsOqiWN6gOO-panel">Carte</button></li> + <li role="presentation"><button id="tabpanel-points-iV47juaOeL4EAUsOqiWN6gOO" class="fr-tabs__tab fr-icon-list-unordered fr-tabs__tab--icon-left" tabindex="0" role="tab" aria-label="Tableau" aria-selected="true" aria-controls="tabpanel-points-iV47juaOeL4EAUsOqiWN6gOO-panel">Tableau</button></li> + </ul> + <div id="tabpanel-carte-iV47juaOeL4EAUsOqiWN6gOO-panel" class="fr-tabs__panel fr-tabs__panel--direction-start" role="tabpanel" aria-labelledby="tabpanel-carte-iV47juaOeL4EAUsOqiWN6gOO" tabindex="0"> + <!----> + </div> + <div id="tabpanel-points-iV47juaOeL4EAUsOqiWN6gOO-panel" class="fr-tabs__panel fr-tabs__panel--selected" role="tabpanel" aria-labelledby="tabpanel-points-iV47juaOeL4EAUsOqiWN6gOO" tabindex="0"> + <div style="display: flex; flex-direction: column;"> + <div class="fr-select-group"><label class="fr-label" for="4326">Système géographique</label> + <div id="4326_wrapper" class="_typeahead_8eddf1"> + <div class="flex"><input id="4326" type="text" title="" name="4326" disabled="" class="fr-input" placeholder="" autocomplete="off" role="combobox" aria-controls="4326-control" aria-activedescendant="4326-control" aria-expanded="false" aria-autocomplete="list" value="WGS84 - (4326)"></div> + <ul class="_typeahead-list_8eddf1 " tabindex="-1" id="4326-control" role="listbox"> + <li class="_typeahead-list-item_8eddf1 _typeahead-list-item-active_8eddf1" aria-selected="false" id="4326-control-0"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="fr-text--bold">Mayotte 2004 / UTM zone 38S - (4471)</span><span class="fr-text">Mayotte - à terre et extraterritorial</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-1"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="fr-text--bold">Réunion / UTM zone 40S - (2975)</span><span class="fr-text">Réunion</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-2"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="fr-text--bold">RGAF09 / UTM zone 20N - (5490)</span><span class="fr-text">Antilles françaises à terre et extraterritorial à l'ouest du méridien 60° Ouest - Guadeloupe (incluant Grande Terre, Basse Terre, Marie Galante, Les Saintes, Iles de la Petite Terre, La Desirade, St Barthélemy, partie nord de St Martin) et Martinique.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-3"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="fr-text--bold">RGF93 / Lambert-93 - (2154)</span><span class="fr-text">France - à terre et extraterritorial - continentale et Corse.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-4"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="fr-text--bold">RGFG95 / UTM zone 22N - (2972)</span><span class="fr-text">Guyane française - à terre et extraterritorial.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-5"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="fr-text--bold">St Pierre et Miquelon / UTM zone 21N - (4467)</span><span class="fr-text">St Pierre et Miquelon à terre et extraterritorial</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-6"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">ED50 - (4230)</span><span class="fr-text">Europe</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-7"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">Guadeloupe 1948 / UTM zone 20N - (2970)</span><span class="fr-text">Guadeloupe - à terre - Basse-Terre, Grande-Terre, La Desirade, Marie-Galante, Les Saintes.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-8"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">NTF (Greenwich) - (4275)</span><span class="fr-text">France - à terre - continentale et Corse.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-9"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">NTF (Paris) - (4807)</span><span class="fr-text">France - à terre - continentale et Corse.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-10"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">NTF (Paris) / Lambert Nord France - (27561)</span><span class="fr-text">France - continentale au nord de 53,5 grades North (48°09'N).</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-11"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">NTF (Paris) / Lambert Sud france - (27563)</span><span class="fr-text">France - continentale au sud de 50,5 grades nord (45°27'N).</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-12"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">NTF (Paris) / Lambert zone I - (27571)</span><span class="fr-text">France - continentale au nord de 53,5 grades nord (48°09'N).</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-13"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">NTF (Paris) / Lambert zone II - (27572)</span><span class="fr-text">France - continentale entre 45°27'N et 48°09'N.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-14"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">NTF (Paris) / Lambert zone III - (27573)</span><span class="fr-text">France - continentale au sud de 50,5 grades nord (45°27'N).</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-15"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">RGF93 - (4171)</span><span class="fr-text">France - à terre et extraterritorial - continentale et Corse.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-16"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">RGF93 / CC49 - (3949)</span><span class="fr-text">France - continentale entre 48°N et 50°N.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-17"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">RGFG95 - (4624)</span><span class="fr-text">Guyane Française - à terre et extraterritorial.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-18"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">RGFG95 / UTM zone 21N - (3313)</span><span class="fr-text">Guyane française - à terre et extraterritorial.</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-19"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">WGS84 / UTM zone 20N - (32620)</span><span class="fr-text">Hémisphère Nord - entre 66°W et 60°W</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-20"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">WGS84 / UTM zone 21N - (32621)</span><span class="fr-text">Hémisphère Nord - entre 60°W et 54°W</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-21"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">WGS84 / UTM zone 22N - (32622)</span><span class="fr-text">Hémisphère Nord - entre 54°W et 48°W</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-22"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">WGS84 / UTM zone 30N - (32630)</span><span class="fr-text">Hémisphère Nord - entre 6°W et 0°W</span></div> + </li> + <li class="_typeahead-list-item_8eddf1 " aria-selected="false" id="4326-control-23"> + <div style="display: flex; flex-direction: column;" class="fr-pl-2w"><span class="">WGS84 / UTM zone 31N - (32631)</span><span class="fr-text">Hémisphère Nord - entre 0°E et 6°E</span></div> + </li> + </ul> + </div> + </div> + <div style="display: flex; flex-direction: column;"> + <div class="fr-mb-1w"> + <div class="fr-table fr-table--no-scroll" style="overflow: auto;"> + <div class="fr-table__wrapper" style="width: auto;"> + <div class="fr-table__container"> + <div class="fr-table__content"> + <table style="display: table; width: 100%;"> + <caption>Points</caption> + <thead> + <tr> + <th scope="col">Nom du point</th> + <th scope="col">Description</th> + <th scope="col">Longitude</th> + <th scope="col">Latitude</th> + <th scope="col">Longitude (E)</th> + <th scope="col">Latitude (N)</th> + </tr> + </thead> + <tbody> + <tr> + <td><span class="">A</span></td> + <td><span class=""></span></td> + <td><span class="">-53.9577777777778</span></td> + <td><span class="">5.07666666666667</span></td> + <td><span class="">-53°57,467'</span></td> + <td><span class="">5°4,6'</span></td> + </tr> + <tr> + <td><span class="">B</span></td> + <td><span class=""></span></td> + <td><span class="">-53.8763888888889</span></td> + <td><span class="">5.02277777777778</span></td> + <td><span class="">-53°52,583'</span></td> + <td><span class="">5°1,367'</span></td> + </tr> + <tr> + <td><span class="">C</span></td> + <td><span class=""></span></td> + <td><span class="">-53.7322222222222</span></td> + <td><span class="">5.02361111111111</span></td> + <td><span class="">-53°43,933'</span></td> + <td><span class="">5°1,417'</span></td> + </tr> + <tr> + <td><span class="">D</span></td> + <td><span class=""></span></td> + <td><span class="">-53.7138888888889</span></td> + <td><span class="">4.96388888888889</span></td> + <td><span class="">-53°42,833'</span></td> + <td><span class="">4°57,833'</span></td> + </tr> + <tr> + <td><span class="">E</span></td> + <td><span class=""></span></td> + <td><span class="">-53.8208333333333</span></td> + <td><span class="">4.97972222222222</span></td> + <td><span class="">-53°49,25'</span></td> + <td><span class="">4°58,783'</span></td> + </tr> + <tr> + <td><span class="">F</span></td> + <td><span class=""></span></td> + <td><span class="">-53.8944444444444</span></td> + <td><span class="">5.00055555555556</span></td> + <td><span class="">-53°53,667'</span></td> + <td><span class="">5°0,033'</span></td> + </tr> + <tr> + <td><span class="">G</span></td> + <td><span class=""></span></td> + <td><span class="">-53.9575</span></td> + <td><span class="">5.0325</span></td> + <td><span class="">-53°57,45'</span></td> + <td><span class="">5°1,95'</span></td> + </tr> + </tbody> + </table> + </div> + </div> + </div> + </div> + </div> + <div style="display: flex;"> + <div class="fr-text--md">Surface : 122.14 Km²</div><a class="fr-btn fr-btn--secondary fr-btn--icon-right fr-icon-download-line" title="Télécharge les points au format csv" href="data:text/csv;charset=utf-8,nom;description;longitude;latitude;x_deg;y_deg%0AA;;-53.9577777777778;5.07666666666667;-53%C2%B057,467';5%C2%B04,6'%0AB;;-53.8763888888889;5.02277777777778;-53%C2%B052,583';5%C2%B01,367'%0AC;;-53.7322222222222;5.02361111111111;-53%C2%B043,933';5%C2%B01,417'%0AD;;-53.7138888888889;4.96388888888889;-53%C2%B042,833';4%C2%B057,833'%0AE;;-53.8208333333333;4.97972222222222;-53%C2%B049,25';4%C2%B058,783'%0AF;;-53.8944444444444;5.00055555555556;-53%C2%B053,667';5%C2%B00,033'%0AG;;-53.9575;5.0325;-53%C2%B057,45';5%C2%B01,95'" download="points-m-pr-bon-espoir-2001.csv" style="margin-left: auto;">.csv</a> + </div> + </div> + <!----> + </div> + </div> + </div> + </div> <!----> <!----> <!----> diff --git a/packages/ui/src/components/titre.stories_snapshots_ChantepieMutation.html b/packages/ui/src/components/titre.stories_snapshots_ChantepieMutation.html index 4a19fbb8e345545633d31abc0e2fb15521f7a399..ad524a8d4ac30c312f967f8549e763a45d750843 100644 --- a/packages/ui/src/components/titre.stories_snapshots_ChantepieMutation.html +++ b/packages/ui/src/components/titre.stories_snapshots_ChantepieMutation.html @@ -19,7 +19,7 @@ <div class="fr-mt-2w">Références<div style="font-weight: 500;">DEB : 2013-0224-MI</div> </div> <div class="fr-grid-row fr-grid-row--middle fr-mt-4w"> - <div><span class="fr-icon-calendar-line fr-icon--sm fr-mr-1w" style="color: var(--text-title-blue-france);" aria-hidden="true"></span>Modifié le 12-10-2023</div><a href="/mocked-href" title="Journaux du titre" class="fr-link" aria-label="Journaux du titre" style="margin-left: auto;">Journaux du titre</a> + <!----><a href="/mocked-href" title="Journaux du titre" class="fr-link" aria-label="Journaux du titre" style="margin-left: auto;">Journaux du titre</a> </div> <div> <!----> diff --git a/packages/ui/src/components/titre.stories_snapshots_ChantepieOctroi.html b/packages/ui/src/components/titre.stories_snapshots_ChantepieOctroi.html index 9173dcdef3e269deee296adf772189cd81490935..2c9f7dd12c40342710bf62d5d87894870057a4dc 100644 --- a/packages/ui/src/components/titre.stories_snapshots_ChantepieOctroi.html +++ b/packages/ui/src/components/titre.stories_snapshots_ChantepieOctroi.html @@ -19,7 +19,7 @@ <div class="fr-mt-2w">Références<div style="font-weight: 500;">DEB : 2013-0224-MI</div> </div> <div class="fr-grid-row fr-grid-row--middle fr-mt-4w"> - <div><span class="fr-icon-calendar-line fr-icon--sm fr-mr-1w" style="color: var(--text-title-blue-france);" aria-hidden="true"></span>Modifié le 12-10-2023</div> + <!----> <!----> </div> <div> diff --git a/packages/ui/src/components/titre.stories_snapshots_CriqueAdolpheOctroi.html b/packages/ui/src/components/titre.stories_snapshots_CriqueAdolpheOctroi.html index 6841a78b953912f98cf9039264284888b61489f9..91034fa09a25602eeea59c7e3b7276658fbac26b 100644 --- a/packages/ui/src/components/titre.stories_snapshots_CriqueAdolpheOctroi.html +++ b/packages/ui/src/components/titre.stories_snapshots_CriqueAdolpheOctroi.html @@ -20,7 +20,7 @@ <div style="font-weight: 500;">ONF : AR 2022-027</div> </div> <div class="fr-grid-row fr-grid-row--middle fr-mt-4w"> - <div><span class="fr-icon-calendar-line fr-icon--sm fr-mr-1w" style="color: var(--text-title-blue-france);" aria-hidden="true"></span>Modifié le 20-10-2023</div><a href="/mocked-href" title="Journaux du titre" class="fr-link" aria-label="Journaux du titre" style="margin-left: auto;">Journaux du titre</a> + <!----><a href="/mocked-href" title="Journaux du titre" class="fr-link" aria-label="Journaux du titre" style="margin-left: auto;">Journaux du titre</a> </div> <div> <!----> @@ -69,7 +69,7 @@ <h2 style="margin: 0px;">Octroi</h2> <p style="z-index: unset; margin-bottom: 0px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; margin-right: auto;" class="fr-badge fr-badge--md fr-ml-2w fr-badge--green-bourgeon fr-ml-2w" title="accepté" aria-label="accepté">accepté</p><button class="fr-btn fr-btn--primary fr-btn--md" title="Ajouter une démarche" aria-label="Ajouter une démarche" type="button">Ajouter une démarche</button><button class="fr-btn fr-btn--secondary fr-btn--md fr-icon-pencil-line fr-ml-2w" title="Modifier la description" aria-label="Modifier la description" type="button" style="margin-right: 0px;"> <!----> - </button><button class="fr-btn fr-btn--secondary fr-btn--md fr-icon-delete-bin-line fr-ml-2w" title="Supprimer la démarche ArmOct" aria-label="Supprimer la démarche ArmOct" type="button"> + </button><button class="fr-btn fr-btn--secondary fr-btn--md fr-icon-delete-bin-line fr-ml-2w" title="Supprimer la démarche AncienLogigrammeOctroiARM" aria-label="Supprimer la démarche AncienLogigrammeOctroiARM" type="button"> <!----> </button> </div> diff --git a/packages/ui/src/components/titre.stories_snapshots_Lenoncourt.html b/packages/ui/src/components/titre.stories_snapshots_Lenoncourt.html index 74b0058378d8b3be38dabf6fef32f6b0ac07d9b8..ac0d54b59f75d069d08362c4e1dc8b688303a05a 100644 --- a/packages/ui/src/components/titre.stories_snapshots_Lenoncourt.html +++ b/packages/ui/src/components/titre.stories_snapshots_Lenoncourt.html @@ -42,9 +42,12 @@ <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir la phase Mutation du 19-11-1970" aria-label="Voir la phase Mutation du 19-11-1970" tab-index="-1">Voir la phase Mutation du 19-11-1970</a></li> <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir la phase Mutation du 27-11-1975" aria-label="Voir la phase Mutation du 27-11-1975" tab-index="-1">Voir la phase Mutation du 27-11-1975</a></li> <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir la phase Extension de périmètre du 13-09-1981" aria-label="Voir la phase Extension de périmètre du 13-09-1981" tab-index="-1">Voir la phase Extension de périmètre du 13-09-1981</a></li> + <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir l'événement Autorisation d'ouverture de travaux du 2000-06-07 lié à la phase Extension de périmètre" aria-label="Voir l'événement Autorisation d'ouverture de travaux du 2000-06-07 lié à la phase Extension de périmètre" tab-index="-1">Voir l'événement Autorisation d'ouverture de travaux du 07-06-2000 lié à la phase Extension de périmètre</a></li> <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir la phase Mutation du 06-10-2000" aria-label="Voir la phase Mutation du 06-10-2000" tab-index="-1">Voir la phase Mutation du 06-10-2000</a></li> <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir la phase Mutation du 08-01-2003" aria-label="Voir la phase Mutation du 08-01-2003" tab-index="-1">Voir la phase Mutation du 08-01-2003</a></li> <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir la phase Mutation du 28-02-2004" aria-label="Voir la phase Mutation du 28-02-2004" tab-index="-1">Voir la phase Mutation du 28-02-2004</a></li> + <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir l'événement Autorisation d'ouverture de travaux du 2012-05-15 lié à la phase Mutation" aria-label="Voir l'événement Autorisation d'ouverture de travaux du 2012-05-15 lié à la phase Mutation" tab-index="-1">Voir l'événement Autorisation d'ouverture de travaux du 15-05-2012 lié à la phase Mutation</a></li> + <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir l'événement Autorisation d'ouverture de travaux du 2019-05-31 lié à la phase Mutation" aria-label="Voir l'événement Autorisation d'ouverture de travaux du 2019-05-31 lié à la phase Mutation" tab-index="-1">Voir l'événement Autorisation d'ouverture de travaux du 31-05-2019 lié à la phase Mutation</a></li> <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir la phase Prolongation du 01-03-2024" aria-label="Voir la phase Prolongation du 01-03-2024" tab-index="-1">Voir la phase Prolongation du 01-03-2024</a></li> <li class="_hidden_b2e482"><a href="/mocked-href" title="Voir la phase Extension de périmètre du 01-03-2024" aria-label="Voir la phase Extension de périmètre du 01-03-2024" aria-current="page" tab-index="-1">Voir la phase Extension de périmètre du 01-03-2024</a></li> </ul> @@ -62,7 +65,16 @@ </div> <div style="display: flex; width: 100%;"> <div style="display: flex; gap: 5px; position: relative; height: 20px; flex: 1;"> - <div class="_phasesContainer_b2e482" style="flex: 1;"><a tabindex="-1" href="/mocked-href" title="Octroi" class="_phase_b2e482" aria-label="Octroi" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Mutation" class="_phase_b2e482" aria-label="Mutation" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Mutation" class="_phase_b2e482" aria-label="Mutation" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Extension de périmètre" class="_phase_b2e482" aria-label="Extension de périmètre" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Mutation" class="_phase_b2e482" aria-label="Mutation" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Mutation" class="_phase_b2e482" aria-label="Mutation" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Mutation" class="_phase_b2e482" aria-label="Mutation" style="min-width: 200px;"></a></div> + <div class="_phasesContainer_b2e482" style="flex: 1;"><a tabindex="-1" href="/mocked-href" title="Octroi" class="_phase_b2e482" aria-label="Octroi" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Mutation" class="_phase_b2e482" aria-label="Mutation" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Mutation" class="_phase_b2e482" aria-label="Mutation" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Extension de périmètre" class="_phase_b2e482" aria-label="Extension de périmètre" style="min-width: 200px;"><a tabindex="-1" href="/mocked-href" title="Autorisation d'ouverture de travaux" aria-label="Autorisation d'ouverture de travaux" aria-describedby="timeline-event-m-cx-lenoncourt-1968-aom01"><svg class="_travaux-icone_a26566" width="17" height="19" viewBox="0 0 17 19" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path d="M0.647766 17.0224L2.06999 17.0223L6.7467 0.275378C6.79229 0.110124 7.12833 0 7.29173 0H9.62077V0.00185531C9.78417 0.00185531 10.048 0.110124 10.0938 0.275378L14.7759 17.0223H16.2624C16.6195 17.0223 16.9103 17.2312 16.9103 17.4858V18.5364C16.9103 18.791 16.6177 19 16.2624 19L0.647905 18.9999C0.290774 18.9999 0 18.7909 0 18.5363V17.4857C0 17.2293 0.292467 17.0224 0.647766 17.0224ZM6.96092 2.97703H9.9531L9.33753 0.746577H7.57446L6.96092 2.97703ZM11.0113 6.82042H5.90076L5.0896 9.76317H11.8261L11.0113 6.82042ZM12.8844 13.6065H4.02757L3.08523 17.0224H13.8267L12.8844 13.6065Z" fill="none"></path> + <path d="M0.647766 17.0224L2.06999 17.0223L6.7467 0.275378C6.79229 0.110124 7.12833 0 7.29173 0H9.62077V0.00185531C9.78417 0.00185531 10.048 0.110124 10.0938 0.275378L14.7759 17.0223H16.2624C16.6195 17.0223 16.9103 17.2312 16.9103 17.4858V18.5364C16.9103 18.791 16.6177 19 16.2624 19L0.647905 18.9999C0.290774 18.9999 0 18.7909 0 18.5363V17.4857C0 17.2293 0.292467 17.0224 0.647766 17.0224ZM6.96092 2.97703H9.9531L9.33753 0.746577H7.57446L6.96092 2.97703ZM11.0113 6.82042H5.90076L5.0896 9.76317H11.8261L11.0113 6.82042ZM12.8844 13.6065H4.02757L3.08523 17.0224H13.8267L12.8844 13.6065Z" stroke="black"></path> + </svg></a></a><a tabindex="-1" href="/mocked-href" title="Mutation" class="_phase_b2e482" aria-label="Mutation" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Mutation" class="_phase_b2e482" aria-label="Mutation" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Mutation" class="_phase_b2e482" aria-label="Mutation" style="min-width: 200px;"><a tabindex="-1" href="/mocked-href" title="Autorisation d'ouverture de travaux" aria-label="Autorisation d'ouverture de travaux" aria-describedby="timeline-event-m-cx-lenoncourt-1968-aom02"><svg class="_travaux-icone_a26566" width="17" height="19" viewBox="0 0 17 19" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path d="M0.647766 17.0224L2.06999 17.0223L6.7467 0.275378C6.79229 0.110124 7.12833 0 7.29173 0H9.62077V0.00185531C9.78417 0.00185531 10.048 0.110124 10.0938 0.275378L14.7759 17.0223H16.2624C16.6195 17.0223 16.9103 17.2312 16.9103 17.4858V18.5364C16.9103 18.791 16.6177 19 16.2624 19L0.647905 18.9999C0.290774 18.9999 0 18.7909 0 18.5363V17.4857C0 17.2293 0.292467 17.0224 0.647766 17.0224ZM6.96092 2.97703H9.9531L9.33753 0.746577H7.57446L6.96092 2.97703ZM11.0113 6.82042H5.90076L5.0896 9.76317H11.8261L11.0113 6.82042ZM12.8844 13.6065H4.02757L3.08523 17.0224H13.8267L12.8844 13.6065Z" fill="none"></path> + <path d="M0.647766 17.0224L2.06999 17.0223L6.7467 0.275378C6.79229 0.110124 7.12833 0 7.29173 0H9.62077V0.00185531C9.78417 0.00185531 10.048 0.110124 10.0938 0.275378L14.7759 17.0223H16.2624C16.6195 17.0223 16.9103 17.2312 16.9103 17.4858V18.5364C16.9103 18.791 16.6177 19 16.2624 19L0.647905 18.9999C0.290774 18.9999 0 18.7909 0 18.5363V17.4857C0 17.2293 0.292467 17.0224 0.647766 17.0224ZM6.96092 2.97703H9.9531L9.33753 0.746577H7.57446L6.96092 2.97703ZM11.0113 6.82042H5.90076L5.0896 9.76317H11.8261L11.0113 6.82042ZM12.8844 13.6065H4.02757L3.08523 17.0224H13.8267L12.8844 13.6065Z" stroke="black"></path> + </svg></a><a tabindex="-1" href="/mocked-href" title="Autorisation d'ouverture de travaux" aria-label="Autorisation d'ouverture de travaux" aria-describedby="timeline-event-m-cx-lenoncourt-1968-aom03"><svg class="_travaux-icone_a26566" width="17" height="19" viewBox="0 0 17 19" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path d="M0.647766 17.0224L2.06999 17.0223L6.7467 0.275378C6.79229 0.110124 7.12833 0 7.29173 0H9.62077V0.00185531C9.78417 0.00185531 10.048 0.110124 10.0938 0.275378L14.7759 17.0223H16.2624C16.6195 17.0223 16.9103 17.2312 16.9103 17.4858V18.5364C16.9103 18.791 16.6177 19 16.2624 19L0.647905 18.9999C0.290774 18.9999 0 18.7909 0 18.5363V17.4857C0 17.2293 0.292467 17.0224 0.647766 17.0224ZM6.96092 2.97703H9.9531L9.33753 0.746577H7.57446L6.96092 2.97703ZM11.0113 6.82042H5.90076L5.0896 9.76317H11.8261L11.0113 6.82042ZM12.8844 13.6065H4.02757L3.08523 17.0224H13.8267L12.8844 13.6065Z" fill="none"></path> + <path d="M0.647766 17.0224L2.06999 17.0223L6.7467 0.275378C6.79229 0.110124 7.12833 0 7.29173 0H9.62077V0.00185531C9.78417 0.00185531 10.048 0.110124 10.0938 0.275378L14.7759 17.0223H16.2624C16.6195 17.0223 16.9103 17.2312 16.9103 17.4858V18.5364C16.9103 18.791 16.6177 19 16.2624 19L0.647905 18.9999C0.290774 18.9999 0 18.7909 0 18.5363V17.4857C0 17.2293 0.292467 17.0224 0.647766 17.0224ZM6.96092 2.97703H9.9531L9.33753 0.746577H7.57446L6.96092 2.97703ZM11.0113 6.82042H5.90076L5.0896 9.76317H11.8261L11.0113 6.82042ZM12.8844 13.6065H4.02757L3.08523 17.0224H13.8267L12.8844 13.6065Z" stroke="black"></path> + </svg></a></a></div> <div style="border: 2px solid black;"></div> <div class="_phasesContainer_b2e482" style="flex: 1;"><a tabindex="-1" href="/mocked-href" title="Prolongation" class="_phase_b2e482" aria-label="Prolongation" style="min-width: 200px;"></a><a tabindex="-1" href="/mocked-href" title="Extension de périmètre" class="_phase_b2e482" aria-label="Extension de périmètre" aria-current="page" style="min-width: 200px;"></a></div> <!----> @@ -142,7 +154,7 @@ <!----> <div style="grid-column: 1 / -1;"> <div class="fr-text--sm fr-mb-0">Communes</div> - <div class="fr-text--md fr-mb-0" style="font-weight: 500;">Saulxures-lès-Nancy, Lenoncourt, Cerville, Art-sur-Meurthe</div> + <div class="fr-text--md fr-mb-0" style="font-weight: 500;">Art-sur-Meurthe, Cerville, Lenoncourt, Saulxures-lès-Nancy</div> </div> </div> </div> diff --git a/packages/ui/src/components/titre.tsx b/packages/ui/src/components/titre.tsx index 89cb0601e2fa8c09d774ab317a7e081355806d1d..5f1218797c9bdc1242461c22991e74624db1338f 100644 --- a/packages/ui/src/components/titre.tsx +++ b/packages/ui/src/components/titre.tsx @@ -1,7 +1,7 @@ import { computed, defineComponent, onMounted, ref, watch, inject } from 'vue' import { useRouter } from 'vue-router' import { LoadingElement } from './_ui/functional-loader' -import { demarcheEnregistrementDemandeDateFind, DemarcheEtapeFondamentale, DemarcheSlug, demarcheSlugValidator } from 'camino-common/src/demarche' +import { DemarcheEtapeFondamentale, DemarcheId, DemarcheSlug, demarcheSlugValidator } from 'camino-common/src/demarche' import { AsyncData, CaminoHttpError } from '@/api/client-rest' import { User, isAdministration, isEntrepriseOrBureauDEtude, isSuper } from 'camino-common/src/roles' import { capitalize } from 'camino-common/src/strings' @@ -43,17 +43,35 @@ import { ModifiedDate } from './_common/modified-date' import { DemarcheMiseEnConcurrence } from './titre/demarche-mise-en-concurrence' import { DemarchesConsentement } from './titre/demarche-consentement' import { useState } from '@/utils/vue-tsx-utils' -import { isMachineWithConsentement, machineIdFind } from 'camino-common/src/machines' +import { isMachineWithConsentement, MachineInfo } from 'camino-common/src/machines' import { InitialSort } from './_ui/table' import { HTTP_STATUS } from 'camino-common/src/http' import { fr } from '@codegouvfr/react-dsfr' import { TitreVisibilite } from './_common/titre-visibilite' +import { CaminoError } from 'camino-common/src/zod-tools' const activitesSort: InitialSort<string> = { colonne: activitesColonneIdAnnee, ordre: 'desc', } +const getMachinesInfo = (titre: TitreGet): Record<DemarcheId, MachineInfo> | CaminoError<string> => { + const result = titre.demarches.map(demarche => MachineInfo.withMachineId(titre.titre_type_id, demarche.demarche_type_id, demarche.id, demarche.machine_id)) + + const error = result.find(machineInfo => !machineInfo.valid) + if (isNotNullNorUndefined(error)) { + return { message: error.error } + } else { + return result.reduce<Record<DemarcheId, MachineInfo>>((acc, machineInfo) => { + if (machineInfo.valid) { + acc[machineInfo.value.demarcheId] = machineInfo.value + } + + return acc + }, {}) + } +} + export const Titre = defineComponent(() => { const router = useRouter() @@ -130,11 +148,11 @@ export interface Props { } export const PureTitre = defineComponent<Props>(props => { - const titreData = ref<AsyncData<TitreGet>>({ status: 'LOADING' }) + const titreData = ref<AsyncData<{ titre: TitreGet; machinesInfo: Record<DemarcheId, MachineInfo> }>>({ status: 'LOADING' }) const [hasTitresFrom, setHasTitresFrom] = useState<boolean | 'LOADING'>('LOADING') const retrieveTitre = async () => { - const titreId: TitreId | null = titreData.value.status === 'LOADED' ? titreData.value.value.id : null + const titreId: TitreId | null = titreData.value.status === 'LOADED' ? titreData.value.value.titre.id : null if (titreId !== null) { await updateTitre(titreId) } @@ -163,22 +181,28 @@ export const PureTitre = defineComponent<Props>(props => { } else { try { const data = await props.apiClient.getTitreById(titreIdOrSlug) - titreData.value = { status: 'LOADED', value: data } - - let demarcheSlug = props.currentDemarcheSlug - - if (isNullOrUndefinedOrEmpty(demarcheSlug) && 'erreur' in phases.value) { - demarcheSlug = phases.value.demarches[0].slug - } else if ( - (isNullOrUndefinedOrEmpty(demarcheSlug) || isNullOrUndefined(data.demarches.find(({ slug }) => slug === props.currentDemarcheSlug))) && - !('erreur' in phases.value) && - phases.value.length > 0 - ) { - demarcheSlug = phases.value[phases.value.length - 1][phases.value[phases.value.length - 1].length - 1].slug - } + const machinesInfo = getMachinesInfo(data) - if (data.slug !== props.titreIdOrSlug || demarcheSlug !== props.currentDemarcheSlug) { - props.router.replace({ name: 'titre', params: { id: data.slug }, query: { demarcheSlug } }) + if ('message' in machinesInfo) { + titreData.value = { status: 'NEW_ERROR', error: machinesInfo } + } else { + titreData.value = { status: 'LOADED', value: { titre: data, machinesInfo } } + + let demarcheSlug = props.currentDemarcheSlug + + if (isNullOrUndefinedOrEmpty(demarcheSlug) && 'erreur' in phases.value) { + demarcheSlug = phases.value.demarches[0].slug + } else if ( + (isNullOrUndefinedOrEmpty(demarcheSlug) || isNullOrUndefined(data.demarches.find(({ slug }) => slug === props.currentDemarcheSlug))) && + !('erreur' in phases.value) && + phases.value.length > 0 + ) { + demarcheSlug = phases.value[phases.value.length - 1][phases.value[phases.value.length - 1].length - 1].slug + } + + if (data.slug !== props.titreIdOrSlug || demarcheSlug !== props.currentDemarcheSlug) { + props.router.replace({ name: 'titre', params: { id: data.slug }, query: { demarcheSlug } }) + } } } catch (e: any) { console.error('error', e) @@ -200,7 +224,7 @@ export const PureTitre = defineComponent<Props>(props => { watch( () => props.titreIdOrSlug, async (_newValue, _oldValue) => { - if (titreData.value.status !== 'LOADED' || (titreData.value.value.id !== props.titreIdOrSlug && titreData.value.value.slug !== props.titreIdOrSlug)) { + if (titreData.value.status !== 'LOADED' || (titreData.value.value.titre.id !== props.titreIdOrSlug && titreData.value.value.titre.slug !== props.titreIdOrSlug)) { await updateTitre(props.titreIdOrSlug) } } @@ -210,10 +234,15 @@ export const PureTitre = defineComponent<Props>(props => { () => titreData.value, async () => { if (titreData.value.status === 'LOADED') { - const titre = titreData.value.value + const titre = titreData.value.value.titre showActivitesLink.value = - canHaveActivites({ titreTypeId: titreData.value.value.titre_type_id, communes: communes.value, secteursMaritime: secteursMaritime.value, demarches: titreData.value.value.demarches }) && + canHaveActivites({ + titreTypeId: titreData.value.value.titre.titre_type_id, + communes: communes.value, + secteursMaritime: secteursMaritime.value, + demarches: titreData.value.value.titre.demarches, + }) && (await canReadTitreActivites( props.user, () => Promise.resolve(titre.titre_type_id), @@ -263,8 +292,8 @@ export const PureTitre = defineComponent<Props>(props => { const showActivitesLink = ref<boolean>(false) const perimetre = computed<null | DemarcheEtapeFondamentale['fondamentale']['perimetre']>(() => { - if (titreData.value.status === 'LOADED' && titreData.value.value.demarches !== null) { - return getMostRecentValuePropFromEtapeFondamentaleValide('perimetre', titreData.value.value.demarches) + if (titreData.value.status === 'LOADED' && titreData.value.value.titre.demarches !== null) { + return getMostRecentValuePropFromEtapeFondamentaleValide('perimetre', titreData.value.value.titre.demarches) } return null @@ -281,8 +310,8 @@ export const PureTitre = defineComponent<Props>(props => { : [] const administrationGestionnaires = - titreData.value.value.titre_type_id !== null - ? getGestionnairesByTitreTypeId(titreData.value.value.titre_type_id) + titreData.value.value.titre.titre_type_id !== null + ? getGestionnairesByTitreTypeId(titreData.value.value.titre.titre_type_id) .filter(({ associee }) => !associee) .filter(({ administrationId }) => Administrations[administrationId].typeId === ADMINISTRATION_TYPE_IDS.MINISTERE) .map(({ administrationId }) => administrationId) @@ -312,7 +341,7 @@ export const PureTitre = defineComponent<Props>(props => { const titreLinkFormTitre = computed(() => { if (titreData.value.status === 'LOADED') { - return { id: titreData.value.value.id, typeId: titreData.value.value.titre_type_id, administrations: administrations.value, demarches: titreData.value.value.demarches } + return { id: titreData.value.value.titre.id, typeId: titreData.value.value.titre.titre_type_id, administrations: administrations.value, demarches: titreData.value.value.titre.demarches } } return null @@ -320,7 +349,7 @@ export const PureTitre = defineComponent<Props>(props => { const phases = computed<PhaseWithAlterations>(() => { if (titreData.value.status === 'LOADED') { - return phaseWithAlterations(titreData.value.value.demarches, props.currentDate) + return phaseWithAlterations(titreData.value.value.titre.demarches, props.currentDate) } return [] @@ -363,24 +392,19 @@ export const PureTitre = defineComponent<Props>(props => { if (isNullOrUndefined(props.currentDemarcheSlug)) { return undefined } - const titre = titreData.value.value + const titre = titreData.value.value.titre const demarche = titre.demarches.find(({ slug }) => slug === props.currentDemarcheSlug) if (isNullOrUndefined(demarche)) { return undefined } - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(demarche.etapes.map(etape => ({ ...etape, typeId: etape.etape_type_id }))) - - if (isNullOrUndefined(firstEtapeDate)) { - return undefined - } - return machineIdFind(titre.titre_type_id, demarche.demarche_type_id, demarche.id, firstEtapeDate) + return demarche.machine_id }) return () => ( <div> <LoadingElement data={titreData.value} - renderItem={titre => ( + renderItem={({ titre, machinesInfo }) => ( <div> <div class="fr-grid-row fr-grid-row--top"> <h1 style={{ maxWidth: '400px' }} class="fr-m-0"> @@ -502,6 +526,7 @@ export const PureTitre = defineComponent<Props>(props => { demarcheCreatedOrUpdated={demarcheCreatedOrUpdated} demarcheDeleted={demarcheDeleted} demarches={titre.demarches} + machinesInfo={machinesInfo} currentDemarcheSlug={props.currentDemarcheSlug} currentDate={props.currentDate} user={props.user} diff --git a/packages/ui/src/components/titre/demarche-mise-en-concurrence.stories.tsx b/packages/ui/src/components/titre/demarche-mise-en-concurrence.stories.tsx index e5e485dec77fc5c8c792ea9c5c607731cddf3259..b1d810404d4b7ebab66a40fd2b6776314c262ca3 100644 --- a/packages/ui/src/components/titre/demarche-mise-en-concurrence.stories.tsx +++ b/packages/ui/src/components/titre/demarche-mise-en-concurrence.stories.tsx @@ -40,6 +40,7 @@ const titrePivotAvantMEC: Props['titre'] = { demarches: [ { id: idPivot, + machine_id: 'ProcedureSpecifique', demarche_type_id: DEMARCHES_TYPES_IDS.Octroi, etapes: [ { @@ -59,6 +60,7 @@ const titrePivotPendantMECEnCours: Props['titre'] = { { id: idPivot, demarche_type_id: DEMARCHES_TYPES_IDS.Octroi, + machine_id: 'ProcedureSpecifique', etapes: [ { etape_type_id: ETAPES_TYPES.demande, @@ -82,6 +84,7 @@ const titrePivotPendantMECProgrammee: Props['titre'] = { { id: idPivot, demarche_type_id: DEMARCHES_TYPES_IDS.Octroi, + machine_id: 'ProcedureSpecifique', etapes: [ { etape_type_id: ETAPES_TYPES.demande, @@ -105,6 +108,7 @@ const titrePivotPendantMECTerminee: Props['titre'] = { { id: idPivot, demarche_type_id: DEMARCHES_TYPES_IDS.Octroi, + machine_id: 'ProcedureSpecifique', etapes: [ { etape_type_id: ETAPES_TYPES.demande, @@ -128,6 +132,7 @@ const titrePivotApresMEC: Props['titre'] = { { id: idPivot, demarche_type_id: DEMARCHES_TYPES_IDS.Octroi, + machine_id: 'ProcedureSpecifique', etapes: [ { etape_type_id: ETAPES_TYPES.demande, @@ -152,6 +157,7 @@ const titreSatellite: Props['titre'] = { { id: idSatellite, demarche_type_id: DEMARCHES_TYPES_IDS.Octroi, + machine_id: 'ProcedureSpecifique', etapes: [ { etape_type_id: ETAPES_TYPES.demande, @@ -170,6 +176,7 @@ const titreSatelliteApresMEC: Props['titre'] = { { id: idSatellite, demarche_type_id: DEMARCHES_TYPES_IDS.Octroi, + machine_id: 'ProcedureSpecifique', etapes: [ { etape_type_id: ETAPES_TYPES.demande, @@ -193,6 +200,7 @@ const titreExtensionDePerimetre: Props['titre'] = { { id: idPivot, demarche_type_id: DEMARCHES_TYPES_IDS.ExtensionDePerimetre, + machine_id: 'ProcedureSpecifique', etapes: [ { etape_type_id: ETAPES_TYPES.demande, @@ -216,6 +224,7 @@ const titrePivotNonProcedureSpecifique: Props['titre'] = { { id: idPivot, demarche_type_id: DEMARCHES_TYPES_IDS.Octroi, + machine_id: 'AncienLogigrammeOctroiARM', etapes: [ { etape_type_id: ETAPES_TYPES.demande, diff --git a/packages/ui/src/components/titre/demarche-mise-en-concurrence.tsx b/packages/ui/src/components/titre/demarche-mise-en-concurrence.tsx index 7ca6aafb2db77f6221b31f7865513c675da3e06b..c0fc9caab3c1e2658d5e69041fcb0906c870690a 100644 --- a/packages/ui/src/components/titre/demarche-mise-en-concurrence.tsx +++ b/packages/ui/src/components/titre/demarche-mise-en-concurrence.tsx @@ -1,6 +1,6 @@ import type { ApiClient } from '@/api/api-client' import { AsyncData } from '@/api/client-rest' -import { canHaveMiseEnConcurrence, demarcheEnregistrementDemandeDateFind, DemarcheEtape, DemarcheId, demarcheIdValidator, GetDemarcheMiseEnConcurrence } from 'camino-common/src/demarche' +import { canHaveMiseEnConcurrence, DemarcheEtape, DemarcheId, demarcheIdValidator, GetDemarcheMiseEnConcurrence } from 'camino-common/src/demarche' import { computed, defineComponent, FunctionalComponent, ref } from 'vue' import { LoadingElement } from '../_ui/functional-loader' import { isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, PickDistributive } from 'camino-common/src/typescript-tools' @@ -10,14 +10,19 @@ import { ETAPE_TYPE_FOR_CONCURRENCY_DATA, ETAPES_TYPES } from 'camino-common/src import { isAdministrationRole, isSuperRole, UserNotNull } from 'camino-common/src/roles' import { watch } from 'vue' import { DemarcheTypeId } from 'camino-common/src/static/demarchesTypes' -import { CaminoMachineId, machineIdFind } from 'camino-common/src/machines' import { TitreTypeId } from 'camino-common/src/static/titresTypes' import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' +import { CaminoMachineId } from 'camino-common/src/validators/machine' export type Props = { apiClient: Pick<ApiClient, 'getDemarcheMiseEnConcurrence'> titre: { titre_type_id: TitreTypeId - demarches: { id: DemarcheId; demarche_type_id: DemarcheTypeId; etapes: PickDistributive<DemarcheEtape, 'etape_type_id' | 'demarche_id_en_concurrence' | 'date' | 'etape_statut_id'>[] }[] + demarches: { + id: DemarcheId + machine_id: CaminoMachineId | null + demarche_type_id: DemarcheTypeId + etapes: PickDistributive<DemarcheEtape, 'etape_type_id' | 'demarche_id_en_concurrence' | 'date' | 'etape_statut_id'>[] + }[] } user: Pick<UserNotNull, 'role'> | null hasTitresFrom: boolean | 'LOADING' @@ -45,14 +50,8 @@ export const DemarcheMiseEnConcurrence = defineComponent<Props>(props => { conf.value = null const demarchesSansResultat = props.titre.demarches - .filter(({ demarche_type_id, etapes, id }) => { - const firstEtapeDate = demarcheEnregistrementDemandeDateFind(etapes.map(etape => ({ ...etape, typeId: etape.etape_type_id }))) - let machineId: CaminoMachineId | undefined - if (isNotNullNorUndefined(firstEtapeDate)) { - machineId = machineIdFind(props.titre.titre_type_id, demarche_type_id, id, firstEtapeDate) - } - - return machineId === 'ProcedureSpecifique' && canHaveMiseEnConcurrence(demarche_type_id, hasTitresFrom) + .filter(({ demarche_type_id, machine_id }) => { + return machine_id === 'ProcedureSpecifique' && canHaveMiseEnConcurrence(demarche_type_id, hasTitresFrom) }) .reduce<{ id: DemarcheId; hasAnf: boolean }[]>((acc, demarche) => { const hasAnf: boolean = demarche.etapes.some(etape => etape.etape_type_id === ETAPES_TYPES.avisDeMiseEnConcurrenceAuJORF) diff --git a/packages/ui/src/components/titre/phase.test.ts b/packages/ui/src/components/titre/phase.test.ts index 4c18944f2a2d6ef7b6bca52d4354af755aab6fc9..b714450a98b87c437d16675bccca3cc7ab4f165a 100644 --- a/packages/ui/src/components/titre/phase.test.ts +++ b/packages/ui/src/components/titre/phase.test.ts @@ -17,6 +17,7 @@ test('phase en erreur', () => { demarche_date_debut: null, demarche_date_fin: null, demarche_visibilite: 'Confidentielle', + machine_id: null, ordre: 1, }, { @@ -29,6 +30,7 @@ test('phase en erreur', () => { demarche_statut_id: 'acp', demarche_date_debut: null, demarche_date_fin: null, + machine_id: null, ordre: 2, }, ] @@ -45,6 +47,7 @@ test('phase en erreur', () => { "description": null, "etapes": [], "id": "idMut", + "machine_id": null, "ordre": 1, "slug": "slug-mut", }, @@ -57,6 +60,7 @@ test('phase en erreur', () => { "description": null, "etapes": [], "id": "idDemPro", + "machine_id": null, "ordre": 2, "slug": "dem-slug-pro", }, @@ -71,6 +75,7 @@ test('phase acceptée et publiée', () => { id: demarcheIdValidator.parse('idMut'), slug: demarcheSlugValidator.parse('slug-mut'), description: null, + machine_id: null, etapes: [ { etape_type_id: 'dex', @@ -100,6 +105,7 @@ test('phase acceptée et publiée', () => { slug: demarcheSlugValidator.parse('dem-slug-pro'), description: null, demarche_visibilite: 'Confidentielle', + machine_id: null, etapes: [ { etape_type_id: 'dex', @@ -165,6 +171,7 @@ test('phase acceptée et publiée', () => { ], "events": [], "id": "idDemPro", + "machine_id": null, "ordre": 2, "slug": "dem-slug-pro", }, @@ -206,6 +213,7 @@ test('phase acceptée et publiée', () => { ], "events": [], "id": "idMut", + "machine_id": null, "ordre": 1, "slug": "slug-mut", }, diff --git a/packages/ui/src/components/titre/resultat-mise-en-concurrence.stories.tsx b/packages/ui/src/components/titre/resultat-mise-en-concurrence.stories.tsx index 8b6a955b964f3ea8a074a4896b3f4930f1374d39..59bce5b15d5eabdf2ec2df404d3c539fc4f94222 100644 --- a/packages/ui/src/components/titre/resultat-mise-en-concurrence.stories.tsx +++ b/packages/ui/src/components/titre/resultat-mise-en-concurrence.stories.tsx @@ -8,10 +8,12 @@ import { Entreprise, newEntrepriseId } from 'camino-common/src/entreprise' import { km2Validator } from 'camino-common/src/number' import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' import { action } from '@storybook/addon-actions' -import { firstEtapeDateValidator, toCaminoDate } from 'camino-common/src/date' +import { toCaminoDate } from 'camino-common/src/date' import { ApiClient } from '@/api/api-client' import { tempDocumentNameValidator } from 'camino-common/src/document' import { testBlankUser } from 'camino-common/src/tests-utils' +import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' +import { MachineInfo } from 'camino-common/src/machines' const meta: Meta = { title: 'Components/Titre/ResultatMiseEnConcurrence', @@ -80,7 +82,6 @@ const perimetreSatellite: Props['pivot']['perimetreSansSatellite'] = { surface: km2Validator.parse(5), } -const firstEtapeDate = firstEtapeDateValidator.parse('2024-10-01') const apiClient: Pick<ApiClient, 'getEtapesTypesEtapesStatuts' | 'etapeCreer' | 'uploadTempDocument' | 'getEtapeDocumentsByEtapeId'> = { getEtapeDocumentsByEtapeId: async etapeId => { getEtapeDocumentsByEtapeIdAction(etapeId) @@ -99,122 +100,143 @@ const apiClient: Pick<ApiClient, 'getEtapesTypesEtapesStatuts' | 'etapeCreer' | return tempDocumentNameValidator.parse('plop') }, } -export const Default: StoryFn = () => ( - <ResultatMiseEnConcurrence - initTab="carte" - initDate={toCaminoDate('2024-10-16')} - initDecision="acc" - entreprises={entreprises} - apiClient={{ - ...apiClient, - }} - user={{ ...testBlankUser, role: 'super' }} - pivot={{ - demarcheId, - demarcheTypeId: 'oct', - titreNom: 'Pivot', - titreSlug: titreSlugValidator.parse('titrePivotSlug'), - titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - titulaireId: entrepriseId1, - perimetreSansSatellite: perimetreSatellite, - perimetreTotal: perimetre, - firstEtapeDate: firstEtapeDate, - }} - /> -) -export const Loading: StoryFn = () => ( - <ResultatMiseEnConcurrence - initTab="carte" - initDate={toCaminoDate('2024-10-16')} - entreprises={entreprises} - apiClient={{ - ...apiClient, - getEtapesTypesEtapesStatuts() { - return new Promise(() => ({})) - }, - }} - user={{ ...testBlankUser, role: 'super' }} - pivot={{ - demarcheId, - demarcheTypeId: 'oct', - titreNom: 'Pivot', - titreSlug: titreSlugValidator.parse('titrePivotSlug'), - titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - titulaireId: entrepriseId1, - perimetreSansSatellite: perimetre, - perimetreTotal: perimetre, - firstEtapeDate: firstEtapeDate, - }} - /> -) +const machineInfo = MachineInfo.withMachineId(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, 'ProcedureSpecifique') -export const WithError: StoryFn = () => ( - <ResultatMiseEnConcurrence - initTab="carte" - initDate={toCaminoDate('2024-10-16')} - entreprises={entreprises} - apiClient={{ - ...apiClient, - getEtapesTypesEtapesStatuts() { - return Promise.resolve({ message: "Message d'erreur" }) - }, - }} - user={{ ...testBlankUser, role: 'super' }} - pivot={{ - demarcheId, - demarcheTypeId: 'oct', - titreNom: 'Pivot', - titreSlug: titreSlugValidator.parse('titrePivotSlug'), - titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - titulaireId: entrepriseId1, - perimetreSansSatellite: perimetre, - perimetreTotal: perimetre, - firstEtapeDate: firstEtapeDate, - }} - /> -) +if (!machineInfo.valid) { + throw new Error(machineInfo.error) +} +export const Default: StoryFn = () => { + return ( + <ResultatMiseEnConcurrence + initTab="carte" + initDate={toCaminoDate('2024-10-16')} + initDecision="acc" + entreprises={entreprises} + apiClient={{ + ...apiClient, + }} + user={{ ...testBlankUser, role: 'super' }} + pivot={{ + demarcheId, + demarcheTypeId: DEMARCHES_TYPES_IDS.Octroi, + titreNom: 'Pivot', + titreSlug: titreSlugValidator.parse('titrePivotSlug'), + titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + titulaireId: entrepriseId1, + perimetreSansSatellite: perimetreSatellite, + perimetreTotal: perimetre, + machineId: 'ProcedureSpecifique', + }} + machineInfo={machineInfo.value} + /> + ) +} + +export const Loading: StoryFn = () => { + return ( + <ResultatMiseEnConcurrence + initTab="carte" + initDate={toCaminoDate('2024-10-16')} + entreprises={entreprises} + apiClient={{ + ...apiClient, + getEtapesTypesEtapesStatuts() { + return new Promise(() => ({})) + }, + }} + user={{ ...testBlankUser, role: 'super' }} + pivot={{ + demarcheId, + demarcheTypeId: 'oct', + titreNom: 'Pivot', + titreSlug: titreSlugValidator.parse('titrePivotSlug'), + titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + titulaireId: entrepriseId1, + perimetreSansSatellite: perimetre, + perimetreTotal: perimetre, + machineId: 'ProcedureSpecifique', + }} + machineInfo={machineInfo.value} + /> + ) +} -export const PerimetreSansSatellite: StoryFn = () => ( - <ResultatMiseEnConcurrence - initTab="carte" - initDate={toCaminoDate('2024-10-16')} - initDecision="acc" - entreprises={entreprises} - apiClient={apiClient} - user={{ ...testBlankUser, role: 'super' }} - pivot={{ - demarcheId, - demarcheTypeId: 'oct', - titreNom: 'Pivot', - titreSlug: titreSlugValidator.parse('titrePivotSlug'), - titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - titulaireId: entrepriseId1, - perimetreSansSatellite: { geojson4326_perimetre: null, surface: km2Validator.parse(0) }, - perimetreTotal: perimetre, - firstEtapeDate: firstEtapeDate, - }} - /> -) +export const WithError: StoryFn = () => { + return ( + <ResultatMiseEnConcurrence + initTab="carte" + initDate={toCaminoDate('2024-10-16')} + entreprises={entreprises} + apiClient={{ + ...apiClient, + getEtapesTypesEtapesStatuts() { + return Promise.resolve({ message: "Message d'erreur" }) + }, + }} + user={{ ...testBlankUser, role: 'super' }} + pivot={{ + demarcheId, + demarcheTypeId: 'oct', + titreNom: 'Pivot', + titreSlug: titreSlugValidator.parse('titrePivotSlug'), + titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + titulaireId: entrepriseId1, + perimetreSansSatellite: perimetre, + perimetreTotal: perimetre, + machineId: 'ProcedureSpecifique', + }} + machineInfo={machineInfo.value} + /> + ) +} + +export const PerimetreSansSatellite: StoryFn = () => { + return ( + <ResultatMiseEnConcurrence + initTab="carte" + initDate={toCaminoDate('2024-10-16')} + initDecision="acc" + entreprises={entreprises} + apiClient={apiClient} + user={{ ...testBlankUser, role: 'super' }} + pivot={{ + demarcheId, + demarcheTypeId: 'oct', + titreNom: 'Pivot', + titreSlug: titreSlugValidator.parse('titrePivotSlug'), + titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + titulaireId: entrepriseId1, + perimetreSansSatellite: { geojson4326_perimetre: null, surface: km2Validator.parse(0) }, + perimetreTotal: perimetre, + machineId: 'ProcedureSpecifique', + }} + machineInfo={machineInfo.value} + /> + ) +} -export const PerimetreAvecSatelliteEquivalent: StoryFn = () => ( - <ResultatMiseEnConcurrence - initTab="carte" - initDate={toCaminoDate('2024-10-16')} - initDecision="acc" - entreprises={entreprises} - apiClient={apiClient} - user={{ ...testBlankUser, role: 'super' }} - pivot={{ - demarcheId, - demarcheTypeId: 'oct', - titreNom: 'Pivot', - titreSlug: titreSlugValidator.parse('titrePivotSlug'), - titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, - titulaireId: entrepriseId1, - perimetreSansSatellite: perimetre, - perimetreTotal: perimetre, - firstEtapeDate: firstEtapeDate, - }} - /> -) +export const PerimetreAvecSatelliteEquivalent: StoryFn = () => { + return ( + <ResultatMiseEnConcurrence + initTab="carte" + initDate={toCaminoDate('2024-10-16')} + initDecision="acc" + entreprises={entreprises} + apiClient={apiClient} + user={{ ...testBlankUser, role: 'super' }} + pivot={{ + demarcheId, + demarcheTypeId: 'oct', + titreNom: 'Pivot', + titreSlug: titreSlugValidator.parse('titrePivotSlug'), + titreTypeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, + titulaireId: entrepriseId1, + perimetreSansSatellite: perimetre, + perimetreTotal: perimetre, + machineId: 'ProcedureSpecifique', + }} + machineInfo={machineInfo.value} + /> + ) +} diff --git a/packages/ui/src/components/titre/resultat-mise-en-concurrence.tsx b/packages/ui/src/components/titre/resultat-mise-en-concurrence.tsx index 0f562fd6af890146587c63dd8b3e549b21124e2c..9b85dabf13edfecba5a886683741eb8a3594c44b 100644 --- a/packages/ui/src/components/titre/resultat-mise-en-concurrence.tsx +++ b/packages/ui/src/components/titre/resultat-mise-en-concurrence.tsx @@ -22,6 +22,7 @@ import { ETAPES_STATUTS, EtapesStatuts } from 'camino-common/src/static/etapesSt import { User } from 'camino-common/src/roles' import { ETAPE_IS_NOT_BROUILLON, EtapeDocument, TempEtapeDocument } from 'camino-common/src/etape' import { EtapeDocumentsEdit } from '../etape/etape-documents-edit' +import { MachineInfo } from 'camino-common/src/machines' export type Props = { apiClient: Pick<ApiClient, 'getEtapesTypesEtapesStatuts' | 'etapeCreer' | 'uploadTempDocument' | 'getEtapeDocumentsByEtapeId'> @@ -30,6 +31,7 @@ export type Props = { initDate?: CaminoDate initDecision?: 'acc' | 'rej' pivot: GetResultatMiseEnConcurrence + machineInfo: MachineInfo user: User } @@ -221,7 +223,7 @@ export const ResultatMiseEnConcurrence = defineComponent<Props>(props => { perimetre={perimetre.value} id="perimetre_final" titreSlug={props.pivot.titreSlug} - titreTypeId={props.pivot.titreTypeId} + machineInfo={props.machineInfo} initTab={props.initTab ?? 'carte'} /> </> @@ -255,10 +257,7 @@ export const ResultatMiseEnConcurrence = defineComponent<Props>(props => { user={props.user} sdomZoneIds={[]} tde={{ - demarcheId: props.pivot.demarcheId, - demarcheTypeId: props.pivot.demarcheTypeId, - titreTypeId: props.pivot.titreTypeId, - firstEtapeDate: props.pivot.firstEtapeDate, + machineInfo: props.machineInfo, etapeTypeId: ETAPES_TYPES.resultatMiseEnConcurrence, }} completeUpdate={onDocumentUpdate} @@ -278,4 +277,4 @@ export const ResultatMiseEnConcurrence = defineComponent<Props>(props => { }) // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 -ResultatMiseEnConcurrence.props = ['initTab', 'pivot', 'entreprises', 'apiClient', 'initDate', 'initDecision', 'user'] +ResultatMiseEnConcurrence.props = ['initTab', 'pivot', 'machineInfo', 'entreprises', 'apiClient', 'initDate', 'initDecision', 'user'] diff --git a/packages/ui/src/components/titre/titre-demarche.tsx b/packages/ui/src/components/titre/titre-demarche.tsx index ef73ad7e542d3c1d6cf59a69cad25d6ed4c8894c..50c6bdd1c0dbeffb23a143dd10a8287571dda508 100644 --- a/packages/ui/src/components/titre/titre-demarche.tsx +++ b/packages/ui/src/components/titre/titre-demarche.tsx @@ -1,6 +1,6 @@ import { FunctionalComponent, computed, defineComponent, ref } from 'vue' import { getMostRecentValuePropFromEtapeFondamentaleValide, TitreGet, TitreGetDemarche } from 'camino-common/src/titres' -import { demarcheEnregistrementDemandeDateFind, DemarcheEtapeFondamentale, DemarcheSlug, getDemarcheContenu } from 'camino-common/src/demarche' +import { DemarcheEtapeFondamentale, DemarcheId, DemarcheSlug, getDemarcheContenu } from 'camino-common/src/demarche' import { DemarchesTypes, isTravaux } from 'camino-common/src/static/demarchesTypes' import { DemarcheStatut } from '@/components/_common/demarche-statut' import { isNonEmptyArray, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefined, onlyUnique } from 'camino-common/src/typescript-tools' @@ -25,14 +25,15 @@ import { isDemarcheStatutNonStatue, isDemarcheStatutNonValide } from 'camino-com import { capitalize } from 'camino-common/src/strings' import { CaminoRouter } from '@/typings/vue-router' import { Alert } from '../_ui/alert' -import { CaminoDate, firstEtapeDateValidator } from 'camino-common/src/date' -import { machineIdFind } from 'camino-common/src/machines' +import { CaminoDate } from 'camino-common/src/date' import { fr } from '@codegouvfr/react-dsfr' import { DemarcheVisibilite } from '../_common/demarche-visibilite' +import { MachineInfo } from 'camino-common/src/machines' type Props = { titre: Pick<TitreGet, 'id' | 'slug' | 'titre_type_id' | 'titre_statut_id' | 'nom' | 'titre_visibilite'> demarches: TitreGetDemarche[] + machinesInfo: Record<DemarcheId, MachineInfo> currentDemarcheSlug: DemarcheSlug currentDate: CaminoDate apiClient: Pick<ApiClient, 'deleteEtape' | 'deposeEtape' | 'getTitresWithPerimetreForCarte' | 'createDemarche' | 'updateDemarche' | 'deleteDemarche' | 'getEtapesTypesEtapesStatuts' | 'etapeCreer'> @@ -170,7 +171,7 @@ export const TitreDemarche = defineComponent<Props>(props => { icon="fr-icon-delete-bin-line" class="fr-ml-2w" buttonType="secondary" - title={`Supprimer la démarche ${isNotNullNorUndefinedNorEmpty(orderedEtapes.value) ? (machineIdFind(props.titre.titre_type_id, demarche.value.demarche_type_id, demarche.value.id, demarcheEnregistrementDemandeDateFind(orderedEtapes.value.map(etape => ({ date: etape.date, typeId: etape.etape_type_id }))) ?? firstEtapeDateValidator.parse(orderedEtapes.value)) ?? 'TDE') : 'vide'}`} + title={`Supprimer la démarche ${isNotNullNorUndefined(demarche.value.machine_id) ? demarche.value.machine_id : 'TDE'}`} onClick={openDeleteDemarchePopup} /> ) : null} @@ -221,7 +222,7 @@ export const TitreDemarche = defineComponent<Props>(props => { <DsfrPerimetre class="fr-pt-3w" titreSlug={props.titre.slug} - titreTypeId={props.titre.titre_type_id} + machineInfo={props.machinesInfo[demarche.value.id]} id={props.currentDemarcheSlug} apiClient={props.apiClient} calculateNeighbours={true} @@ -235,7 +236,7 @@ export const TitreDemarche = defineComponent<Props>(props => { <div class="fr-mt-3w" style={{ display: 'flex', alignContent: 'center' }}> <h3 class="fr-mb-0">Étapes</h3> <div style={{ marginLeft: 'auto' }}> - {canPublishResultatMiseEnConcurrence(props.user, props.titre.titre_type_id, demarche.value.demarche_type_id, demarche.value.etapes, demarche.value.id).valid ? ( + {canPublishResultatMiseEnConcurrence(props.user, props.machinesInfo[demarche.value.id], demarche.value.etapes).valid ? ( <DsfrLink buttonType="primary" class="fr-mr-2w" @@ -247,11 +248,7 @@ export const TitreDemarche = defineComponent<Props>(props => { ) : null} {canCreateEtapeByDemarche(props.user, props.titre.titre_type_id, demarche.value.demarche_type_id, administrations.value, props.titre.titre_statut_id) ? ( <DsfrLink - buttonType={ - canPublishResultatMiseEnConcurrence(props.user, props.titre.titre_type_id, demarche.value.demarche_type_id, demarche.value.etapes, demarche.value.id).valid - ? 'secondary' - : 'primary' - } + buttonType={canPublishResultatMiseEnConcurrence(props.user, props.machinesInfo[demarche.value.id], demarche.value.etapes).valid ? 'secondary' : 'primary'} icon={null} disabled={false} title="Ajouter une étape" @@ -287,6 +284,7 @@ export const TitreDemarche = defineComponent<Props>(props => { sdom_zones: perimetre.value?.sdom_zones ?? [], communes: perimetre.value?.communes?.map(({ id }) => id) ?? [], etapes: demarche.value.etapes, + machineInfo: props.machinesInfo[demarche.value.id], }} apiClient={props.apiClient} currentDate={props.currentDate} @@ -338,7 +336,20 @@ export const TitreDemarche = defineComponent<Props>(props => { }) // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833 -TitreDemarche.props = ['titre', 'demarches', 'currentDemarcheSlug', 'currentDate', 'apiClient', 'user', 'entreprises', 'router', 'initTab', 'demarcheCreatedOrUpdated', 'demarcheDeleted'] +TitreDemarche.props = [ + 'titre', + 'demarches', + 'machinesInfo', + 'currentDemarcheSlug', + 'currentDate', + 'apiClient', + 'user', + 'entreprises', + 'router', + 'initTab', + 'demarcheCreatedOrUpdated', + 'demarcheDeleted', +] const DisplayLocalisation: FunctionalComponent<Pick<DemarcheEtapeFondamentale['fondamentale'], 'perimetre'>> = props => { if (isNullOrUndefined(props.perimetre)) {