From 998714105b95aca27fd8beaa580f765317a4dd82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Arod?= Date: Sun, 15 Jun 2025 09:55:53 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20stats=20amendes=20par=20type=20d'=C3=A9?= =?UTF-8?q?v=C3=A8nements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/statistiques/v2/penales/StatsPenales.ts | 16 ++---- .../v2/penales/computeStatsAmendes.ts | 49 +++++++++++++++++ .../v2/penales/computeStatsPenales.ts | 54 +------------------ 3 files changed, 55 insertions(+), 64 deletions(-) create mode 100644 src/statistiques/v2/penales/computeStatsAmendes.ts diff --git a/src/statistiques/v2/penales/StatsPenales.ts b/src/statistiques/v2/penales/StatsPenales.ts index 7924ee9..bb6d6e4 100644 --- a/src/statistiques/v2/penales/StatsPenales.ts +++ b/src/statistiques/v2/penales/StatsPenales.ts @@ -24,7 +24,7 @@ export const statsTribunalCorrectionnelDesc = { }, } as const; -const statsAmendesDesc = { +export const statsAmendesDesc = { amendeMinAvecSursi: { label: "Amende avec sursi minimale", unit: "€", @@ -169,17 +169,9 @@ export const statsPenalesDesc = { valueMaxFractioDigits: 0, }, amendes: { - label: "Amendes", - stats: { - tc: { - label: "Tribunal Correctionnel", - stats: statsAmendesDesc, - }, - tp: { - label: "Tribunal de Police", - stats: statsAmendesDesc, - }, - }, + label: "Amendes par type d'évènements", + type: "group-list", + stats: statsAmendesDesc, }, parDepartements: { label: "Par départements", diff --git a/src/statistiques/v2/penales/computeStatsAmendes.ts b/src/statistiques/v2/penales/computeStatsAmendes.ts new file mode 100644 index 0000000..a3ac57a --- /dev/null +++ b/src/statistiques/v2/penales/computeStatsAmendes.ts @@ -0,0 +1,49 @@ +import { uniq } from "lodash"; +import { Famille } from "../../../data/Famille"; +import { NamedStatsType } from "../desc/StatsDesc"; +import { statsAmendesDesc } from "./StatsPenales"; +import { isEvtProcedurePenale } from "../../../data/EvenementFamille"; + +export function computeStatsAmendes( + familles: Famille[] +): Record> { + const flatEvtsProcedurePenale = familles + .flatMap((f) => f.EvenementsEL) + .filter((e) => isEvtProcedurePenale(e)); + + const typeEvtsAvecAmendesFermeOuSursi = uniq( + flatEvtsProcedurePenale + .filter((e) => + e.Amendes.find( + (a) => + !isNaN(a.Montant) && + (a.Type === "avec sursis" || a.Type === "ferme") + ) + ) + .map((e) => e.Type) + ).sort(); + + return Object.fromEntries( + typeEvtsAvecAmendesFermeOuSursi.map((evtType) => { + const amendesForType = flatEvtsProcedurePenale + .filter((e) => e.Type === evtType) + .flatMap((e) => e.Amendes) + .filter((a) => !isNaN(a.Montant)); + + const montantsAvecSursi = amendesForType + .filter((a) => a.Type === "avec sursis") + .map((a) => a.Montant); + const montantsFerme = amendesForType + .filter((a) => a.Type === "ferme") + .map((a) => a.Montant); + + const stats = { + amendeMinAvecSursi: Math.min(...montantsAvecSursi), + amendeMaxAvecSursi: Math.max(...montantsAvecSursi), + amendeMinFerme: Math.min(...montantsFerme), + amendeMaxFerme: Math.max(...montantsFerme), + }; + return [evtType, stats]; + }) + ); +} diff --git a/src/statistiques/v2/penales/computeStatsPenales.ts b/src/statistiques/v2/penales/computeStatsPenales.ts index 21c3993..2ae2423 100644 --- a/src/statistiques/v2/penales/computeStatsPenales.ts +++ b/src/statistiques/v2/penales/computeStatsPenales.ts @@ -25,6 +25,7 @@ import { computeIntervalMedGendarmerieOuProcureur } from "./intervals/computeInt import { groupBy } from "lodash"; import { percent } from "../../../utils/math/percent"; import { isEvtTypeProcedurePenaleHorsGendarmerie } from "../../../data/TypeEvenementsPenal"; +import { computeStatsAmendes } from "./computeStatsAmendes"; export type FamilleAvecInfoTribunaux = Famille & { infoTribunaux: InfoTribunalCorrectionnel[]; @@ -76,20 +77,6 @@ export function computeStatsPenales(familles: Famille[]): StatsPenales { const famillesAvecInfoProceduresPenales: FamilleAvecInfoProceduresPenales[] = famillesResistantesOuEx.map(computeFamilleAvecInfosProceduresPenales); - const amendesTC = famillesResistantesOuEx - .flatMap((f) => - f.EvenementsEL.filter((e) => e.Type === "Tribunal correctionnel") - ) - .flatMap((e) => e.Amendes) - .filter((e) => !isNaN(e.Montant)); - - const amendesTP = famillesResistantesOuEx - .flatMap((f) => - f.EvenementsEL.filter((e) => e.Type === "Tribunal de police judiciaire") - ) - .flatMap((e) => e.Amendes) - .filter((e) => !isNaN(e.Montant)); - const statsPenales: StatsPenales = { nbFamillesMisesEnDemeure: nbFamillesAvecPagesLiees(famillesMisesEnDemeure), nbFamillesAvecProcedurePenale: nbFamillesAvecPagesLiees( @@ -177,44 +164,7 @@ export function computeStatsPenales(familles: Famille[]): StatsPenales { computeIntervalProcureurTribunalCorrectionnel( famillesAvecInfoProceduresPenales ), - amendes: { - tc: { - amendeMinAvecSursi: Math.min( - ...amendesTC - .filter((a) => a.Type === "avec sursis") - .map((a) => a.Montant) - ), - amendeMaxAvecSursi: Math.max( - ...amendesTC - .filter((a) => a.Type === "avec sursis") - .map((a) => a.Montant) - ), - amendeMinFerme: Math.min( - ...amendesTC.filter((a) => a.Type === "ferme").map((a) => a.Montant) - ), - amendeMaxFerme: Math.max( - ...amendesTC.filter((a) => a.Type === "ferme").map((a) => a.Montant) - ), - }, - tp: { - amendeMinAvecSursi: Math.min( - ...amendesTP - .filter((a) => a.Type === "avec sursis") - .map((a) => a.Montant) - ), - amendeMaxAvecSursi: Math.max( - ...amendesTP - .filter((a) => a.Type === "avec sursis") - .map((a) => a.Montant) - ), - amendeMinFerme: Math.min( - ...amendesTP.filter((a) => a.Type === "ferme").map((a) => a.Montant) - ), - amendeMaxFerme: Math.max( - ...amendesTP.filter((a) => a.Type === "ferme").map((a) => a.Montant) - ), - }, - }, + amendes: computeStatsAmendes(famillesResistantesOuEx), parDepartements: Object.fromEntries( departements.map((d) => [ d,