From f82e91c6f10ea251b1fca414f71b963178ca36f0 Mon Sep 17 00:00:00 2001 From: C2Chandelier Date: Tue, 15 Oct 2024 17:00:21 +0200 Subject: [PATCH 1/6] up --- admin/src/scenes/centersV2/list.jsx | 9 +++++---- admin/src/scenes/pointDeRassemblement/List.tsx | 3 ++- .../controllers/elasticsearch/cohesioncenter.js | 14 +++++++------- .../elasticsearch/pointderassemblement.js | 2 +- api/src/controllers/elasticsearch/sessionphase1.js | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/admin/src/scenes/centersV2/list.jsx b/admin/src/scenes/centersV2/list.jsx index 1916c18847..862ae9f848 100644 --- a/admin/src/scenes/centersV2/list.jsx +++ b/admin/src/scenes/centersV2/list.jsx @@ -16,6 +16,7 @@ import ModalRattacherCentre from "./components/ModalRattacherCentre"; import { ExportComponent, Filters, ResultTable, Save, SelectedFilters } from "../../components/filters-system-v2"; import { getCohortGroups } from "@/services/cohort.service"; import { getDefaultCohort } from "@/utils/session"; +import { title } from "process"; export default function List() { const user = useSelector((state) => state.Auth.user); @@ -80,6 +81,7 @@ const ListSession = ({ firstSession }) => { const [size, setSize] = useState(10); const filterArray = [ { title: "Cohorte", name: "cohort", missingLabel: "Non renseignée", sort: (e) => orderCohort(e) }, + { title: "Matricule", name: "codeCentre", missingLabel: "Non renseigné" }, { title: "Région", name: "region", missingLabel: "Non renseignée", defaultValue: user.role === ROLES.REFERENT_REGION ? [user.region] : [] }, { title: "Département", @@ -100,7 +102,6 @@ const ListSession = ({ firstSession }) => { translate, }, ]; - if (user.role === ROLES.ADMIN) filterArray.push({ title: "Code", name: "code", missingLabel: "Non renseignée" }); if (!firstSession) return
; return ( @@ -141,7 +142,7 @@ const ListSession = ({ firstSession }) => { const hasSanitaryContactEmail = Boolean(data?.sanitaryContactEmail).toString(); return { "Id centre": center?._id?.toString(), - "Code du centre": center?.code2022, + Matricule: center?.matricule, "Nom du centre": center?.name, "Désignation du centre": center?.centerDesignation, "Id de la session": data?._id?.toString(), @@ -223,6 +224,7 @@ const ListCenter = ({ firstSession }) => { }); const [size, setSize] = useState(10); const filterArray = [ + { title: "Matricule", name: "matricule", missingLabel: "Non renseigné" }, { title: "Cohorte", name: "cohorts", missingLabel: "Non renseignée", sort: (e) => orderCohort(e) }, { title: "Région", @@ -250,7 +252,6 @@ const ListCenter = ({ firstSession }) => { translate: (e) => translateDomainCenter(e), }, ]; - if (user.role === ROLES.ADMIN) filterArray.push({ title: "Code", name: "code2022", missingLabel: "Non renseignée" }); const history = useHistory(); @@ -281,7 +282,7 @@ const ListCenter = ({ firstSession }) => { return all?.map((data) => { return { Id: data._id.toString(), - "Code du centre": data?.code2022, + Matricule: data?.matricule, Nom: data?.name, "Désignation du centre": data?.centerDesignation, "Cohorte(s)": data?.cohorts diff --git a/admin/src/scenes/pointDeRassemblement/List.tsx b/admin/src/scenes/pointDeRassemblement/List.tsx index 537783cf02..58a1685e0a 100644 --- a/admin/src/scenes/pointDeRassemblement/List.tsx +++ b/admin/src/scenes/pointDeRassemblement/List.tsx @@ -4,7 +4,6 @@ import { useSelector } from "react-redux"; import { useHistory, useParams, useLocation } from "react-router-dom"; import { PointDeRassemblementType, ROLES, canCreateMeetingPoint, getDepartmentNumber } from "snu-lib"; import BusSvg from "../../assets/icons/Bus"; -import Calendar from "../../assets/icons/Calendar"; import ExternalLink from "../../assets/icons/ExternalLink"; import Menu from "../../assets/icons/Menu"; import Breadcrumbs from "../../components/Breadcrumbs"; @@ -104,6 +103,7 @@ const ListPoints = ({ user }) => { const [paramData, setParamData] = React.useState({ page: 0 }); const [size, setSize] = useState(10); const filterArray = [ + { title: "Matricule", name: "matricule", missingLabel: "Non renseigné" }, { title: "Cohorte", name: "cohorts", missingLabel: "Non renseignée", sort: (e) => orderCohort(e) }, { title: "Région", name: "region", missingLabel: "Non renseignée", defaultValue: user.role === ROLES.REFERENT_REGION ? [user.region] : [] }, { @@ -145,6 +145,7 @@ const ListPoints = ({ user }) => { // @ts-ignore Identifiant: item._id.toString(), Code: item.code, + Matricule: item.matricule, Cohortes: item?.cohorts.map((e) => e).join(", "), Nom: item.name, Adresse: item.address, diff --git a/api/src/controllers/elasticsearch/cohesioncenter.js b/api/src/controllers/elasticsearch/cohesioncenter.js index efb5b7ba29..5dc39a20fc 100644 --- a/api/src/controllers/elasticsearch/cohesioncenter.js +++ b/api/src/controllers/elasticsearch/cohesioncenter.js @@ -14,8 +14,8 @@ router.post("/:action(search|export)", passport.authenticate(["referent"], { ses // Configuration const { user, body } = req; - const searchFields = ["name", "city", "zip", "code2022", "typology", "domain"]; - const filterFields = ["department.keyword", "region.keyword", "cohorts.keyword", "code2022.keyword", "typology.keyword", "domain.keyword"]; + const searchFields = ["name", "city", "zip", "matricule", "typology", "domain"]; + const filterFields = ["department.keyword", "region.keyword", "cohorts.keyword", "matricule.keyword", "typology.keyword", "domain.keyword"]; const sortFields = []; // Authorization if (!canSearchInElasticSearch(req.user, "cohesioncenter")) return res.status(403).send({ ok: false, code: ERRORS.OPERATION_UNAUTHORIZED }); @@ -24,7 +24,7 @@ router.post("/:action(search|export)", passport.authenticate(["referent"], { ses if (error) return res.status(400).send({ ok: false, code: ERRORS.INVALID_PARAMS }); // Context filters - let contextFilters = []; + let contextFilters = [{ bool: { must_not: { exists: { field: "deletedAt" } } } }, { exists: { field: "matricule" } }]; if (req.user.role === ROLES.REFERENT_REGION) contextFilters.push({ term: { "region.keyword": req.user.region } }); if (req.user.role === ROLES.REFERENT_DEPARTMENT) contextFilters.push({ terms: { "department.keyword": req.user.department } }); @@ -62,7 +62,7 @@ router.post("/:action(search|export)", passport.authenticate(["referent"], { ses router.post("/not-in-cohort/:cohort", passport.authenticate(["referent"], { session: false, failWithError: true }), async (req, res) => { try { // Configuration - const searchFields = ["name", "city", "zip", "code2022", "typology", "domain", "centerDesignation"]; + const searchFields = ["name", "city", "zip", "matricule", "typology", "domain", "centerDesignation"]; // Authorization if (!canSearchInElasticSearch(req.user, "cohesioncenter")) return res.status(403).send({ ok: false, code: ERRORS.OPERATION_UNAUTHORIZED }); @@ -92,9 +92,9 @@ router.post("/not-in-cohort/:cohort", passport.authenticate(["referent"], { sess router.post("/presence/:action(search|export)", passport.authenticate(["referent"], { session: false, failWithError: true }), async (req, res) => { try { // Configuration - const searchFields = ["name", "city", "zip", "code2022"]; - const filterFields = ["department.keyword", "region.keyword", "cohorts.keyword", "code2022.keyword", "academy.keyword", "status.keyword", "statusPhase1.keyword"]; - const filterFieldsCenter = ["department.keyword", "region.keyword", "cohorts.keyword", "code2022.keyword", "academy.keyword"]; + const searchFields = ["name", "city", "zip", "matricule"]; + const filterFields = ["department.keyword", "region.keyword", "cohorts.keyword", "matricule.keyword", "academy.keyword", "status.keyword", "statusPhase1.keyword"]; + const filterFieldsCenter = ["department.keyword", "region.keyword", "cohorts.keyword", "matricule.keyword", "academy.keyword"]; const sortFields = []; // Authorization diff --git a/api/src/controllers/elasticsearch/pointderassemblement.js b/api/src/controllers/elasticsearch/pointderassemblement.js index 106bf209f8..9ce69f0a3e 100644 --- a/api/src/controllers/elasticsearch/pointderassemblement.js +++ b/api/src/controllers/elasticsearch/pointderassemblement.js @@ -12,7 +12,7 @@ router.post("/:action(search|export)", passport.authenticate(["referent"], { ses // Configuration const { user, body } = req; const searchFields = ["name", "address", "particularitesAcces", "region", "department", "code", "city", "zip", "matricule"]; - const filterFields = ["cohorts.keyword", "region.keyword", "department.keyword"]; + const filterFields = ["cohorts.keyword", "region.keyword", "department.keyword", "matricule.keyword"]; const sortFields = []; // Body params validation diff --git a/api/src/controllers/elasticsearch/sessionphase1.js b/api/src/controllers/elasticsearch/sessionphase1.js index 8160455a63..7f17608d78 100644 --- a/api/src/controllers/elasticsearch/sessionphase1.js +++ b/api/src/controllers/elasticsearch/sessionphase1.js @@ -17,8 +17,8 @@ router.post("/:action(search|export)", passport.authenticate(["referent"], { ses "department.keyword", "region.keyword", "cohort.keyword", - "code.keyword", "placesLeft", + "codeCentre.keyword", "hasTimeSchedule.keyword", "typology.keyword", "domain.keyword", From cbd7ac697876024b50419dd3b64be2032fd3bff3 Mon Sep 17 00:00:00 2001 From: C2Chandelier Date: Fri, 18 Oct 2024 12:52:29 +0200 Subject: [PATCH 2/6] up --- admin/src/scenes/classe/utils/index.ts | 2 ++ admin/src/scenes/plan-transport/ligne-bus/List.jsx | 6 ++++-- admin/src/scenes/plan-transport/util.jsx | 7 ++++--- admin/src/scenes/volontaires/utils/index.js | 5 ++--- api/src/cohesionCenter/cohesionCenterController.js | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/admin/src/scenes/classe/utils/index.ts b/admin/src/scenes/classe/utils/index.ts index 72bf9eb729..f7f82a3a04 100644 --- a/admin/src/scenes/classe/utils/index.ts +++ b/admin/src/scenes/classe/utils/index.ts @@ -329,6 +329,7 @@ export function exportExcelSheet(classes: ClasseExport[], type: typeExport) { studentNotAutorized: c.studentNotAutorized, studentWithdrawn: c.studentWithdrawn, centerId: c.cohesionCenterId, + centerMatricule: c.cohesionCenter?.matricule, centerName: c.cohesionCenter ? `${c.cohesionCenter?.name}, ${c.cohesionCenter?.address}, ${c.cohesionCenter?.zip} ${c.cohesionCenter?.city}` : "", centerDepartment: c.cohesionCenter?.department, centerRegion: c.cohesionCenter?.region, @@ -373,6 +374,7 @@ export function exportExcelSheet(classes: ClasseExport[], type: typeExport) { "Nombre d'élèves non autorisés", "Nombre d'élèves désistés", "ID centre", + "Matricule du centre", "Désignation du centre", "Département du centre", "Région du centre", diff --git a/admin/src/scenes/plan-transport/ligne-bus/List.jsx b/admin/src/scenes/plan-transport/ligne-bus/List.jsx index 92db5dedd1..747faf170a 100644 --- a/admin/src/scenes/plan-transport/ligne-bus/List.jsx +++ b/admin/src/scenes/plan-transport/ligne-bus/List.jsx @@ -79,7 +79,7 @@ export default function List() { translate: (e) => getDepartmentNumber(e) + " - " + e, }, { title: "Ville", name: "pointDeRassemblements.city", parentGroup: "Points de rassemblement", missingLabel: "Non renseigné" }, - { title: "Code", name: "pointDeRassemblements.code", parentGroup: "Points de rassemblement", missingLabel: "Non renseigné" }, + { title: "Matricule", name: "pointDeRassemblements.matricule", parentGroup: "Points de rassemblement", missingLabel: "Non renseigné" }, { title: "Nom", name: "centerName", parentGroup: "Centre", missingLabel: "Non renseigné" }, { title: "Région", name: "centerRegion", parentGroup: "Centre", missingLabel: "Non renseigné" }, { @@ -90,7 +90,7 @@ export default function List() { missingLabel: "Non renseigné", translate: (e) => getDepartmentNumber(e) + " - " + e, }, - { title: "Code", name: "centerCode", parentGroup: "Centre", missingLabel: "Non renseigné" }, + { title: "Matricule", name: "centerCode", parentGroup: "Centre", missingLabel: "Non renseigné" }, { title: "Modification demandée", @@ -369,6 +369,7 @@ const returnSelect = (cohort, selectedFilters, user) => { pdrs[`N° DE DEPARTEMENT PDR ${num}`] = pdr?.department ? getDepartmentNumber(pdr.department) : ""; pdrs[`REGION DU PDR ${num}`] = pdr?.region || ""; pdrs[`ID PDR ${num}`] = pdr?.meetingPointId || ""; + pdrs[`MATRICULE DU PDR ${num}`] = pdr?.matricule || ""; pdrs[`TYPE DE TRANSPORT PDR ${num}`] = pdr?.transportType || ""; pdrs[`NOM + ADRESSE DU PDR ${num}`] = pdr?.name ? pdr.name + " / " + pdr.address : ""; pdrs[`HEURE ALLER ARRIVÉE AU PDR ${num}`] = pdr?.busArrivalHour || ""; @@ -385,6 +386,7 @@ const returnSelect = (cohort, selectedFilters, user) => { "N° DU DEPARTEMENT DU CENTRE": getDepartmentNumber(data.centerDepartment), "REGION DU CENTRE": data.centerRegion, "ID CENTRE": data.centerId, + "MATRICULE DU CENTRE": data.centerCode, "NOM + ADRESSE DU CENTRE": data.centerName + " / " + data.centerAddress, "HEURE D'ARRIVEE AU CENTRE": data.centerArrivalTime, "HEURE DE DÉPART DU CENTRE": data.centerDepartureTime, diff --git a/admin/src/scenes/plan-transport/util.jsx b/admin/src/scenes/plan-transport/util.jsx index f52ce29f2e..c04a13cd67 100644 --- a/admin/src/scenes/plan-transport/util.jsx +++ b/admin/src/scenes/plan-transport/util.jsx @@ -125,7 +125,7 @@ export async function exportLigneBus(cohort) { "Téléphone représentant légal 2": formatPhoneE164(young.parent2Phone, young.parent2PhoneZone || getPhoneZoneByDepartment(young.department)), "ID centre": center._id, - "Code centre (2022)": center.code2022, + "Matricule du centre)": center.matricule, "Nom du centre": center.name, "Adresse du centre": center.address, "Ville du centre": center.city, @@ -133,6 +133,7 @@ export async function exportLigneBus(cohort) { "Région du centre": center.region, "Id du point de rassemblement": young.meetingPointId, + "Matricule du point de rassemblement": meetingPoint.matricule, "Nom du point de rassemblement": meetingPoint.name, "Adresse point de rassemblement": meetingPoint.address, "Ville du point de rassemblement": meetingPoint.city, @@ -343,7 +344,7 @@ export async function exportConvoyeur(cohort) { const matchingCenter = centers.find((c) => c._id === currentLigneBus.centerId); if (matchingCenter) { - currentLigneBus.centerCode = matchingCenter.code2022; + currentLigneBus.centerCode = matchingCenter.matricule; currentLigneBus.centerDepartment = matchingCenter.department; } } @@ -410,7 +411,7 @@ export async function exportConvoyeur(cohort) { const dataItem = { "Bus n˚": item.busId, - "Code centre (2022)": item.centerCode, + "Matricule Centre": item.centerCode, Département: item.centerDepartment, ...team, }; diff --git a/admin/src/scenes/volontaires/utils/index.js b/admin/src/scenes/volontaires/utils/index.js index 3383f5deb8..28c0df032f 100644 --- a/admin/src/scenes/volontaires/utils/index.js +++ b/admin/src/scenes/volontaires/utils/index.js @@ -206,7 +206,7 @@ export const getFilterArray = (user, bus, session, classes, etablissements) => { if (item === "N/A" || !session.length) return item; const res = session.find((option) => option._id.toString() === item); if (!res) return "N/A - Supprimé"; - return (res?.codeCentre || "N/A") + " - " + res?.cohesionCenterId; + return res?.codeCentre; }, }, { @@ -476,8 +476,7 @@ export async function transformVolontaires(data, values) { }, phase1Affectation: { "ID centre": center._id || "", - // "Code centre (2021)": center.code || "", - "Code centre (2022)": center.code2022 || "", + "Matricule centre": center.matricule || "", "Nom du centre": center.name || "", "Ville du centre": center.city || "", "Département du centre": center.department || "", diff --git a/api/src/cohesionCenter/cohesionCenterController.js b/api/src/cohesionCenter/cohesionCenterController.js index f54982608b..cc08b8a6f5 100644 --- a/api/src/cohesionCenter/cohesionCenterController.js +++ b/api/src/cohesionCenter/cohesionCenterController.js @@ -130,7 +130,7 @@ router.put("/:id/session-phase1", passport.authenticate("referent", { session: f placesLeft: value.placesTotal, department: center.department, region: center.region, - codeCentre: center.code2022, + codeCentre: center.matricule, nameCentre: center.name, cityCentre: center.city, zipCentre: center.zip, From 06dc92fa52b4be937d198d332678f3324bd4d3e2 Mon Sep 17 00:00:00 2001 From: Johannbr Date: Wed, 16 Oct 2024 10:33:57 +0200 Subject: [PATCH 3/6] feat(api): 3395 - utiliser matricule au lieu des id pour import de pdt --- api/src/controllers/planDeTransport/import.js | 40 +++++++++++++------ .../lib/src/constants/functionalErrors.ts | 4 ++ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/api/src/controllers/planDeTransport/import.js b/api/src/controllers/planDeTransport/import.js index 1c528ed1d7..5e60b5c869 100644 --- a/api/src/controllers/planDeTransport/import.js +++ b/api/src/controllers/planDeTransport/import.js @@ -4,7 +4,7 @@ const passport = require("passport"); const { capture } = require("../../sentry"); const { ERRORS } = require("../../utils"); const Joi = require("joi"); -const { canSendPlanDeTransport, MIME_TYPES, COHORT_TYPE } = require("snu-lib"); +const { canSendPlanDeTransport, MIME_TYPES, COHORT_TYPE, FUNCTIONAL_ERRORS } = require("snu-lib"); const fs = require("fs"); const { parse: parseDate } = require("date-fns"); const fileUpload = require("express-fileupload"); @@ -112,7 +112,7 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f } const lines = importData.lines; - const countPdr = Object.keys(lines[0]).filter((e) => e.startsWith("ID PDR")).length; + const countPdr = Object.keys(lines[0]).filter((e) => e.startsWith("MATRICULE PDR")).length; // Vérification des lignes existantes (ne sont modifié que les nouvelles) const newLines = []; @@ -132,18 +132,32 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f for (const line of newLines) { const pdrIds = []; for (let pdrNumber = 1; pdrNumber <= countPdr; pdrNumber++) { - if (line[`ID PDR ${pdrNumber}`] && !["correspondance aller", "correspondance retour", "correspondance"].includes(line[`ID PDR ${pdrNumber}`]?.toLowerCase())) { - pdrIds.push(line[`ID PDR ${pdrNumber}`]); + if ( + line[`MATRICULE PDR ${pdrNumber}`] && + !["correspondance aller", "correspondance retour", "correspondance"].includes(line[`MATRICULE PDR ${pdrNumber}`]?.toLowerCase()) + ) { + const pdr = await PointDeRassemblementModel.findOne({ matricule: line[`MATRICULE PDR ${pdrNumber}`] }); + if (!pdr) { + throw new Error(ERRORS.NOT_FOUND, { cause: `Pdr not found for matricule : ${line[`MATRICULE PDR ${pdrNumber}`]}` }); + } + pdrIds.push(pdr._id); } } - const session = await SessionPhase1Model.findOne({ cohort: importData.cohort, cohesionCenterId: line["ID CENTRE"] }); + const cohesionCenter = await CohesionCenterModel.find({ matricule: line["MATRICULE CENTRE"] }); + if (cohesionCenter.length > 1) { + throw new Error(FUNCTIONAL_ERRORS.MORE_THAN_ONE_CENTER_FOR_ONE_MATRICULE, { cause: `More than one cohesionCenter for matricule : ${line["MATRICULE CENTRE"]}` }); + } + if (cohesionCenter.length === 0) { + throw new Error(ERRORS.NOT_FOUND, { cause: `No cohesionCenter for matricule : ${line["MATRICULE CENTRE"]}` }); + } + const session = await SessionPhase1Model.findOne({ cohort: importData.cohort, cohesionCenterId: cohesionCenter[0]._id }); const busLineData = { cohort: importData.cohort, busId: line["NUMERO DE LIGNE"], departuredDate: parseDate(line["DATE DE TRANSPORT ALLER"], "dd/MM/yyyy", new Date()), returnDate: parseDate(line["DATE DE TRANSPORT RETOUR"], "dd/MM/yyyy", new Date()), - centerId: line["ID CENTRE"], + centerId: cohesionCenter[0]._id, centerArrivalTime: formatTime(line["HEURE D'ARRIVEE AU CENTRE"]), centerDepartureTime: formatTime(line["HEURE DE DÉPART DU CENTRE"]), followerCapacity: line["TOTAL ACCOMPAGNATEURS"], @@ -171,11 +185,11 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f } const lineToPointWithCorrespondance = Array.from({ length: countPdr }, (_, i) => i + 1).reduce((acc, pdrNumber) => { - if (pdrNumber > 1 && !line[`ID PDR ${pdrNumber}`]) return acc; - if (!["correspondance aller", "correspondance retour", "correspondance"].includes(line[`ID PDR ${pdrNumber}`].toLowerCase())) { + if (pdrNumber > 1 && !line[`MATRICULE PDR ${pdrNumber}`]) return acc; + if (!["correspondance aller", "correspondance retour", "correspondance"].includes(line[`MATRICULE PDR ${pdrNumber}`].toLowerCase())) { acc.push({ lineId: busLine._id.toString(), - meetingPointId: line[`ID PDR ${pdrNumber}`], + meetingPointId: line[`MATRICULE PDR ${pdrNumber}`], transportType: line[`TYPE DE TRANSPORT PDR ${pdrNumber}`].toLowerCase(), busArrivalHour: formatTime(line[`HEURE ALLER ARRIVÉE AU PDR ${pdrNumber}`]), departureHour: formatTime(line[`HEURE DEPART DU PDR ${pdrNumber}`]), @@ -184,7 +198,7 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f stepPoints: [], }); } else { - if (line[`ID PDR ${pdrNumber}`].toLowerCase() === "correspondance") { + if (line[`MATRICULE PDR ${pdrNumber}`].toLowerCase() === "correspondance") { // Special case: when correspondance is not aller or retour // We create 2 step points (aller and retour). acc[acc.length - 1].stepPoints.push({ @@ -203,10 +217,10 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f }); } else { acc[acc.length - 1].stepPoints.push({ - type: line[`ID PDR ${pdrNumber}`].toLowerCase() === "correspondance aller" ? "aller" : "retour", + type: line[`MATRICULE PDR ${pdrNumber}`].toLowerCase() === "correspondance aller" ? "aller" : "retour", address: line[`NOM + ADRESSE DU PDR ${pdrNumber}`], - departureHour: line[`ID PDR ${pdrNumber}`].toLowerCase() === "correspondance aller" ? formatTime(line[`HEURE DEPART DU PDR ${pdrNumber}`]) : "", - returnHour: line[`ID PDR ${pdrNumber}`].toLowerCase() === "correspondance aller" ? "" : formatTime(line[`HEURE DE RETOUR ARRIVÉE AU PDR ${pdrNumber}`]), + departureHour: line[`MATRICULE PDR ${pdrNumber}`].toLowerCase() === "correspondance aller" ? formatTime(line[`HEURE DEPART DU PDR ${pdrNumber}`]) : "", + returnHour: line[`MATRICULE PDR ${pdrNumber}`].toLowerCase() === "correspondance aller" ? "" : formatTime(line[`HEURE DE RETOUR ARRIVÉE AU PDR ${pdrNumber}`]), transportType: line[`TYPE DE TRANSPORT PDR ${pdrNumber}`].toLowerCase(), }); } diff --git a/packages/lib/src/constants/functionalErrors.ts b/packages/lib/src/constants/functionalErrors.ts index 2e899f4f6a..be9c1eedaf 100644 --- a/packages/lib/src/constants/functionalErrors.ts +++ b/packages/lib/src/constants/functionalErrors.ts @@ -7,4 +7,8 @@ export const FUNCTIONAL_ERRORS = { INSCRIPTION_GOAL_REACHED: "INSCRIPTION_GOAL_REACHED", INSCRIPTION_GOAL_REGION_REACHED: "INSCRIPTION_GOAL_REGION_REACHED", INSCRIPTION_GOAL_NOT_DEFINED: "INSCRIPTION_GOAL_NOT_DEFINED", + NO_CENTER_CODE_PROVIDED: "NO_CENTER_CODE_PROVIDED", + NO_PDR_CODE_PROVIDED: "NO_PDR_CODE_PROVIDED", + NO_SESSION_CODE_PROVIDED: "NO_SESSION_CODE_PROVIDED", + MORE_THAN_ONE_CENTER_FOR_ONE_MATRICULE: "MORE_THAN_ONE_CENTER_FOR_ONE_MATRICULE", }; From cf555d05d37e13d0900cce645f8971ac56695a22 Mon Sep 17 00:00:00 2001 From: Johannbr Date: Wed, 16 Oct 2024 17:26:27 +0200 Subject: [PATCH 4/6] update --- .../PlanDeTransport/importPlanTransport.ts | 16 ++-- .../PlanDeTransport/planDeTransport.ts | 22 ++--- api/src/controllers/planDeTransport/import.js | 10 +- .../import/pdtImportService.ts | 96 +++++++++---------- .../lib/src/constants/plan-de-transport.ts | 3 + 5 files changed, 75 insertions(+), 72 deletions(-) diff --git a/api/src/__tests__/fixtures/PlanDeTransport/importPlanTransport.ts b/api/src/__tests__/fixtures/PlanDeTransport/importPlanTransport.ts index 3c0bf62e64..1ebb0a5a6b 100644 --- a/api/src/__tests__/fixtures/PlanDeTransport/importPlanTransport.ts +++ b/api/src/__tests__/fixtures/PlanDeTransport/importPlanTransport.ts @@ -7,28 +7,28 @@ function getNewImportPlanTransportFixture() { "DATE DE TRANSPORT ALLER": "12/06/2022", "DATE DE TRANSPORT RETOUR": "03/07/2022", "N° DE DEPARTEMENT PDR 1": "18", - "ID PDR 1": "63da1f2547841408c58e533d", + "MATRICULE PDR 1": "MATRICULE_PDR_1", "TYPE DE TRANSPORT PDR 1": "Bus", "NOM + ADRESSE DU PDR 1": "PARKING A L'ENTREE DU PARC DES EXPOSITIONS - RUE DES JARS (RUE BARBUSSE) - 17000 LA ROCHELLE", "HEURE ALLER ARRIVÉE AU PDR 1": "12:00", "HEURE DEPART DU PDR 1": "12:30", "HEURE DE RETOUR ARRIVÉE AU PDR 1": "17:30", "N° DE DEPARTEMENT PDR 2": null, - "ID PDR 2": null, + "MATRICULE PDR 2": null, "TYPE DE TRANSPORT PDR 2": null, "NOM + ADRESSE DU PDR 2": null, "HEURE ALLER ARRIVÉE AU PDR 2": null, "HEURE DEPART DU PDR 2": null, "HEURE DE RETOUR ARRIVÉE AU PDR 2": null, "N° DE DEPARTEMENT PDR 3": null, - "ID PDR 3": null, + "MATRICULE PDR 3": null, "TYPE DE TRANSPORT PDR 3": null, "NOM + ADRESSE DU PDR 3": null, "HEURE ALLER ARRIVÉE AU PDR 3": null, "HEURE DEPART DU PDR 3": null, "HEURE DE RETOUR ARRIVÉE AU PDR 3": null, "N° DU DEPARTEMENT DU CENTRE": "12", - "ID CENTRE": "63c919d5700cce08ce846633", + "MATRICULE CENTRE": "MATRICULE_CENTRE_1", "NOM + ADRESSE DU CENTRE": "LYCEE PROFESSIONNEL DU BATIMENT ET METIERS DE LA SECURITE - CHARDEUIL - 24420 COULAURES", "HEURE D'ARRIVEE AU CENTRE": "17:00", "HEURE DE DÉPART DU CENTRE": "11:30", @@ -46,28 +46,28 @@ function getNewImportPlanTransportFixture() { "DATE DE TRANSPORT ALLER": "12/06/2023", "DATE DE TRANSPORT RETOUR": "03/07/2023", "N° DE DEPARTEMENT PDR 1": "19", - "ID PDR 1": "63ce916d95bf6308d789bea9", + "MATRICULE PDR 1": "MATRICULE_PDR_2", "TYPE DE TRANSPORT PDR 1": "Bus", "NOM + ADRESSE DU PDR 1": "PARKING A L'ENTREE DU PARC DES EXPOSITIONS - RUE DES JARS (RUE BARBUSSE) - 17000 LA ROCHELLE", "HEURE ALLER ARRIVÉE AU PDR 1": "12:00", "HEURE DEPART DU PDR 1": "12:30", "HEURE DE RETOUR ARRIVÉE AU PDR 1": "17:30", "N° DE DEPARTEMENT PDR 2": "18", - "ID PDR 2": "63ce91e495bf6308d789c96b", + "MATRICULE PDR 2": "MATRICULE_PDR_3", "TYPE DE TRANSPORT PDR 2": "Bus", "NOM + ADRESSE DU PDR 2": "PARKING A L'ENTREE DU PARC DES EXPOSITIONS - RUE DES JARS (RUE BARBUSSE) - 17000 LA ROCHELLE", "HEURE ALLER ARRIVÉE AU PDR 2": "12:00", "HEURE DEPART DU PDR 2": "12:30", "HEURE DE RETOUR ARRIVÉE AU PDR 2": "17:30", "N° DE DEPARTEMENT PDR 3": null, - "ID PDR 3": null, + "MATRICULE PDR 3": null, "TYPE DE TRANSPORT PDR 3": null, "NOM + ADRESSE DU PDR 3": null, "HEURE ALLER ARRIVÉE AU PDR 3": null, "HEURE DEPART DU PDR 3": null, "HEURE DE RETOUR ARRIVÉE AU PDR 3": null, "N° DU DEPARTEMENT DU CENTRE": "12", - "ID CENTRE": "63c919d5700cce08ce846633", + "MATRICULE CENTRE": "MATRICULE_CENTRE_2", "NOM + ADRESSE DU CENTRE": "LYCEE PROFESSIONNEL DU BATIMENT ET METIERS DE LA SECURITE - CHARDEUIL - 24420 COULAURES", "HEURE D'ARRIVEE AU CENTRE": "17:00", "HEURE DE DÉPART DU CENTRE": "11:30", diff --git a/api/src/__tests__/helpers/PlanDeTransport/planDeTransport.ts b/api/src/__tests__/helpers/PlanDeTransport/planDeTransport.ts index b1a46ae605..00c00f5394 100644 --- a/api/src/__tests__/helpers/PlanDeTransport/planDeTransport.ts +++ b/api/src/__tests__/helpers/PlanDeTransport/planDeTransport.ts @@ -9,25 +9,25 @@ import { createCohesionCenterWithSession } from "../cohesionCenter"; import { createPointDeRassemblementHelper } from "./pointDeRassemblement"; async function initPlanTransport(planTransport) { - const ids = planTransport.lines.reduce( + const matricules = planTransport.lines.reduce( (acc, line) => { - const { "ID CENTRE": centreId, "ID PDR 1": pdr1Id, "ID PDR 2": pdr2Id, "ID PDR 3": pdr3Id } = line; - if (centreId) acc.centreIds[centreId] = centreId; - if (pdr1Id) acc.pdrIds[pdr1Id] = { department: departmentLookUp[line["N° DE DEPARTEMENT PDR 1"]] }; - if (pdr2Id) acc.pdrIds[pdr2Id] = { department: departmentLookUp[line["N° DE DEPARTEMENT PDR 2"]] }; - if (pdr3Id) acc.pdrIds[pdr3Id] = { department: departmentLookUp[line["N° DE DEPARTEMENT PDR 3"]] }; + const { "MATRICULE CENTRE": centreMatricule, "MATRICULE PDR 1": pdr1Matricule, "MATRICULE PDR 2": pdr2Matricule, "MATRICULE PDR 3": pdr3Matricule } = line; + if (centreMatricule) acc.centreMatricules[centreMatricule] = centreMatricule; + if (pdr1Matricule) acc.pdrMatricules[pdr1Matricule] = { department: departmentLookUp[line["N° DE DEPARTEMENT PDR 1"]] }; + if (pdr2Matricule) acc.pdrMatricules[pdr2Matricule] = { department: departmentLookUp[line["N° DE DEPARTEMENT PDR 2"]] }; + if (pdr3Matricule) acc.pdrMatricules[pdr3Matricule] = { department: departmentLookUp[line["N° DE DEPARTEMENT PDR 3"]] }; return acc; }, - { centreIds: {}, pdrIds: {} }, + { centreMatricules: {}, pdrMatricules: {} }, ); - for (const centreId of Object.keys(ids.centreIds)) { + for (const centreMatricule of Object.keys(matricules.centreMatricules)) { await createCohesionCenterWithSession( - getNewCohesionCenterFixture({ _id: centreId, cohorts: [planTransport.cohort] }), + getNewCohesionCenterFixture({ cohorts: [planTransport.cohort], matricule: centreMatricule }), getNewSessionPhase1Fixture({ cohort: planTransport.cohort }), ); } - for (const pdrId of Object.keys(ids.pdrIds)) { - await createPointDeRassemblementHelper(getNewPointDeRassemblementFixture({ _id: pdrId, department: ids.pdrIds[pdrId].department })); + for (const pdrMatricule of Object.keys(matricules.pdrMatricules)) { + await createPointDeRassemblementHelper(getNewPointDeRassemblementFixture({ department: matricules.pdrMatricules[pdrMatricule].department, matricule: pdrMatricule })); } } diff --git a/api/src/controllers/planDeTransport/import.js b/api/src/controllers/planDeTransport/import.js index 5e60b5c869..28b872ae35 100644 --- a/api/src/controllers/planDeTransport/import.js +++ b/api/src/controllers/planDeTransport/import.js @@ -130,7 +130,7 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f // import des nouvelles lignes for (const line of newLines) { - const pdrIds = []; + const pdrMatriculeIdMap = new Map(); for (let pdrNumber = 1; pdrNumber <= countPdr; pdrNumber++) { if ( line[`MATRICULE PDR ${pdrNumber}`] && @@ -140,9 +140,10 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f if (!pdr) { throw new Error(ERRORS.NOT_FOUND, { cause: `Pdr not found for matricule : ${line[`MATRICULE PDR ${pdrNumber}`]}` }); } - pdrIds.push(pdr._id); + pdrMatriculeIdMap.set(line[`MATRICULE PDR ${pdrNumber}`], pdr._id); } } + const meetingPointsIds = Array.from(pdrMatriculeIdMap.values()); const cohesionCenter = await CohesionCenterModel.find({ matricule: line["MATRICULE CENTRE"] }); if (cohesionCenter.length > 1) { @@ -168,7 +169,7 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f lunchBreakReturn: line["PAUSE DÉJEUNER RETOUR" || ""].toLowerCase() === "oui", travelTime: formatTime(line["TEMPS DE ROUTE"]), sessionId: session?._id.toString(), - meetingPointsIds: pdrIds, + meetingPointsIds: meetingPointsIds, classeId: line["ID CLASSE"] ? line["ID CLASSE"] : undefined, mergedBusIds: line["LIGNES FUSIONNÉES"] ? line["LIGNES FUSIONNÉES"].split(",") : [], }; @@ -189,7 +190,7 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f if (!["correspondance aller", "correspondance retour", "correspondance"].includes(line[`MATRICULE PDR ${pdrNumber}`].toLowerCase())) { acc.push({ lineId: busLine._id.toString(), - meetingPointId: line[`MATRICULE PDR ${pdrNumber}`], + meetingPointId: pdrMatriculeIdMap.get(line[`MATRICULE PDR ${pdrNumber}`]), transportType: line[`TYPE DE TRANSPORT PDR ${pdrNumber}`].toLowerCase(), busArrivalHour: formatTime(line[`HEURE ALLER ARRIVÉE AU PDR ${pdrNumber}`]), departureHour: formatTime(line[`HEURE DEPART DU PDR ${pdrNumber}`]), @@ -295,7 +296,6 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f }); } catch (error) { capture(error); - res.status(500).send({ ok: false, code: ERRORS.SERVER_ERROR }); } finally { await endSession(transaction); diff --git a/api/src/planDeTransport/planDeTransport/import/pdtImportService.ts b/api/src/planDeTransport/planDeTransport/import/pdtImportService.ts index 8e5c36a838..822d84f453 100644 --- a/api/src/planDeTransport/planDeTransport/import/pdtImportService.ts +++ b/api/src/planDeTransport/planDeTransport/import/pdtImportService.ts @@ -37,8 +37,8 @@ export const validatePdtFile = async ( return { ok: false, code: ERRORS.INVALID_BODY }; } - // Count columns that start with "ID PDR" to know how many PDRs there are. - const countPdr = Object.keys(lines[0]).filter((e) => e.startsWith("ID PDR")).length; + // Count columns that start with "MATRICULE PDR" to know how many PDRs there are. + const countPdr = Object.keys(lines[0]).filter((e) => e.startsWith("MATRICULE PDR")).length; let maxPdrOnLine = 0; const errors: PdtErrors = { @@ -47,7 +47,7 @@ export const validatePdtFile = async ( "DATE DE TRANSPORT RETOUR": [], ...Array.from({ length: countPdr }, (_, i) => ({ [`N° DE DEPARTEMENT PDR ${i + 1}`]: [], - [`ID PDR ${i + 1}`]: [], + [`MATRICULE PDR ${i + 1}`]: [], [`TYPE DE TRANSPORT PDR ${i + 1}`]: [], [`NOM + ADRESSE DU PDR ${i + 1}`]: [], [`HEURE ALLER ARRIVÉE AU PDR ${i + 1}`]: [], @@ -55,7 +55,7 @@ export const validatePdtFile = async ( [`HEURE DE RETOUR ARRIVÉE AU PDR ${i + 1}`]: [], })).reduce((acc, cur) => ({ ...acc, ...cur }), {}), "N° DU DEPARTEMENT DU CENTRE": [], - "ID CENTRE": [], + "MATRICULE CENTRE": [], "NOM + ADRESSE DU CENTRE": [], "HEURE D'ARRIVEE AU CENTRE": [], "HEURE DE DÉPART DU CENTRE": [], @@ -130,7 +130,7 @@ export const validatePdtFile = async ( // Check each PDR for (let i = 1; i <= countPdr; i++) { // Skip empty PDR - if (i > 1 && !line[`ID PDR ${i}`]) continue; + if (i > 1 && !line[`MATRICULE PDR ${i}`]) continue; if (!line[`N° DE DEPARTEMENT PDR ${i}`]) { errors[`N° DE DEPARTEMENT PDR ${i}`].push({ line: index, error: PDT_IMPORT_ERRORS.MISSING_DATA }); @@ -138,14 +138,14 @@ export const validatePdtFile = async ( if (line[`N° DE DEPARTEMENT PDR ${i}`] && !isValidDepartment(line[`N° DE DEPARTEMENT PDR ${i}`])) { errors[`N° DE DEPARTEMENT PDR ${i}`].push({ line: index, error: PDT_IMPORT_ERRORS.UNKNOWN_DEPARTMENT, extra: line[`N° DE DEPARTEMENT PDR ${i}`] }); } - if (!line[`ID PDR ${i}`]) { - errors[`ID PDR ${i}`].push({ line: index, error: PDT_IMPORT_ERRORS.MISSING_DATA }); + if (!line[`MATRICULE PDR ${i}`]) { + errors[`MATRICULE PDR ${i}`].push({ line: index, error: PDT_IMPORT_ERRORS.MISSING_DATA }); } - if (line[`ID PDR ${i}`]) { - const isValidObjectId = mongoose.Types.ObjectId.isValid(line[`ID PDR ${i}`]); - const isValidCorrespondance = i > 1 && ["correspondance aller", "correspondance retour", "correspondance"].includes(line[`ID PDR ${i}`].toLowerCase()); - if (!(isValidObjectId || isValidCorrespondance)) { - errors[`ID PDR ${i}`].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_FORMAT }); + if (line[`MATRICULE PDR ${i}`]) { + const isValidString = typeof line[`MATRICULE PDR ${i}`] === "string"; + const isValidCorrespondance = i > 1 && ["correspondance aller", "correspondance retour", "correspondance"].includes(line[`MATRICULE PDR ${i}`].toLowerCase()); + if (!(isValidString || isValidCorrespondance)) { + errors[`MATRICULE PDR ${i}`].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_FORMAT }); } } if (!line[`TYPE DE TRANSPORT PDR ${i}`]) { @@ -166,13 +166,13 @@ export const validatePdtFile = async ( if (line[`HEURE ALLER ARRIVÉE AU PDR ${i}`] && !isValidTime(line[`HEURE ALLER ARRIVÉE AU PDR ${i}`])) { errors[`HEURE ALLER ARRIVÉE AU PDR ${i}`].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_FORMAT }); } - if (!line[`HEURE DEPART DU PDR ${i}`] && (line[`ID PDR ${i}`] || "").toLowerCase() !== "correspondance retour") { + if (!line[`HEURE DEPART DU PDR ${i}`] && (line[`MATRICULE PDR ${i}`] || "").toLowerCase() !== "correspondance retour") { errors[`HEURE DEPART DU PDR ${i}`].push({ line: index, error: PDT_IMPORT_ERRORS.MISSING_DATA }); } if (line[`HEURE DEPART DU PDR ${i}`] && !isValidTime(line[`HEURE DEPART DU PDR ${i}`])) { errors[`HEURE DEPART DU PDR ${i}`].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_FORMAT }); } - if (!line[`HEURE DE RETOUR ARRIVÉE AU PDR ${i}`] && (line[`ID PDR ${i}`] || "").toLowerCase() !== "correspondance aller") { + if (!line[`HEURE DE RETOUR ARRIVÉE AU PDR ${i}`] && (line[`MATRICULE PDR ${i}`] || "").toLowerCase() !== "correspondance aller") { errors[`HEURE DE RETOUR ARRIVÉE AU PDR ${i}`].push({ line: index, error: PDT_IMPORT_ERRORS.MISSING_DATA }); } if (line[`HEURE DE RETOUR ARRIVÉE AU PDR ${i}`] && !isValidTime(line[`HEURE DE RETOUR ARRIVÉE AU PDR ${i}`])) { @@ -185,11 +185,11 @@ export const validatePdtFile = async ( if (line["N° DU DEPARTEMENT DU CENTRE"] && !isValidDepartment(line["N° DU DEPARTEMENT DU CENTRE"])) { errors["N° DU DEPARTEMENT DU CENTRE"].push({ line: index, error: PDT_IMPORT_ERRORS.UNKNOWN_DEPARTMENT }); } - if (!line["ID CENTRE"]) { - errors["ID CENTRE"].push({ line: index, error: PDT_IMPORT_ERRORS.MISSING_DATA }); + if (!line["MATRICULE CENTRE"]) { + errors["MATRICULE CENTRE"].push({ line: index, error: PDT_IMPORT_ERRORS.MISSING_DATA }); } - if (line["ID CENTRE"] && !mongoose.Types.ObjectId.isValid(line["ID CENTRE"])) { - errors["ID CENTRE"].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_FORMAT }); + if (line["MATRICULE CENTRE"] && typeof line["MATRICULE CENTRE"] !== "string") { + errors["MATRICULE CENTRE"].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_FORMAT }); } if (!line["NOM + ADRESSE DU CENTRE"]) { errors["NOM + ADRESSE DU CENTRE"].push({ line: index, error: PDT_IMPORT_ERRORS.MISSING_DATA }); @@ -319,17 +319,17 @@ export const validatePdtFile = async ( errors["ID CLASSE"].push({ line: index, error: PDT_IMPORT_ERRORS.DOUBLON_CLASSE, extra: line["ID CLASSE"] }); } } - // Check if "ID CENTRE" exists in DB + // Check if "MATRICULE CENTRE" exists in DB for (const [i, line] of lines.entries()) { const index = i + FIRST_LINE_NUMBER_IN_EXCEL; - if (line["ID CENTRE"] && mongoose.Types.ObjectId.isValid(line["ID CENTRE"])) { - const center = await CohesionCenterModel.findById(line["ID CENTRE"]); + if (line["MATRICULE CENTRE"] && typeof line["MATRICULE CENTRE"] !== "string") { + const center = await CohesionCenterModel.findOne({ matricule: line["MATRICULE CENTRE"] }); if (!center) { - errors["ID CENTRE"].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_CENTER_ID, extra: line["ID CENTRE"] }); + errors["MATRICULE CENTRE"].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_CENTER_MATRICULE, extra: line["MATRICULE CENTRE"] }); } - const session = await SessionPhase1Model.findOne({ cohort: cohortName, cohesionCenterId: line["ID CENTRE"] }); + const session = await SessionPhase1Model.findOne({ cohort: cohortName, cohesionCenterId: center?._id }); if (!session) { - errors["ID CENTRE"].push({ line: index, error: PDT_IMPORT_ERRORS.CENTER_WITHOUT_SESSION, extra: line["ID CENTRE"] }); + errors["MATRICULE CENTRE"].push({ line: index, error: PDT_IMPORT_ERRORS.CENTER_WITHOUT_SESSION, extra: line["MATRICULE CENTRE"] }); } } } @@ -345,20 +345,20 @@ export const validatePdtFile = async ( } } } - // Check if `ID PDR ${i}` exists in DB, and if departement is the same as the PDR. + // Check if `MATRICULE PDR ${i}` exists in DB, and if departement is the same as the PDR. for (const [i, line] of lines.entries()) { const index = i + FIRST_LINE_NUMBER_IN_EXCEL; for (let pdrNumber = 1; pdrNumber <= countPdr; pdrNumber++) { - if (line[`ID PDR ${pdrNumber}`]) { - if (mongoose.Types.ObjectId.isValid(line[`ID PDR ${pdrNumber}`])) { - const pdr = await PointDeRassemblementModel.findOne({ _id: line[`ID PDR ${pdrNumber}`], deletedAt: { $exists: false } }); + if (line[`MATRICULE PDR ${pdrNumber}`]) { + if (typeof line[`MATRICULE PDR ${pdrNumber}`] === "string") { + const pdr = await PointDeRassemblementModel.findOne({ matricule: line[`MATRICULE PDR ${pdrNumber}`], deletedAt: { $exists: false } }); if (!pdr) { - errors[`ID PDR ${pdrNumber}`].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_PDR_ID, extra: line[`ID PDR ${pdrNumber}`] }); + errors[`MATRICULE PDR ${pdrNumber}`].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_PDR_MATRICULE, extra: line[`MATRICULE PDR ${pdrNumber}`] }); } else if ((pdr?.department || "").toLowerCase() !== departmentLookUp[line[`N° DE DEPARTEMENT PDR ${pdrNumber}`]]?.toLowerCase()) { - errors[`ID PDR ${pdrNumber}`].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_PDR_DEPARTEMENT, extra: line[`ID PDR ${pdrNumber}`] }); + errors[`MATRICULE PDR ${pdrNumber}`].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_PDR_DEPARTEMENT, extra: line[`MATRICULE PDR ${pdrNumber}`] }); } - } else if (!["correspondance aller", "correspondance retour", "correspondance"].includes(line[`ID PDR ${pdrNumber}`]?.toLowerCase())) { - errors[`ID PDR ${pdrNumber}`].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_PDR_ID, extra: line[`ID PDR ${pdrNumber}`] }); + } else if (!["correspondance aller", "correspondance retour", "correspondance"].includes(line[`MATRICULE PDR ${pdrNumber}`]?.toLowerCase())) { + errors[`MATRICULE PDR ${pdrNumber}`].push({ line: index, error: PDT_IMPORT_ERRORS.BAD_PDR_MATRICULE, extra: line[`MATRICULE PDR ${pdrNumber}`] }); } } } @@ -367,14 +367,14 @@ export const validatePdtFile = async ( // and check the max number of PDR on a line for (const [i, line] of lines.entries()) { const index = i + FIRST_LINE_NUMBER_IN_EXCEL; - const pdrIds = getLinePdrIds(line); - if (pdrIds.length > maxPdrOnLine) { - maxPdrOnLine = pdrIds.length; + const pdrMatricules = getLinePdrMatricules(line); + if (pdrMatricules.length > maxPdrOnLine) { + maxPdrOnLine = pdrMatricules.length; } //check and return duplicate pdr for (let pdrNumber = 1; pdrNumber <= countPdr; pdrNumber++) { - if (line[`ID PDR ${pdrNumber}`] && pdrIds.filter((pdrId) => pdrId === line[`ID PDR ${pdrNumber}`]).length > 1) { - errors[`ID PDR ${pdrNumber}`].push({ line: index, error: PDT_IMPORT_ERRORS.SAME_PDR_ON_LINE, extra: line[`ID PDR ${pdrNumber}`] }); + if (line[`MATRICULE PDR ${pdrNumber}`] && pdrMatricules.filter((pdrMatricule) => pdrMatricule === line[`MATRICULE PDR ${pdrNumber}`]).length > 1) { + errors[`MATRICULE PDR ${pdrNumber}`].push({ line: index, error: PDT_IMPORT_ERRORS.SAME_PDR_ON_LINE, extra: line[`MATRICULE PDR ${pdrNumber}`] }); } } } @@ -386,7 +386,7 @@ export const computeImportSummary = (lines: PdtLine[]) => { const countPdr = getLinePdrCount(lines[0]); let maxPdrOnLine = 0; for (const line of lines.entries()) { - const currentLinePDRCount = getLinePdrIds(line).length; + const currentLinePDRCount = getLinePdrMatricules(line).length; if (currentLinePDRCount > maxPdrOnLine) { maxPdrOnLine = currentLinePDRCount; } @@ -394,8 +394,8 @@ export const computeImportSummary = (lines: PdtLine[]) => { // Count total unique centers const centers = lines.reduce((acc: { [key: string]: number }, line: PdtLine) => { - if (line["ID CENTRE"]) { - acc[line["ID CENTRE"]] = (acc[line["ID CENTRE"]] || 0) + parseInt(line["CAPACITÉ VOLONTAIRE TOTALE"]); + if (line["MATRICULE CENTRE"]) { + acc[line["MATRICULE CENTRE"]] = (acc[line["MATRICULE CENTRE"]] || 0) + parseInt(line["CAPACITÉ VOLONTAIRE TOTALE"]); } return acc; }, {}); @@ -411,8 +411,8 @@ export const computeImportSummary = (lines: PdtLine[]) => { // Count total unique PDR const pdrCount = lines.reduce((acc: string[], line: PdtLine) => { for (let i = 1; i <= countPdr; i++) { - if (line[`ID PDR ${i}`] && !acc.includes(line[`ID PDR ${i}`]) && mongoose.Types.ObjectId.isValid(line[`ID PDR ${i}`])) { - acc.push(line[`ID PDR ${i}`]); + if (line[`MATRICULE PDR ${i}`] && !acc.includes(line[`MATRICULE PDR ${i}`]) && mongoose.Types.ObjectId.isValid(line[`MATRICULE PDR ${i}`])) { + acc.push(line[`MATRICULE PDR ${i}`]); } } return acc; @@ -427,16 +427,16 @@ export const computeImportSummary = (lines: PdtLine[]) => { }; const getLinePdrCount = (line) => { - return Object.keys(line).filter((e) => e.startsWith("ID PDR")).length; + return Object.keys(line).filter((e) => e.startsWith("MATRICULE PDR")).length; }; -const getLinePdrIds = (line) => { +const getLinePdrMatricules = (line) => { const countPdr = getLinePdrCount(line); - const pdrIds: string[] = []; + const pdrMatricules: string[] = []; for (let pdrNumber = 1; pdrNumber <= countPdr; pdrNumber++) { - if (line[`ID PDR ${pdrNumber}`] && !["correspondance aller", "correspondance retour", "correspondance"].includes(line[`ID PDR ${pdrNumber}`]?.toLowerCase())) { - pdrIds.push(line[`ID PDR ${pdrNumber}`]); + if (line[`MATRICULE PDR ${pdrNumber}`] && !["correspondance aller", "correspondance retour", "correspondance"].includes(line[`MATRICULE PDR ${pdrNumber}`]?.toLowerCase())) { + pdrMatricules.push(line[`MATRICULE PDR ${pdrNumber}`]); } } - return pdrIds; + return pdrMatricules; }; diff --git a/packages/lib/src/constants/plan-de-transport.ts b/packages/lib/src/constants/plan-de-transport.ts index 64dfc6d649..dc4ad80208 100644 --- a/packages/lib/src/constants/plan-de-transport.ts +++ b/packages/lib/src/constants/plan-de-transport.ts @@ -3,8 +3,10 @@ const PDT_IMPORT_ERRORS = { DOUBLON_BUSNUM: "DOUBLON_BUSNUM", DOUBLON_CLASSE: "DOUBLON_CLASSE", BAD_CENTER_ID: "BAD_CENTER_ID", + BAD_CENTER_MATRICULE: "BAD_CENTER_MATRICULE", BAD_CLASSE_ID: "BAD_CLASSE_ID", BAD_PDR_ID: "BAD_PDR_ID", + BAD_PDR_MATRICULE: "BAD_PDR_MATRICULE", BAD_PDR_DEPARTEMENT: "BAD_PDR_DEPARTEMENT", BAD_MERGED_LINE_ID: "BAD_MERGED_LINE_ID", SAME_PDR_ON_LINE: "SAME_PDR_ON_LINE", @@ -23,6 +25,7 @@ const PDT_IMPORT_ERRORS_TRANSLATION = { DOUBLON_BUSNUM: { text: "Le numéro de ligne %s est en doublon.", tooltip: "Veuillez vérifier que chaque numéro de ligne n’apparait qu’une seule fois dans le fichier." }, DOUBLON_CLASSE: { text: "Le numéro de classe %s est en doublon.", tooltip: "Une classe ne peut être divisé sur plusieurs lignes." }, BAD_CENTER_ID: { text: "ID du centre %s non existant.", tooltip: "Les ID des centres sont transmis dans le schéma de répartition." }, + BAD_CENTER_MATRICULE: { text: "Le matricule du centre %s non existant.", tooltip: "Les matricules des centres sont transmis dans le schéma de répartition." }, BAD_CLASSE_ID: { text: "ID de classe %s non existant.", tooltip: "Les ID des classes sont transmis dans le schéma de répartition." }, BAD_PDR_ID: { text: "ID du PDR %s non existant.", tooltip: "Les ID des PDR sont transmis dans le schéma de répartition." }, BAD_PDR_DEPARTEMENT: { text: "Erreur sur le département du PDR %s.", tooltip: "Le département du fichier ne correspond pas au département du PDR en base de données." }, From 425477d4b4ec4301e1953b7b5cbbe0d5687a7bd2 Mon Sep 17 00:00:00 2001 From: Johannbr Date: Tue, 22 Oct 2024 11:43:24 +0200 Subject: [PATCH 5/6] feat(api): 3395 - after CR --- api/src/controllers/planDeTransport/import.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/controllers/planDeTransport/import.js b/api/src/controllers/planDeTransport/import.js index 28b872ae35..ae0bede37a 100644 --- a/api/src/controllers/planDeTransport/import.js +++ b/api/src/controllers/planDeTransport/import.js @@ -170,7 +170,7 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f travelTime: formatTime(line["TEMPS DE ROUTE"]), sessionId: session?._id.toString(), meetingPointsIds: meetingPointsIds, - classeId: line["ID CLASSE"] ? line["ID CLASSE"] : undefined, + classeId: line["ID CLASSE"] ? line["ID CLASSE"].toLowerCase() : undefined, mergedBusIds: line["LIGNES FUSIONNÉES"] ? line["LIGNES FUSIONNÉES"].split(",") : [], }; const newBusLine = new LigneBusModel(busLineData); @@ -280,7 +280,7 @@ router.post("/:importId/execute", passport.authenticate("referent", { session: f centerZip: center?.zip, centerAddress: center?.address, centerName: center?.name, - centerCode: center?.code2022, + centerCode: center?.matricule, centerArrivalTime: busLine.centerArrivalTime, centerDepartureTime: busLine.centerDepartureTime, pointDeRassemblements, From 13dada73df10a2c788ec7179257d55d21f20645c Mon Sep 17 00:00:00 2001 From: C2Chandelier Date: Tue, 22 Oct 2024 15:28:02 +0200 Subject: [PATCH 6/6] up --- .../planDeTransport/planDeTransport/import/pdtImportService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/planDeTransport/planDeTransport/import/pdtImportService.ts b/api/src/planDeTransport/planDeTransport/import/pdtImportService.ts index 822d84f453..aa5f47751d 100644 --- a/api/src/planDeTransport/planDeTransport/import/pdtImportService.ts +++ b/api/src/planDeTransport/planDeTransport/import/pdtImportService.ts @@ -411,7 +411,7 @@ export const computeImportSummary = (lines: PdtLine[]) => { // Count total unique PDR const pdrCount = lines.reduce((acc: string[], line: PdtLine) => { for (let i = 1; i <= countPdr; i++) { - if (line[`MATRICULE PDR ${i}`] && !acc.includes(line[`MATRICULE PDR ${i}`]) && mongoose.Types.ObjectId.isValid(line[`MATRICULE PDR ${i}`])) { + if (line[`MATRICULE PDR ${i}`] && !acc.includes(line[`MATRICULE PDR ${i}`])) { acc.push(line[`MATRICULE PDR ${i}`]); } }