Skip to content

Commit

Permalink
add controller validation
Browse files Browse the repository at this point in the history
  • Loading branch information
achorein committed Nov 29, 2024
1 parent cadcc8a commit fdb3092
Show file tree
Hide file tree
Showing 42 changed files with 802 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";

import { HiOutlineLightningBolt } from "react-icons/hi";

import { getDepartmentNumber, GRADES, Phase1Routes, region2department, RegionsMetropole, translate } from "snu-lib";
import { formatDepartement, GRADES, Phase1Routes, region2department, RegionsMetropole, translate } from "snu-lib";
import { Button, CollapsableSelectSwitcher, Modal, SectionSwitcher } from "@snu/ds/admin";
import { useSetState } from "react-use";
import { useMutation, useQueryClient } from "@tanstack/react-query";
Expand All @@ -18,16 +18,16 @@ interface AffectationSimulationMetropoleProps {
export default function AffectationSimulationMetropoleModal({ sessionId, onClose }: AffectationSimulationMetropoleProps) {
const queryClient = useQueryClient();
const [state, setState] = useSetState<{
departements: Record<string, string[]>;
niveauScolaires: string[];
departements: Record<string, string[]>;
etranger: boolean;
affecterPDR: boolean;
}>({
niveauScolaires: Object.values(GRADES),
departements: RegionsMetropole.reduce((acc, region) => {
acc[region] = region2department[region];
return acc;
}, {}),
niveauScolaires: Object.values(GRADES),
etranger: false,
affecterPDR: false,
});
Expand All @@ -38,6 +38,8 @@ export default function AffectationSimulationMetropoleModal({ sessionId, onClose
departements: Object.keys(state.departements).reduce((acc, region) => [...acc, ...state.departements[region]], []),
niveauScolaires: state.niveauScolaires as any,
changementDepartements: [],
etranger: state.etranger,
affecterPDR: state.affecterPDR,
});
},
onSuccess: (task) => {
Expand Down Expand Up @@ -88,14 +90,14 @@ export default function AffectationSimulationMetropoleModal({ sessionId, onClose
<CollapsableSelectSwitcher
key={region}
title={region}
options={region2department[region].map((department) => ({ label: `${department} (${getDepartmentNumber(department)})`, value: department }))}
options={region2department[region].map((department) => ({ label: formatDepartement(department), value: department }))}
values={state.departements[region]}
onChange={(values) => setState({ departements: { ...state.departements, [region]: values } })}
isOpen={false}
/>
))}
<SectionSwitcher title="Etranger" disabled value={state.etranger} onChange={(etranger) => setState({ etranger })} />
</div>
<SectionSwitcher title="Etranger" disabled value={state.etranger} onChange={(etranger) => setState({ etranger })} />
</div>
<div className="flex flex-col w-full gap-2.5">
<h2 className="text-lg leading-7 font-bold m-0">Points de rassemblement</h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useQuery } from "@tanstack/react-query";
import { HiOutlinePaperClip, HiPlay } from "react-icons/hi";
import { useLocation } from "react-router-dom";

import { formatDateFR, getZonedDate, Phase1Routes, TaskName, translateSimulationName, translateTaskStatus } from "snu-lib";
import { formatDateFR, getZonedDate, Phase1Routes, TaskName, translate, translateSimulationName, translateTaskStatus } from "snu-lib";
import { Badge, DataTable, TBadgeStatus, Tooltip } from "@snu/ds/admin";

import { Phase1Service } from "@/services/phase1Service";
Expand Down Expand Up @@ -91,7 +91,7 @@ export default function SimulationsSubTab({ sessionId }: SimulationsSubTabProps)
title: "Statut",
filtrable: true,
renderCell: (simulation) => (
<Tooltip id={simulation.id} title={simulation.libelle} disabled={!simulation.libelle}>
<Tooltip id={simulation.id} title={`${translate(simulation.erreur?.code)} ${simulation.erreur?.description || ""}`} disabled={!simulation.erreur?.code}>
<Badge title={translateTaskStatus(simulation.status)} status={MAPPING_STATUS_COLOR[simulation.status]} />
</Tooltip>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useMemo } from "react";

import { HiOutlineLightningBolt, HiPlay } from "react-icons/hi";

import { Phase1Routes, region2department, RegionsMetropole, SimulationAffectationHTSTaskDto, translate } from "snu-lib";
import { formatDepartement, getDepartmentNumber, Phase1Routes, region2department, RegionsMetropole, SimulationAffectationHTSTaskDto, translate } from "snu-lib";
import { Button, Modal } from "@snu/ds/admin";
import { useToggle } from "react-use";

Expand Down Expand Up @@ -63,9 +63,7 @@ export default function SimulationHtsResultStartButton({ simulation }: Simulatio
</div>
</div>
<h1 className="font-bold text-xl m-0">Affectation HTS (Hors DOM TOM)</h1>
<p className="text-lg">
La simulation se basera sur le schéma de répartition suivant : <b>Nom-du-Fichier.xxx</b>
</p>
<p className="text-lg">Vérifier les paramètres avant de lancer ce traitement.</p>
</div>
<div className="flex items-start flex-col w-full gap-8">
<div className="flex flex-col w-full gap-2.5">
Expand All @@ -80,7 +78,7 @@ export default function SimulationHtsResultStartButton({ simulation }: Simulatio
<div className="flex flex-col w-full gap-2.5">
<h2 className="text-lg leading-7 font-bold m-0">Situations scolaires</h2>
<div className="flex gap-2">
<div className="text-gray-400">Niveaux :</div>
<div className="text-gray-400">Niveaux&nbsp;:</div>
<div className="text-sm leading-5 font-normal">
{simulationHts.metadata?.parameters?.niveauScolaires?.map((niveau) => translate(niveau)).join(", ") || "Aucun"}
</div>
Expand All @@ -91,20 +89,20 @@ export default function SimulationHtsResultStartButton({ simulation }: Simulatio
<div className="flex flex-col w-full gap-4">
{RegionsMetropole.map((region) => (
<div key={region} className="flex gap-2">
<div className="text-gray-400 min-w-[200px]">{region} :</div>
<div className="text-sm leading-5 font-normal">{regions[region].join(", ") || "Aucun"}</div>
<div className="text-gray-400 min-w-[200px]">{region}&nbsp;:</div>
<div className="text-sm leading-5 font-normal">{regions[region].map(formatDepartement).join(", ") || "Aucun"}</div>
</div>
))}
</div>
<div className="flex gap-2">
<div className="text-gray-400">Etranger :</div>
<div className="text-gray-400">Etranger&nbsp;:</div>
<div className="text-sm leading-5 font-normal">{simulationHts.metadata?.parameters?.etranger ? "Oui" : "Non"}</div>
</div>
</div>
<div className="flex flex-col w-full gap-2.5">
<h2 className="text-lg leading-7 font-bold m-0">Points de rassemblement</h2>
<div className="flex gap-2">
<div className="text-gray-400">Affecter les PDR :</div>
<div className="text-gray-400">Affecter les PDR&nbsp;:</div>
<div className="text-sm leading-5 font-normal">{simulationHts.metadata?.parameters?.affecterPDR ? "Oui" : "Non"}</div>
</div>
</div>
Expand Down
7 changes: 5 additions & 2 deletions admin/src/services/affectationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import { AffectationRoutes } from "snu-lib";
import { buildRequest } from "@/utils/buildRequest";

const AffectationService = {
postAffectationMetropole: async (sessionId: string, { departements, niveauScolaires, changementDepartements }: AffectationRoutes["PostSimulationsRoute"]["payload"]) => {
postAffectationMetropole: async (
sessionId: string,
{ niveauScolaires, departements, etranger, affecterPDR, changementDepartements }: AffectationRoutes["PostSimulationsRoute"]["payload"],
) => {
return await buildRequest<AffectationRoutes["PostSimulationsRoute"]>({
path: "/affectation/{sessionId}/simulations",
method: "POST",
params: { sessionId },
payload: { departements, niveauScolaires, changementDepartements },
payload: { niveauScolaires, departements, etranger, affecterPDR, changementDepartements },
target: "API_V2",
})();
},
Expand Down
1 change: 1 addition & 0 deletions apiv2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"clean": "rm -fr node_modules dist .turbo"
},
"dependencies": {
"@faker-js/faker": "^8.4.1",
"@fast-csv/parse": "^5.0.2",
"@getbrevo/brevo": "^2.2.0",
"@nestjs/bullmq": "^10.2.1",
Expand Down
1 change: 1 addition & 0 deletions apiv2/src/admin/core/sejours/jeune/Jeune.model.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// TODO: Mettre à niveau pour de l'ecriture
export type JeuneModel = {
id: string;
statusPhase1: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Inject, Logger } from "@nestjs/common";

import { RegionsHorsMetropole, YOUNG_STATUS, YOUNG_STATUS_PHASE1, GRADES } from "snu-lib";
import { RegionsHorsMetropole, YOUNG_STATUS, YOUNG_STATUS_PHASE1, GRADES, department2region } from "snu-lib";

import { UseCase } from "@shared/core/UseCase";
import { FunctionalException, FunctionalExceptionCode } from "@shared/core/FunctionalException";
Expand Down Expand Up @@ -63,7 +63,7 @@ export class SimulationAffectationHTS implements UseCase<SimulationAffectationHT
niveauScolaires: Array<keyof typeof GRADES>;
changementDepartements: { origine: string; destination: string }[];
}): Promise<SimulationAffectationHTSResult> {
if (departements.some((departement) => RegionsHorsMetropole.includes(departement))) {
if (departements.some((departement) => RegionsHorsMetropole.includes(department2region[departement]))) {
throw new FunctionalException(FunctionalExceptionCode.AFFECTATION_DEPARTEMENT_HORS_METROPOLE);
}

Expand All @@ -75,19 +75,19 @@ export class SimulationAffectationHTS implements UseCase<SimulationAffectationHT
// Chargement des données associés à la session
const ligneDeBusList = await this.ligneDeBusGateway.findBySessionId(sessionId);
if (ligneDeBusList.length === 0) {
throw new FunctionalException(FunctionalExceptionCode.NOT_FOUND);
throw new FunctionalException(FunctionalExceptionCode.AFFECTATION_NOT_ENOUGH_DATA, "lignes de bus");
}
const sejoursList = await this.sejoursGateway.findBySessionId(sessionId);
if (sejoursList.length === 0) {
throw new FunctionalException(FunctionalExceptionCode.NOT_FOUND);
throw new FunctionalException(FunctionalExceptionCode.AFFECTATION_NOT_ENOUGH_DATA, "sejours");
}
const pdrList = await this.pointDeRassemblementGateway.findBySessionId(sessionId);
if (pdrList.length === 0) {
throw new FunctionalException(FunctionalExceptionCode.NOT_FOUND);
throw new FunctionalException(FunctionalExceptionCode.AFFECTATION_NOT_ENOUGH_DATA, "PDRs");
}
const centreList = await this.centresGateway.findBySessionId(sessionId);
if (centreList.length === 0) {
throw new FunctionalException(FunctionalExceptionCode.NOT_FOUND);
throw new FunctionalException(FunctionalExceptionCode.AFFECTATION_NOT_ENOUGH_DATA, "centres");
}
const allJeunes = await this.jeuneGateway.findBySessionIdStatusNiveauScolairesAndDepartements(
sessionId,
Expand All @@ -96,7 +96,7 @@ export class SimulationAffectationHTS implements UseCase<SimulationAffectationHT
departements,
);
if (allJeunes.length === 0) {
throw new FunctionalException(FunctionalExceptionCode.NOT_FOUND);
throw new FunctionalException(FunctionalExceptionCode.AFFECTATION_NOT_ENOUGH_DATA, "jeunes");
}

// on sépare les jeunes intra dep des autres
Expand Down
1 change: 1 addition & 0 deletions apiv2/src/admin/core/sejours/phase1/centre/Centre.model.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// TODO: Mettre à niveau pour de l'ecriture
export type CentreModel = {
id: string;
nom?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// TODO: Mettre à niveau pour de l'ecriture
export type LigneDeBusModel = {
id: string;
numeroLigne: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// TODO: Mettre à niveau pour de l'ecriture
export type PointDeRassemblementModel = {
id: string;
code: string;
Expand Down
1 change: 1 addition & 0 deletions apiv2/src/admin/core/sejours/phase1/sejour/Sejour.model.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// TODO: Mettre à niveau pour de l'ecriture
export type SejourModel = {
id: string;
nom?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SessionModel } from "./Session.model";
import { CreateSessionModel, SessionModel } from "./Session.model";

export interface SessionGateway {
findById(id: string): Promise<SessionModel>;
create(session: CreateSessionModel): Promise<SessionModel>;
}
export const SessionGateway = Symbol("SessionGateway");
130 changes: 130 additions & 0 deletions apiv2/src/admin/core/sejours/phase1/session/Session.model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,134 @@
// TODO: Mettre à niveau pour de l'ecriture
export type SessionModel = {
id: string;
nom: string;
snuId: string;
statut: string;
// legacy
cohortGroupId?: string;
dsnjExportDates?: {
cohesionCenters?: Date;
youngsBeforeSession?: Date;
youngsAfterSession?: Date;
};
injepExportDates?: {
youngsBeforeSession?: Date;
youngsAfterSession?: Date;
};
isAssignmentAnnouncementsOpenForYoung: boolean;
manualAffectionOpenForAdmin?: boolean;
manualAffectionOpenForReferentRegion?: boolean;
manualAffectionOpenForReferentDepartment?: boolean;
dateStart: Date;
dateEnd: Date;
eligibility: {
zones: string[];
schoolLevels: string[];
bornAfter: Date;
bornBefore: Date;
};
inscriptionStartDate: Date;
inscriptionEndDate: Date;
instructionEndDate: Date;
inscriptionModificationEndDate?: Date;
reInscriptionStartDate?: Date;
reInscriptionEndDate?: Date;
buffer: number;
event: string;
pdrChoiceLimitDate?: Date;
cleUpdateCohortForReferentRegion: boolean;
cleUpdateCohortForReferentRegionDate: { from?: Date; to?: Date };
cleUpdateCohortForReferentDepartment: boolean;
cleUpdateCohortForReferentDepartmentDate: { from?: Date; to?: Date };
cleDisplayCohortsForAdminCLE: boolean;
cleDisplayCohortsForAdminCLEDate: { from?: Date; to?: Date };
cleDisplayCohortsForReferentClasse: boolean;
cleDisplayCohortsForReferentClasseDate: { from?: Date; to?: Date };
cleUpdateCentersForReferentRegion: boolean;
cleUpdateCentersForReferentRegionDate: { from?: Date; to?: Date };
cleUpdateCentersForReferentDepartment: boolean;
cleUpdateCentersForReferentDepartmentDate: { from?: Date; to?: Date };
cleDisplayCentersForAdminCLE: boolean;
cleDisplayCentersForAdminCLEDate: { from?: Date; to?: Date };
cleDisplayCentersForReferentClasse: boolean;
cleDisplayCentersForReferentClasseDate: { from?: Date; to?: Date };
cleDisplayPDRForAdminCLE: boolean;
cleDisplayPDRForAdminCLEDate: { from?: Date; to?: Date };
cleDisplayPDRForReferentClasse: boolean;
cleDisplayPDRForReferentClasseDate: { from?: Date; to?: Date };
validationDate?: Date;
validationDateForTerminaleGrade?: Date;
youngCheckinForAdmin?: boolean;
youngCheckinForHeadOfCenter?: boolean;
youngCheckinForRegionReferent?: boolean;
youngCheckinForDepartmentReferent?: boolean;
busListAvailability?: boolean;
sessionEditionOpenForReferentRegion: boolean;
sessionEditionOpenForReferentDepartment: boolean;
sessionEditionOpenForTransporter: boolean;
pdrEditionOpenForReferentRegion: boolean;
pdrEditionOpenForReferentDepartment: boolean;
pdrEditionOpenForTransporter: boolean;
informationsConvoyage?: {
editionOpenForReferentRegion: boolean;
editionOpenForReferentDepartment: boolean;
editionOpenForHeadOfCenter: boolean;
};
repartitionSchemaCreateAndEditGroupAvailability?: boolean;
repartitionSchemaDownloadAvailability?: boolean;
isTransportPlanCorrectionRequestOpen?: boolean;
schemaAccessForReferentRegion: boolean;
schemaAccessForReferentDepartment: boolean;
busEditionOpenForTransporter: boolean;
daysToValidate: number;
daysToValidateForTerminalGrade?: number;
type: string;
createdAt: Date;
updatedAt: Date;
inscriptionOpenForReferentClasse: boolean;
inscriptionOpenForReferentRegion: boolean;
inscriptionOpenForReferentDepartment: boolean;
inscriptionOpenForAdministrateurCle: boolean;
};

export type CreateSessionModel = Omit<
SessionModel,
| "id"
| "createdAt"
| "updatedAt"
| "cleUpdateCohortForReferentRegion"
| "cleUpdateCohortForReferentDepartment"
| "cleDisplayCohortsForAdminCLE"
| "cleDisplayCohortsForReferentClasse"
| "cleUpdateCentersForReferentRegion"
| "cleUpdateCentersForReferentDepartment"
| "cleDisplayCentersForAdminCLE"
| "cleDisplayCentersForReferentClasse"
| "cleDisplayPDRForAdminCLE"
| "cleDisplayPDRForReferentClasse"
| "isAssignmentAnnouncementsOpenForYoung"
| "cleUpdateCohortForReferentRegionDate"
| "cleUpdateCohortForReferentDepartmentDate"
| "cleDisplayCohortsForAdminCLEDate"
| "cleDisplayCohortsForReferentClasseDate"
| "cleUpdateCentersForReferentRegionDate"
| "cleUpdateCentersForReferentDepartmentDate"
| "cleDisplayCentersForAdminCLEDate"
| "cleDisplayCentersForReferentClasseDate"
| "cleDisplayPDRForAdminCLEDate"
| "cleDisplayPDRForReferentClasseDate"
| "pdrEditionOpenForReferentRegion"
| "pdrEditionOpenForReferentDepartment"
| "pdrEditionOpenForTransporter"
| "schemaAccessForReferentRegion"
| "schemaAccessForReferentDepartment"
| "busListAvailability"
| "busEditionOpenForTransporter"
| "daysToValidate"
| "youngCheckinForRegionReferent"
| "inscriptionOpenForReferentRegion"
| "inscriptionOpenForReferentClasse"
| "inscriptionOpenForReferentRegion"
| "inscriptionOpenForReferentDepartment"
| "inscriptionOpenForAdministrateurCle"
>;
Loading

0 comments on commit fdb3092

Please sign in to comment.