diff --git a/src/cron/demarchesSimplifiees.ts b/src/cron/demarchesSimplifiees.ts index 33fd6a47..f0c4cdf2 100644 --- a/src/cron/demarchesSimplifiees.ts +++ b/src/cron/demarchesSimplifiees.ts @@ -1,6 +1,7 @@ import * as Sentry from "@sentry/nextjs"; import pLimit from "p-limit"; +import { formatAdeliId } from "../services/adeli/formatAdeliId"; import { requestAdeli } from "../services/adeli/request"; import { addVerificationMessage } from "../services/demarchesSimplifiees/buildRequest"; import filterDossiersToVerif from "../services/demarchesSimplifiees/dossiers"; @@ -20,7 +21,6 @@ import { } from "../services/psychologists"; import { AdeliData } from "../types/adeli"; import { Psychologist } from "../types/psychologist"; -import { removeNonNumericCharacters } from "../utils/string"; const limit = pLimit(5); @@ -74,6 +74,27 @@ export const importFromDS = async (): Promise => { await importArchived(); }; +function isAdeliIdValidDepartment( + adeliId: string, + department: string +): boolean { + const departmentFromAdeli = formatAdeliId(adeliId).substring(0, 2); + switch (departmentFromAdeli) { + case "9A": + return department === "971"; + case "9B": + return department === "972"; + case "9C": + return department === "973"; + case "9D": + return department === "974"; + case "9F": + return department === "976"; + default: + return departmentFromAdeli === department; + } +} + export const validateDossier = async ( dossier: Psychologist, adeliData: AdeliData[] @@ -84,10 +105,7 @@ export const validateDossier = async ( return [`Numéro ADELI invalide : ${dossier.adeliId}`]; } - const departmentFromAdeli = removeNonNumericCharacters( - dossier.adeliId || "" - ).substring(0, 2); - if (dossier.department !== departmentFromAdeli) { + if (!isAdeliIdValidDepartment(dossier.adeliId || "", dossier.department)) { errors.push( `Le numéro ADELI ${dossier.adeliId} ne correspond pas au département ${dossier.department}` ); diff --git a/src/services/__tests__/adeli-resquest.spec.ts b/src/services/__tests__/adeli-resquest.spec.ts index 5c1dcfbf..c54269cc 100644 --- a/src/services/__tests__/adeli-resquest.spec.ts +++ b/src/services/__tests__/adeli-resquest.spec.ts @@ -20,17 +20,23 @@ describe("requestAdeli", () => { }); it.each` - input - ${"123"} - ${"1 2 3"} - ${"1.2...3"} - ${"00/00/01/23"} - `("should call api endpoint if adeli is $input", async ({ input }) => { - const result = await requestAdeli(input); - expect(axios.get).toHaveBeenCalledWith( - "https://datasette-ps-libre-acces.dev.fabrique.social.gouv.fr/PS_LibreAcces/PS_LibreAcces_Personne_activite.json", - { params: { "Identification nationale PP__exact": "0000000123" } } - ); - expect(result).toEqual([]); - }); + input | expected + ${"123"} | ${"0000000123"} + ${"1 2 3"} | ${"0000000123"} + ${"1.2...3"} | ${"0000000123"} + ${"00/00/01/23"} | ${"0000000123"} + ${"123zzz"} | ${"0000000123"} + ${"9F12345678"} | ${"9F12345678"} + ${"2A 1234 5678"} | ${"2A12345678"} + `( + "should call api endpoint if adeli is $input", + async ({ input, expected }) => { + const result = await requestAdeli(input); + expect(axios.get).toHaveBeenCalledWith( + "https://datasette-ps-libre-acces.dev.fabrique.social.gouv.fr/PS_LibreAcces/PS_LibreAcces_Personne_activite.json", + { params: { "Identification nationale PP__exact": expected } } + ); + expect(result).toEqual([]); + } + ); }); diff --git a/src/services/adeli/formatAdeliId.ts b/src/services/adeli/formatAdeliId.ts new file mode 100644 index 00000000..2020fe2c --- /dev/null +++ b/src/services/adeli/formatAdeliId.ts @@ -0,0 +1,10 @@ +export const formatAdeliId = (adeliId: string): string => { + // Adeli ID is a 10-digit string, that can also contain letters for some departments. + // e.g. "9A1234678" (Guadeloupe) or "2A1234678" (Corse-du-Sud). + // In this particular function, we just want to remove non-alphanumeric (0 to 9 and A to F) characters + // since it is sent to adeli service for complete checking. + return (adeliId || "") + .replace(/[^0-9a-f]/gi, "") + .toUpperCase() + .padStart(10, "0"); +}; diff --git a/src/services/adeli/request.ts b/src/services/adeli/request.ts index 04b4f568..221ac707 100644 --- a/src/services/adeli/request.ts +++ b/src/services/adeli/request.ts @@ -2,11 +2,8 @@ import axios, { AxiosResponse } from "axios"; import { AdeliData, AdeliRawResponse } from "../../types/adeli"; import { zip } from "../../utils/array"; -import { removeNonNumericCharacters } from "../../utils/string"; import config from "../config"; - -const formatRequestedAdeli = (adeliId: string): string => - removeNonNumericCharacters(adeliId || "").padStart(10, "0"); +import { formatAdeliId } from "./formatAdeliId"; const rowColumnsToObject = (row: string[], columns: Column[]) => Object.fromEntries(zip(columns, row)); @@ -24,7 +21,7 @@ export const requestAdeli = async ( config.adeli.apiUrl, { params: { - "Identification nationale PP__exact": formatRequestedAdeli(numeroAdeli), + "Identification nationale PP__exact": formatAdeliId(numeroAdeli), }, } ); diff --git a/src/utils/string.ts b/src/utils/string.ts index afd63fac..b2451593 100644 --- a/src/utils/string.ts +++ b/src/utils/string.ts @@ -19,7 +19,3 @@ export const firstWordAreSimilar = ( return areSimilar(firstWord1, firstWord2); }; - -export function removeNonNumericCharacters(value: string): string { - return value.replace(/[^0-9]/g, ""); -}