diff --git a/packages/api/src/business/rules-demarches/procedure-simplifiee/ps.machine.test.ts b/packages/api/src/business/rules-demarches/procedure-simplifiee/ps.machine.test.ts index 24dd6a13cccf499df9e37f64a96d91dcb25521e2..ab488b80c273a7a8b0e69b6ca282a99150e2f836 100644 --- a/packages/api/src/business/rules-demarches/procedure-simplifiee/ps.machine.test.ts +++ b/packages/api/src/business/rules-demarches/procedure-simplifiee/ps.machine.test.ts @@ -20,6 +20,7 @@ describe('vérifie l’arbre des procédures historiques et simplifiées', () => 'FAIRE_DEMANDE', 'RENDRE_DECISION_ADMINISTRATION_ACCEPTEE', 'RENDRE_DECISION_ADMINISTRATION_REJETEE', + 'RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE', ]) expect(service.getSnapshot().context.demarcheStatut).toBe(DemarchesStatutsIds.EnConstruction) }) @@ -29,6 +30,7 @@ describe('vérifie l’arbre des procédures historiques et simplifiées', () => 'FAIRE_DEMANDE', 'RENDRE_DECISION_ADMINISTRATION_ACCEPTEE', 'RENDRE_DECISION_ADMINISTRATION_REJETEE', + 'RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE', 'SAISIR_INFORMATION_HISTORIQUE_INCOMPLETE', 'PUBLIER_DECISION_ACCEPTEE_AU_JORF', 'PUBLIER_DECISION_AU_RECUEIL_DES_ACTES_ADMINISTRATIFS', @@ -62,6 +64,7 @@ describe('vérifie l’arbre des procédures historiques et simplifiées', () => 'OUVRIR_PARTICIPATION_DU_PUBLIC', 'RENDRE_DECISION_ADMINISTRATION_ACCEPTEE', 'RENDRE_DECISION_ADMINISTRATION_REJETEE', + 'RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE', ]) expect(service.getSnapshot().context.demarcheStatut).toBe(DemarchesStatutsIds.EnInstruction) }) @@ -76,6 +79,7 @@ describe('vérifie l’arbre des procédures historiques et simplifiées', () => 'OUVRIR_PARTICIPATION_DU_PUBLIC', 'RENDRE_DECISION_ADMINISTRATION_ACCEPTEE', 'RENDRE_DECISION_ADMINISTRATION_REJETEE', + 'RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE', ]) expect(service.getSnapshot().context.demarcheStatut).toBe(DemarchesStatutsIds.EnInstruction) }) @@ -83,7 +87,7 @@ describe('vérifie l’arbre des procédures historiques et simplifiées', () => test('ne peut pas faire deux dépôts de la demande', () => { const etapes = [ETES.demande.FAIT, ETES.depotDeLaDemande.FAIT, ETES.depotDeLaDemande.FAIT] expect(() => setDateAndOrderAndInterpretMachine(psMachine, '2022-04-12', etapes)).toThrowErrorMatchingInlineSnapshot( - `[Error: Error: cannot execute step: '{"etapeTypeId":"mdp","etapeStatutId":"fai","date":"2022-04-15"}' after '["mfr_fai","mdp_fai"]'. The event {"type":"DEPOSER_DEMANDE"} should be one of 'CLASSER_SANS_SUITE,DEMANDER_INFORMATION,DESISTER_PAR_LE_DEMANDEUR,OUVRIR_PARTICIPATION_DU_PUBLIC,RECEVOIR_INFORMATION,RENDRE_DECISION_ADMINISTRATION_ACCEPTEE,RENDRE_DECISION_ADMINISTRATION_REJETEE']` + `[Error: Error: cannot execute step: '{"etapeTypeId":"mdp","etapeStatutId":"fai","date":"2022-04-15"}' after '["mfr_fai","mdp_fai"]'. The event {"type":"DEPOSER_DEMANDE"} should be one of 'CLASSER_SANS_SUITE,DEMANDER_INFORMATION,DESISTER_PAR_LE_DEMANDEUR,OUVRIR_PARTICIPATION_DU_PUBLIC,RECEVOIR_INFORMATION,RENDRE_DECISION_ADMINISTRATION_ACCEPTEE,RENDRE_DECISION_ADMINISTRATION_REJETEE,RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE']` ) }) @@ -169,6 +173,7 @@ describe('vérifie l’arbre des procédures historiques et simplifiées', () => 'RECEVOIR_INFORMATION', 'RENDRE_DECISION_ADMINISTRATION_ACCEPTEE', 'RENDRE_DECISION_ADMINISTRATION_REJETEE', + 'RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE', ]) }) test("peut faire deux demandes d'information consécutives", () => { @@ -188,6 +193,7 @@ describe('vérifie l’arbre des procédures historiques et simplifiées', () => 'DESISTER_PAR_LE_DEMANDEUR', 'RENDRE_DECISION_ADMINISTRATION_ACCEPTEE', 'RENDRE_DECISION_ADMINISTRATION_REJETEE', + 'RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE', ]) }) @@ -222,12 +228,19 @@ describe('vérifie l’arbre des procédures historiques et simplifiées', () => expect(service.getSnapshot().context.visibilite).toBe('confidentielle') }) - test("peut rejeter immédiatement un décision de l'administration", () => { + test("peut rejeter immédiatement une décision de l'administration", () => { const { service, dateFin } = setDateAndOrderAndInterpretMachine(psMachine, '2022-04-08', [ETES.decisionDeLadministration.REJETE]) expect(service).canOnlyTransitionTo({ machine: psMachine, date: dateFin }, ['PUBLIER_DECISION_ACCEPTEE_AU_JORF']) expect(service.getSnapshot().context.demarcheStatut).toBe(DemarchesStatutsIds.Rejete) expect(service.getSnapshot().context.visibilite).toBe('confidentielle') }) + + test("peut rejeter par décision implicite une décision de l'administration", () => { + const { service, dateFin } = setDateAndOrderAndInterpretMachine(psMachine, '2022-04-08', [ETES.decisionDeLadministration.REJETE_DECISION_IMPLICITE]) + expect(service).canOnlyTransitionTo({ machine: psMachine, date: dateFin }, []) + expect(service.getSnapshot().context.demarcheStatut).toBe(DemarchesStatutsIds.Rejete) + expect(service.getSnapshot().context.visibilite).toBe('publique') + }) // pour regénérer le oct.cas.json: `npm run test:generate-data -w packages/api` test.each(etapesProdProceduresHistoriques as any[])('cas réel N°$id', demarche => { // ici les étapes sont déjà ordonnées diff --git a/packages/api/src/business/rules-demarches/procedure-simplifiee/ps.machine.ts b/packages/api/src/business/rules-demarches/procedure-simplifiee/ps.machine.ts index 3683ee0fdb14aa5768d556d8c569f811aae38499..9e95e63e4e54e53f9e1418b059367621d4e481dd 100644 --- a/packages/api/src/business/rules-demarches/procedure-simplifiee/ps.machine.ts +++ b/packages/api/src/business/rules-demarches/procedure-simplifiee/ps.machine.ts @@ -18,7 +18,10 @@ type RendreDecisionAdministrationRejetee = { date: CaminoDate type: 'RENDRE_DECISION_ADMINISTRATION_REJETEE' } - +type RendreDecisionAdministrationRejeteeDecisionImplicite = { + date: CaminoDate + type: 'RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE' +} type PublierDecisionAccepteeAuJORF = { date: CaminoDate type: 'PUBLIER_DECISION_ACCEPTEE_AU_JORF' @@ -39,6 +42,7 @@ type ProcedureSimplifieeXStateEvent = | ParticipationDuPublic | RendreDecisionAdministrationAcceptee | RendreDecisionAdministrationRejetee + | RendreDecisionAdministrationRejeteeDecisionImplicite | SaisirInformationHistoriqueIncomplete | PublierDecisionAccepteeAuJORF | PublierDecisionAuRecueilDesActesAdministratifs @@ -56,6 +60,7 @@ const trad: { [key in Event]: { db: DBEtat; mainStep: boolean } } = { OUVRIR_PARTICIPATION_DU_PUBLIC: { db: ETES.participationDuPublic, mainStep: true }, RENDRE_DECISION_ADMINISTRATION_ACCEPTEE: { db: { ACCEPTE: ETES.decisionDeLadministration.ACCEPTE }, mainStep: true }, RENDRE_DECISION_ADMINISTRATION_REJETEE: { db: { REJETE: ETES.decisionDeLadministration.REJETE }, mainStep: true }, + RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE: { db: { REJETE_DECISION_IMPLICITE: ETES.decisionDeLadministration.REJETE_DECISION_IMPLICITE }, mainStep: true }, PUBLIER_DECISION_ACCEPTEE_AU_JORF: { db: { FAIT: ETES.publicationDeDecisionAuJORF.FAIT }, mainStep: true }, PUBLIER_DECISION_AU_RECUEIL_DES_ACTES_ADMINISTRATIFS: { db: ETES.publicationDeDecisionAuRecueilDesActesAdministratifs, mainStep: true }, CLASSER_SANS_SUITE: { db: ETES.classementSansSuite, mainStep: false }, @@ -79,6 +84,7 @@ export class ProcedureSimplifieeMachine extends CaminoMachine<ProcedureSimplifie switch (event) { case 'RENDRE_DECISION_ADMINISTRATION_ACCEPTEE': case 'RENDRE_DECISION_ADMINISTRATION_REJETEE': + case 'RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE': case 'SAISIR_INFORMATION_HISTORIQUE_INCOMPLETE': case 'PUBLIER_DECISION_ACCEPTEE_AU_JORF': case 'PUBLIER_DECISION_AU_RECUEIL_DES_ACTES_ADMINISTRATIFS': @@ -108,7 +114,8 @@ export class ProcedureSimplifieeMachine extends CaminoMachine<ProcedureSimplifie case 'PUBLIER_DECISION_AU_RECUEIL_DES_ACTES_ADMINISTRATIFS': case 'SAISIR_INFORMATION_HISTORIQUE_INCOMPLETE': case 'RENDRE_DECISION_ADMINISTRATION_ACCEPTEE': - case 'RENDRE_DECISION_ADMINISTRATION_REJETEE': { + case 'RENDRE_DECISION_ADMINISTRATION_REJETEE': + case 'RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE': { return { type: eventFromEntry, date: etape.date } } case 'OUVRIR_PARTICIPATION_DU_PUBLIC': { @@ -181,6 +188,14 @@ const procedureSimplifieeMachine = createMachine({ demarcheStatut: DemarchesStatutsIds.Rejete, }), }, + RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE: { + guard: ({ context, event }) => isBefore(event.date, procedureHistoriqueDateMax) && context.demarcheStatut === defaultDemarcheStatut, + target: '.finDeMachine', + actions: assign({ + visibilite: 'publique', + demarcheStatut: DemarchesStatutsIds.Rejete, + }), + }, CLASSER_SANS_SUITE: { guard: ({ context }) => context.demarcheStatut === DemarchesStatutsIds.EnInstruction, target: '.finDeMachine', @@ -248,6 +263,14 @@ const procedureSimplifieeMachine = createMachine({ }), target: 'finDeMachine', }, + RENDRE_DECISION_ADMINISTRATION_REJETEE_DECISION_IMPLICITE: { + guard: ({ context }) => isNullOrUndefined(context.ouverturePublicStatut) || context.ouverturePublicStatut === ETAPES_STATUTS.TERMINE, + actions: assign({ + visibilite: 'publique', + demarcheStatut: DemarchesStatutsIds.Rejete, + }), + target: 'finDeMachine', + }, }, }, publicationAuRecueilDesActesAdministratifsOupublicationAuJORFAFaire: { diff --git a/packages/common/src/static/etapesStatuts.ts b/packages/common/src/static/etapesStatuts.ts index cd05e049ddf329dd91425db0f57691a1e9400665..5525ebf997ca417c2d5abe44c52563e94ac431cc 100644 --- a/packages/common/src/static/etapesStatuts.ts +++ b/packages/common/src/static/etapesStatuts.ts @@ -1,7 +1,7 @@ import { Couleur } from './couleurs' import { z } from 'zod' -const IDS = ['acc', 'dre', 'enc', 'fai', 'dep', 'exe', 'req', 'com', 'inc', 'fav', 'def', 'fre', 'ajo', 'rej', 'ter', 'nul', 'pro'] as const +const IDS = ['acc', 'dre', 'enc', 'fai', 'dep', 'exe', 'req', 'com', 'inc', 'fav', 'def', 'fre', 'ajo', 'rej', 'rei', 'ter', 'nul', 'pro'] as const export const ETAPES_STATUTS = { ACCEPTE: 'acc', DEFAVORABLE_AVEC_RESERVES: 'dre', @@ -17,6 +17,7 @@ export const ETAPES_STATUTS = { FAVORABLE_AVEC_RESERVE: 'fre', AJOURNE: 'ajo', REJETE: 'rej', + REJETE_DECISION_IMPLICITE: 'rei', TERMINE: 'ter', NON_APPLICABLE: 'nul', PROGRAMME: 'pro', @@ -57,6 +58,12 @@ export const EtapesStatuts: { [key in EtapeStatutId]: EtapeStatut<key> } = { description: "La demande a fait l’objet d’une décision défavorable de l'administration. Les textes d’applications du code minier prévoient que les décisions de rejet ne font pas l’objet d’une publication. En conséquence, les démarches qui passent au statut “rejeté” dans Camino sont dé-publiées et rendues inaccessibles aux tiers.\n", }, + rei: { + id: 'rei', + nom: 'rejeté - décision implicite', + couleur: 'error', + description: '', + }, req: { id: 'req', nom: 'requis', couleur: 'neutral' }, ter: { id: 'ter', diff --git a/packages/common/src/static/etapesTypesEtapesStatuts.ts b/packages/common/src/static/etapesTypesEtapesStatuts.ts index 001daad0a32e3650e952bcf1b3fd475bea0c95a9..a86615c0600aa0aca0c34ed6122fde02c997f3a5 100644 --- a/packages/common/src/static/etapesTypesEtapesStatuts.ts +++ b/packages/common/src/static/etapesTypesEtapesStatuts.ts @@ -109,6 +109,7 @@ export const EtapesTypesEtapesStatuts = { decisionDeLadministration: { ACCEPTE: { etapeTypeId: 'dex', etapeStatutId: 'acc' }, REJETE: { etapeTypeId: 'dex', etapeStatutId: 'rej' }, + REJETE_DECISION_IMPLICITE: { etapeTypeId: 'dex', etapeStatutId: 'rei' }, }, decisionImplicite: { ACCEPTE: { etapeTypeId: 'dim', etapeStatutId: 'acc' }, diff --git a/packages/ui/src/components/_common/etape-statut.stories_snapshots_All.html b/packages/ui/src/components/_common/etape-statut.stories_snapshots_All.html index 639491f2d11b650a54fa28f1af5c21566c58acdb..091550debb693ac141c8ab11760aa01ee2ececdd 100644 --- a/packages/ui/src/components/_common/etape-statut.stories_snapshots_All.html +++ b/packages/ui/src/components/_common/etape-statut.stories_snapshots_All.html @@ -94,6 +94,12 @@ <p style="z-index: unset; margin-bottom: 0px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="fr-badge fr-badge--md fr-badge--purple-glycine" title="rejeté" aria-label="rejeté">rejeté</p> </td> </tr> + <tr> + <td>rejeté - décision implicite</td> + <td> + <p style="z-index: unset; margin-bottom: 0px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="fr-badge fr-badge--md fr-badge--purple-glycine" title="rejeté - décision implicite" aria-label="rejeté - décision implicite">rejeté - décision implicite</p> + </td> + </tr> <tr> <td>requis</td> <td> diff --git a/packages/ui/src/components/_common/etape-statut.tsx b/packages/ui/src/components/_common/etape-statut.tsx index 4b42f62c95475fb1140e7c32285d874910f67eb0..c21d9dfcb804a3d097acb70f2c643476a31bf8b8 100644 --- a/packages/ui/src/components/_common/etape-statut.tsx +++ b/packages/ui/src/components/_common/etape-statut.tsx @@ -23,6 +23,7 @@ const couleurParStatut = { [ETAPES_STATUTS.FAVORABLE_AVEC_RESERVE]: 'green-bourgeon', [ETAPES_STATUTS.AJOURNE]: 'orange-terre-battue', [ETAPES_STATUTS.REJETE]: 'purple-glycine', + [ETAPES_STATUTS.REJETE_DECISION_IMPLICITE]: 'purple-glycine', [ETAPES_STATUTS.TERMINE]: 'green-bourgeon', [ETAPES_STATUTS.NON_APPLICABLE]: 'beige-gris-galet', [ETAPES_STATUTS.PROGRAMME]: 'orange-terre-battue',