feat: stats amendes par type d'évènements

This commit is contained in:
Sébastien Arod 2025-06-15 09:55:53 +02:00
parent d5755516fb
commit 998714105b
3 changed files with 55 additions and 64 deletions

View file

@ -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",

View file

@ -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<string, NamedStatsType<typeof statsAmendesDesc>> {
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];
})
);
}

View file

@ -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,