Skip to content
This repository has been archived by the owner on Sep 17, 2024. It is now read-only.

refactor(etapes): le format d'échange des étapes possibles à une date donnée est amélioré #1462

Merged
merged 1 commit into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 43 additions & 76 deletions packages/api/src/api/rest/etapes.test.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,63 +54,35 @@ describe('getEtapesTypesEtapesStatusWithMainStep', () => {
const tested = await restCall(dbPool, '/rest/etapesTypes/:demarcheId/:date', { demarcheId: titreDemarche.id, date: toCaminoDate('2024-09-01') }, userSuper)

expect(tested.statusCode).toBe(HTTP_STATUS.OK)
// TODO 2024-06-19 changer ce format ?
// Partir plutôt sur un object avec comme clé le etapeTypeId, une liste de etapeStatut associée et la clé mainStep (soit sur le statut, soit directement au top niveau)
// soit { mfr: {statuts: ['fai'], mainStep: true}}
// soit { mfr: {statuts: [{id: 'fai', mainStep: true}]}}
expect(tested.body).toMatchInlineSnapshot(`
[
{
"etapeStatutId": "fai",
"etapeTypeId": "mfr",
"mainStep": true,
},
{
"etapeStatutId": "fai",
"etapeTypeId": "mfr",
"mainStep": true,
},
{
"etapeStatutId": "fai",
"etapeTypeId": "mfr",
{
"dae": {
"etapeStatutIds": [
"req",
"exe",
],
"mainStep": true,
},
{
"etapeStatutId": "fai",
"etapeTypeId": "mfr",
"mfr": {
"etapeStatutIds": [
"fai",
],
"mainStep": true,
},
{
"etapeStatutId": "fai",
"etapeTypeId": "mfr",
"pfd": {
"etapeStatutIds": [
"fai",
],
"mainStep": true,
},
{
"etapeStatutId": "fai",
"etapeTypeId": "pfd",
"rde": {
"etapeStatutIds": [
"def",
"fav",
],
"mainStep": true,
},
{
"etapeStatutId": "req",
"etapeTypeId": "dae",
"mainStep": false,
},
{
"etapeStatutId": "exe",
"etapeTypeId": "dae",
"mainStep": true,
},
{
"etapeStatutId": "def",
"etapeTypeId": "rde",
"mainStep": false,
},
{
"etapeStatutId": "fav",
"etapeTypeId": "rde",
"mainStep": true,
},
]
}
`)
})
test('nouvelle étapes possibles prends en compte les brouillons', async () => {
Expand Down Expand Up @@ -145,34 +117,29 @@ describe('getEtapesTypesEtapesStatusWithMainStep', () => {

expect(tested.statusCode).toBe(HTTP_STATUS.OK)
expect(tested.body).toMatchInlineSnapshot(`
[
{
"etapeStatutId": "fai",
"etapeTypeId": "pfd",
"mainStep": true,
},
{
"etapeStatutId": "req",
"etapeTypeId": "dae",
"mainStep": false,
},
{
"etapeStatutId": "exe",
"etapeTypeId": "dae",
"mainStep": true,
},
{
"etapeStatutId": "def",
"etapeTypeId": "rde",
"mainStep": false,
},
{
"etapeStatutId": "fav",
"etapeTypeId": "rde",
"mainStep": true,
},
]
`)
{
"dae": {
"etapeStatutIds": [
"req",
"exe",
],
"mainStep": true,
},
"pfd": {
"etapeStatutIds": [
"fai",
],
"mainStep": true,
},
"rde": {
"etapeStatutIds": [
"def",
"fav",
],
"mainStep": true,
},
}
`)
})
})

Expand Down
36 changes: 26 additions & 10 deletions packages/api/src/api/rest/etapes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,18 @@ import { machineFind } from '../../business/rules-demarches/definitions'
import { User, isBureauDEtudes, isEntreprise } from 'camino-common/src/roles'
import { canCreateEtape, canDeposeEtape, canDeleteEtape, canEditEtape, canEditDates, canEditDuree } from 'camino-common/src/permissions/titres-etapes'
import { TitresStatutIds } from 'camino-common/src/static/titresStatuts'
import { canBeBrouillon } from 'camino-common/src/static/etapesTypes'
import { DeepReadonly, SimplePromiseFn, isNonEmptyArray, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty, isNullOrUndefined, memoize, onlyUnique } from 'camino-common/src/typescript-tools'
import { canBeBrouillon, isEtapeTypeId } from 'camino-common/src/static/etapesTypes'
import {
DeepReadonly,
SimplePromiseFn,
getKeys,
isNonEmptyArray,
isNotNullNorUndefined,
isNotNullNorUndefinedNorEmpty,
isNullOrUndefined,
memoize,
onlyUnique,
} from 'camino-common/src/typescript-tools'
import { Pool } from 'pg'
import { EntrepriseDocument, EntrepriseDocumentId, EntrepriseId, EtapeEntrepriseDocument } from 'camino-common/src/entreprise'
import {
Expand Down Expand Up @@ -1010,7 +1020,7 @@ export const deposeEtape =

export const getEtapesTypesEtapesStatusWithMainStep =
(_pool: Pool) =>
async (req: CaminoRequest, res: CustomResponse<EtapeTypeEtapeStatutWithMainStep[]>): Promise<void> => {
async (req: CaminoRequest, res: CustomResponse<EtapeTypeEtapeStatutWithMainStep>): Promise<void> => {
const demarcheIdParsed = demarcheIdValidator.safeParse(req.params.demarcheId)
const dateParsed = caminoDateValidator.safeParse(req.params.date)
const etapeIdParsed = z.optional(etapeIdValidator).safeParse(req.query.etapeId)
Expand Down Expand Up @@ -1059,7 +1069,7 @@ const demarcheEtapesTypesGet = async (titreDemarcheId: DemarcheId, date: CaminoD

const demarcheDefinition = machineFind(titre.typeId, titreDemarche.typeId, titreDemarche.etapes, titreDemarche.id, date)

const etapesTypes: EtapeTypeEtapeStatutWithMainStep[] = getPossiblesEtapesTypes(
const etapesTypes: EtapeTypeEtapeStatutWithMainStep = getPossiblesEtapesTypes(
demarcheDefinition,
titre.typeId,
titreDemarche.typeId,
Expand All @@ -1069,10 +1079,16 @@ const demarcheEtapesTypesGet = async (titreDemarcheId: DemarcheId, date: CaminoD
titreDemarche.etapes
)

return etapesTypes.filter(({ etapeTypeId }) =>
canCreateEtape(user, etapeTypeId, ETAPE_IS_BROUILLON, titre.titulaireIds ?? [], titre.administrationsLocales ?? [], titreDemarche.typeId, {
typeId: titre.typeId,
titreStatutId: titre.titreStatutId ?? TitresStatutIds.Indetermine,
})
)
return getKeys(etapesTypes, isEtapeTypeId).reduce<EtapeTypeEtapeStatutWithMainStep>((acc, etapeTypeId) => {
if (
canCreateEtape(user, etapeTypeId, ETAPE_IS_BROUILLON, titre.titulaireIds ?? [], titre.administrationsLocales ?? [], titreDemarche.typeId, {
typeId: titre.typeId,
titreStatutId: titre.titreStatutId ?? TitresStatutIds.Indetermine,
})
) {
acc[etapeTypeId] = etapesTypes[etapeTypeId]
}

return acc
}, {})
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { describe, test, expect, vi } from 'vitest'
import { caminoDateValidator, toCaminoDate } from 'camino-common/src/date'
import { EtapeTypeId } from 'camino-common/src/static/etapesTypes'
import { ETAPE_IS_BROUILLON, ETAPE_IS_NOT_BROUILLON, etapeIdValidator } from 'camino-common/src/etape'
import { onlyUnique } from 'camino-common/src/typescript-tools'
import { ArmOctMachine } from '../rules-demarches/arm/oct.machine'
import { TitreEtapeForMachine } from '../rules-demarches/machine-common'
import { communeIdValidator } from 'camino-common/src/static/communes'
Expand Down Expand Up @@ -539,34 +538,44 @@ describe('etapesTypesPossibleACetteDateOuALaPlaceDeLEtape', function () {
const machine = new ArmOctMachine()
test('modifie une étape existante', () => {
const tested = etapesTypesPossibleACetteDateOuALaPlaceDeLEtape(machine, etapes, 'etapeId3', toCaminoDate('2019-10-11'))
expect(tested).toHaveLength(1)
expect(tested[0].etapeTypeId).toStrictEqual('dae')
expect(Object.keys(tested)).toHaveLength(1)
expect(tested.dae).toMatchInlineSnapshot(`
{
"etapeStatutIds": [
"exe",
],
"mainStep": true,
}
`)
})

test('modifie une étape existante à la même date devrait permettre de recréer la même étape', () => {
for (const etape of etapes ?? []) {
const etapesTypesPossibles = etapesTypesPossibleACetteDateOuALaPlaceDeLEtape(machine, etapes, etape.id, etape.date)
if (etapesTypesPossibles.length === 0) {
if (Object.keys(etapesTypesPossibles).length === 0) {
console.error(`pas d'étapes possibles à l'étape ${JSON.stringify(etape)}. Devrait contenir AU MOINS la même étape`)
}
expect(etapesTypesPossibles.length).toBeGreaterThan(0)
expect(etapesTypesPossibles.map(({ etapeTypeId }) => etapeTypeId)).toContain(etape.typeId)
expect(Object.keys(etapesTypesPossibles).length).toBeGreaterThan(0)
expect(etapesTypesPossibles[etape.typeId]).toHaveProperty('etapeStatutIds')
}
})

test('ajoute une nouvelle étape à la fin', () => {
const tested = etapesTypesPossibleACetteDateOuALaPlaceDeLEtape(machine, etapes, null, toCaminoDate('2022-05-06'))
.map(({ etapeTypeId }) => etapeTypeId)
.filter(onlyUnique)
expect(tested).toHaveLength(1)
expect(tested[0]).toBe('mnv')
expect(Object.keys(tested)).toHaveLength(1)
expect(tested.mnv).toMatchInlineSnapshot(`
{
"etapeStatutIds": [
"fai",
],
"mainStep": false,
}
`)
})

test('ajoute une nouvelle étape en plein milieu', () => {
const tested = etapesTypesPossibleACetteDateOuALaPlaceDeLEtape(machine, etapes, null, toCaminoDate('2019-12-04'))
.map(({ etapeTypeId }) => etapeTypeId)
.filter(onlyUnique)
expect(tested).toStrictEqual(['mod', 'ede', 'edm'])
expect(Object.keys(tested).toSorted()).toStrictEqual(['ede', 'edm', 'mod'])
})

test('peut faire une dae, une rde et pfd AVANT la mfr', () => {
Expand Down Expand Up @@ -596,9 +605,7 @@ describe('etapesTypesPossibleACetteDateOuALaPlaceDeLEtape', function () {
]

const tested = etapesTypesPossibleACetteDateOuALaPlaceDeLEtape(machine, etapes, null, toCaminoDate('2019-12-04'))
.map(({ etapeTypeId }) => etapeTypeId)
.filter(onlyUnique)
expect(tested).toStrictEqual(['pfd', 'dae', 'rde'])
expect(Object.keys(tested).toSorted()).toStrictEqual(['dae', 'pfd', 'rde'])
})

test('peut faire que une pfd AVANT la mfr non mecanisee', () => {
Expand Down Expand Up @@ -628,9 +635,7 @@ describe('etapesTypesPossibleACetteDateOuALaPlaceDeLEtape', function () {
]

const tested = etapesTypesPossibleACetteDateOuALaPlaceDeLEtape(machine, etapes, null, toCaminoDate('2019-12-04'))
.map(({ etapeTypeId }) => etapeTypeId)
.filter(onlyUnique)
expect(tested).toStrictEqual(['pfd'])
expect(Object.keys(tested)).toStrictEqual(['pfd'])
})

test('peut faire refuser une rde après une demande mécanisée', () => {
Expand Down Expand Up @@ -783,9 +788,7 @@ describe('etapesTypesPossibleACetteDateOuALaPlaceDeLEtape', function () {
]

const tested = etapesTypesPossibleACetteDateOuALaPlaceDeLEtape(machine, etapes, null, toCaminoDate('2022-07-01'))
.map(({ etapeTypeId }) => etapeTypeId)
.filter(onlyUnique)
expect(tested).toStrictEqual(['mod', 'des', 'css', 'ede', 'asc', 'rcb', 'rde', 'mcb'])
expect(Object.keys(tested).toSorted()).toStrictEqual(['asc', 'css', 'des', 'ede', 'mcb', 'mod', 'rcb', 'rde'])
vi.resetAllMocks()
})
test('peut faire une completude (mcp) le même jour que le dépôt (mdp) de la demande', () => {
Expand Down Expand Up @@ -844,8 +847,6 @@ describe('etapesTypesPossibleACetteDateOuALaPlaceDeLEtape', function () {
]

const tested = etapesTypesPossibleACetteDateOuALaPlaceDeLEtape(machine, etapes, null, toCaminoDate('2022-07-01'))
.map(({ etapeTypeId }) => etapeTypeId)
.filter(onlyUnique)
expect(tested).toStrictEqual(['mod', 'des', 'css', 'rde', 'mcb', 'mcp'])
expect(Object.keys(tested).toSorted()).toStrictEqual(['css', 'des', 'mcb', 'mcp', 'mod', 'rde'])
})
})
Loading
Loading