feat: Draft stats par anciennete

This commit is contained in:
sebastien.arod@gmail.com 2024-07-31 14:42:39 +02:00
parent f3764a98f5
commit 64faab1c8e
3 changed files with 108 additions and 0 deletions

View file

@ -4,6 +4,7 @@ import { checkDataConsistency } from "./data/checkDataConsistency";
import { fetchFamiliesWithEventsFromNotion } from "./notion/fetch/fetchFamiliesWithEventsFromNotion"; import { fetchFamiliesWithEventsFromNotion } from "./notion/fetch/fetchFamiliesWithEventsFromNotion";
import { publishStatisticsToNotion } from "./notion/publish/publishStatisticsToNotion"; import { publishStatisticsToNotion } from "./notion/publish/publishStatisticsToNotion";
import { computeELStats } from "./statistiques/computeELStats"; import { computeELStats } from "./statistiques/computeELStats";
import { computeStatsParAnciennete } from "./statistiques/computeEvenementsParAnciennete";
type ProcessOptions = { type ProcessOptions = {
dryRun: boolean; dryRun: boolean;
@ -59,6 +60,11 @@ function buildProcessOptions(): ProcessOptions {
console.log("Building statistics..."); console.log("Building statistics...");
const elStats = computeELStats(familles, currentDate); const elStats = computeELStats(familles, currentDate);
const statsParAnciennete = computeStatsParAnciennete(familles);
writeFileSync(
"./el-stats-par-anciennete.json",
JSON.stringify(statsParAnciennete, null, " ")
);
if (options.dryRun) { if (options.dryRun) {
console.log( console.log(
"Dry run => Skip Publishing. Stats are dumped in file el-stats.json" "Dry run => Skip Publishing. Stats are dumped in file el-stats.json"

View file

@ -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
),
};
}

View file

@ -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;
};