From 64faab1c8e7bbe29d86237b781bfba23b1aa2fab Mon Sep 17 00:00:00 2001 From: "sebastien.arod@gmail.com" Date: Wed, 31 Jul 2024 14:42:39 +0200 Subject: [PATCH] feat: Draft stats par anciennete --- src/index.ts | 6 ++ .../computeEvenementsParAnciennete.ts | 35 ++++++++++ ...omputeFamilleWithEventAfterDurationOfDC.ts | 67 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/statistiques/computeEvenementsParAnciennete.ts create mode 100644 src/statistiques/computeFamilleWithEventAfterDurationOfDC.ts diff --git a/src/index.ts b/src/index.ts index fb7f90a..e1da1dd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ import { checkDataConsistency } from "./data/checkDataConsistency"; import { fetchFamiliesWithEventsFromNotion } from "./notion/fetch/fetchFamiliesWithEventsFromNotion"; import { publishStatisticsToNotion } from "./notion/publish/publishStatisticsToNotion"; import { computeELStats } from "./statistiques/computeELStats"; +import { computeStatsParAnciennete } from "./statistiques/computeEvenementsParAnciennete"; type ProcessOptions = { dryRun: boolean; @@ -59,6 +60,11 @@ function buildProcessOptions(): ProcessOptions { console.log("Building statistics..."); const elStats = computeELStats(familles, currentDate); + const statsParAnciennete = computeStatsParAnciennete(familles); + writeFileSync( + "./el-stats-par-anciennete.json", + JSON.stringify(statsParAnciennete, null, " ") + ); if (options.dryRun) { console.log( "Dry run => Skip Publishing. Stats are dumped in file el-stats.json" diff --git a/src/statistiques/computeEvenementsParAnciennete.ts b/src/statistiques/computeEvenementsParAnciennete.ts new file mode 100644 index 0000000..a131445 --- /dev/null +++ b/src/statistiques/computeEvenementsParAnciennete.ts @@ -0,0 +1,35 @@ +import { isProcedureCivile, isProcedurePenale } from "../data/EvenementFamille"; +import { computeFamillesWithEventsConditionInEarlyPeriod } from "./computeFamilleWithEventAfterDurationOfDC"; + +export function computeStatsParAnciennete( + familles: import("c:/Users/sebas/git/perso/el/statistiques/src/data/Famille").Famille[] +) { + return { + procedureCivile: computeFamillesWithEventsConditionInEarlyPeriod( + familles, + (events) => events.find((ev) => isProcedureCivile(ev)) !== undefined + ), + procedurePenale: computeFamillesWithEventsConditionInEarlyPeriod( + familles, + (events) => events.find((ev) => isProcedurePenale(ev)) !== undefined + ), + + miseEnDemeure: computeFamillesWithEventsConditionInEarlyPeriod( + familles, + (events) => + events.find((ev) => ev.Type === "Mise en demeure de scolarisation") !== + undefined + ), + auditionGendarmerie: computeFamillesWithEventsConditionInEarlyPeriod( + familles, + (events) => + events.find((ev) => ev.Type === "Audition gendarmerie / police") !== + undefined + ), + tribunalCorrectionnel: computeFamillesWithEventsConditionInEarlyPeriod( + familles, + (events) => + events.find((ev) => ev.Type === "Tribunal correctionnel") !== undefined + ), + }; +} diff --git a/src/statistiques/computeFamilleWithEventAfterDurationOfDC.ts b/src/statistiques/computeFamilleWithEventAfterDurationOfDC.ts new file mode 100644 index 0000000..9f09a62 --- /dev/null +++ b/src/statistiques/computeFamilleWithEventAfterDurationOfDC.ts @@ -0,0 +1,67 @@ +import { addMonths } from "date-fns"; +import { EvenementFamille, isEvenementBefore } from "../data/EvenementFamille"; +import { Famille } from "../data/Famille"; +import { percent } from "../utils/math/percent"; + +type FamillesWithEventsConditionInEarlyPeriod = { + [name: string]: { + nbFamillesWithAtLeastDuration: number; + nbFamillesWithEventPredicate: number; + percentage: number; + }; +}; + +export const computeFamillesWithEventsConditionInEarlyPeriod = ( + familles: Famille[], + eventsPredicate: (events: EvenementFamille[]) => boolean, + durations: { + [name: string]: number; + } = { + "0 mois": 0, + "3 mois": 3, + "6 mois": 6, + "12 mois": 12, + "24 mois": 24, + } +): FamillesWithEventsConditionInEarlyPeriod => { + const evalDate = new Date(Date.now()); + return Object.fromEntries( + Object.entries(durations).map(([name, months]) => { + const famillesWithAtLeastDurationOfDc = familles + .filter( + (f) => f.Statut === "Résistant.e" || f.Statut === "Ex résistant·e·s" + ) + .filter( + (f) => + dcStartDate(f) !== null && + addMonths(dcStartDate(f)!, months) < evalDate + ); + + const famillesWithEventPredicate = famillesWithAtLeastDurationOfDc.filter( + (f) => { + const dcDate = dcStartDate(f)!; + const dcPeriodEnd = addMonths(dcDate, months); + const eventsBeforeDate = f.Evenements.filter((e) => + isEvenementBefore(e, dcPeriodEnd) + ); + return eventsPredicate(eventsBeforeDate); + } + ); + return [ + name, + { + nbFamillesWithAtLeastDuration: famillesWithAtLeastDurationOfDc.length, + nbFamillesWithEventPredicate: famillesWithEventPredicate.length, + percentage: percent( + famillesWithEventPredicate.length, + famillesWithAtLeastDurationOfDc.length + ), + }, + ]; + }) + ); +}; + +const dcStartDate = (famille: Famille): Date | null => { + return famille.Integration; +};