feat: ajoute Pourcentage d'Entrees Après Mises en Demeure

This commit is contained in:
sebastien.arod@gmail.com 2024-06-04 09:29:33 +02:00
parent 54fcebebf0
commit e1acd45eb7
8 changed files with 56 additions and 3 deletions

View file

@ -8,6 +8,7 @@ export type Famille = {
Titre: string; Titre: string;
Statut: StatutFamille; Statut: StatutFamille;
Integration: Date | null; Integration: Date | null;
ContexteEntree: ContexteEntreeDC;
Sortie: Date | null; Sortie: Date | null;
Evenements: EvenementFamille[]; Evenements: EvenementFamille[];
}; };
@ -21,6 +22,13 @@ export type EvenementFamille = {
"Enfants concernés": string; "Enfants concernés": string;
}; };
export type ContexteEntreeDC =
| "Pas de demande (Plein droit)"
| "Pas de demande"
| "Après refus"
| "Après mise en demeure"
| "Après poursuite procureur";
export type TypeEvenement = export type TypeEvenement =
| "Mise en demeure de scolarisation" | "Mise en demeure de scolarisation"
| "Composition pénale refusée" | "Composition pénale refusée"

View file

@ -1,6 +1,7 @@
import { Client, isFullPage } from "@notionhq/client"; import { Client, isFullPage } from "@notionhq/client";
import { PageObjectResponse } from "@notionhq/client/build/src/api-endpoints"; import { PageObjectResponse } from "@notionhq/client/build/src/api-endpoints";
import { import {
ContexteEntreeDC,
EvenementFamille, EvenementFamille,
Famille, Famille,
StatutFamille, StatutFamille,
@ -70,6 +71,10 @@ function buildFamily(
notionId: page.id, notionId: page.id,
Titre: titlePropertyToText(pageProperties, ""), Titre: titlePropertyToText(pageProperties, ""),
Statut: statusPropertyToText(pageProperties, "Statut") as StatutFamille, Statut: statusPropertyToText(pageProperties, "Statut") as StatutFamille,
ContexteEntree: selectPropertyToText(
pageProperties,
"Contexte dentrée DC"
) as ContexteEntreeDC,
Integration: datePropertyToDate(pageProperties, "Intégration"), Integration: datePropertyToDate(pageProperties, "Intégration"),
Sortie: datePropertyToDate(pageProperties, "Sortie"), Sortie: datePropertyToDate(pageProperties, "Sortie"),
Evenements: familyEvents.filter((fe) => fe.notionIdFamille === page.id), Evenements: familyEvents.filter((fe) => fe.notionIdFamille === page.id),

View file

@ -10,6 +10,7 @@ import {
statNameDureeResistanceMoyenne, statNameDureeResistanceMoyenne,
statsNameNbFamillesMisesEnDemeure, statsNameNbFamillesMisesEnDemeure,
statsNameNbFamillesResistantes, statsNameNbFamillesResistantes,
statsNamePourcentageEntreeApresMisesEnDemeure,
} from "./statNames"; } from "./statNames";
export async function publishPeriodStats( export async function publishPeriodStats(
@ -102,6 +103,9 @@ function buildRowPropertiesForUpsert(
[statsNameNbFamillesMisesEnDemeure]: valueWithEvolProp( [statsNameNbFamillesMisesEnDemeure]: valueWithEvolProp(
stat.nbFamillesMisesEnDemeure stat.nbFamillesMisesEnDemeure
), ),
[statsNamePourcentageEntreeApresMisesEnDemeure]: valueWithEvolProp(
stat.pourcentageEntreeApresMiseEnDemeure
),
}; };
} }

View file

@ -11,6 +11,7 @@ import {
statsNameNbFamillesMisesEnDemeure, statsNameNbFamillesMisesEnDemeure,
statsNameNbFamillesResistantes, statsNameNbFamillesResistantes,
statsNameNbFamillesResistantesOuEx, statsNameNbFamillesResistantesOuEx,
statsNamePourcentageEntreeApresMisesEnDemeure,
statsNamePourcentageFamilleMisesEnDemeure, statsNamePourcentageFamilleMisesEnDemeure,
} from "./statNames"; } from "./statNames";
@ -73,6 +74,10 @@ export async function publishStatsActuelles(
statsNamePourcentageFamilleMisesEnDemeure, statsNamePourcentageFamilleMisesEnDemeure,
statsActuelles.pourcentageFamillesMisesEnDemeure statsActuelles.pourcentageFamillesMisesEnDemeure
), ),
currentStatBlock(
statsNamePourcentageEntreeApresMisesEnDemeure,
statsActuelles.pourcentageEntreeApresMiseEnDemeure
),
], ],
}); });
} }

View file

@ -6,3 +6,5 @@ export const statsNameNbFamillesResistantesOuEx =
export const statsNameNbFamillesMisesEnDemeure = "Nb Familles Mises en Demeure"; export const statsNameNbFamillesMisesEnDemeure = "Nb Familles Mises en Demeure";
export const statsNamePourcentageFamilleMisesEnDemeure = export const statsNamePourcentageFamilleMisesEnDemeure =
"Pourcentage de Familles Mises en Demeure"; "Pourcentage de Familles Mises en Demeure";
export const statsNamePourcentageEntreeApresMisesEnDemeure =
"Pourcentage d'Entrees Après Mises en Demeure";

View file

@ -13,6 +13,7 @@ export type ELStatsActuelles = {
dureeResistanceMediane: number; dureeResistanceMediane: number;
nbFamillesMiseEnDemeure: number; nbFamillesMiseEnDemeure: number;
pourcentageFamillesMisesEnDemeure: number; pourcentageFamillesMisesEnDemeure: number;
pourcentageEntreeApresMiseEnDemeure: number;
}; };
export type ELPeriodStats = { export type ELPeriodStats = {
@ -21,6 +22,7 @@ export type ELPeriodStats = {
dureeResistanceMoyenne: ValueWithEvol; dureeResistanceMoyenne: ValueWithEvol;
dureeResistanceMediane: ValueWithEvol; dureeResistanceMediane: ValueWithEvol;
nbFamillesMisesEnDemeure: ValueWithEvol; nbFamillesMisesEnDemeure: ValueWithEvol;
pourcentageEntreeApresMiseEnDemeure: ValueWithEvol;
}; };
export type ValueWithEvol = { export type ValueWithEvol = {

View file

@ -2,6 +2,7 @@ import {
Famille, Famille,
dureeResistanceInDays, dureeResistanceInDays,
isResistantOverPeriod, isResistantOverPeriod,
periodOfResistance,
} from "../data/Famille"; } from "../data/Famille";
import { IdentifiedPeriod } from "../period/IdentifiedPeriod"; import { IdentifiedPeriod } from "../period/IdentifiedPeriod";
import { isPeriodContaining } from "../period/isPeriodContaining"; import { isPeriodContaining } from "../period/isPeriodContaining";
@ -16,18 +17,19 @@ export function computeELPeriodStats(
const periodStats: ELPeriodStats[] = []; const periodStats: ELPeriodStats[] = [];
let previousELPeriodStats: ELPeriodStats | null = null; let previousELPeriodStats: ELPeriodStats | null = null;
for (const period of periods) { for (const period of periods) {
const periodEndOrNow =
period.end.getTime() > Date.now() ? new Date(Date.now()) : period.end;
const nbFamilleResistantes = familles.filter((famille) => const nbFamilleResistantes = familles.filter((famille) =>
isResistantOverPeriod(famille, period) isResistantOverPeriod(famille, period)
).length; ).length;
const periodEndOrNow =
period.end.getTime() > Date.now() ? new Date(Date.now()) : period.end;
const dureesResistances = familles const dureesResistances = familles
.map((famille) => dureeResistanceInDays(famille, periodEndOrNow)) .map((famille) => dureeResistanceInDays(famille, periodEndOrNow))
.filter(notNull); .filter(notNull);
const dureeResistanceMediane = Math.round(median(dureesResistances)); const dureeResistanceMediane = Math.round(median(dureesResistances));
const dureeResistanceMoyenne = Math.round(average(dureesResistances)); const dureeResistanceMoyenne = Math.round(average(dureesResistances));
const nbFamillesMiseEnDemeure = familles.filter((famille) => const nbFamillesMiseEnDemeure = familles.filter((famille) =>
famille.Evenements.find( famille.Evenements.find(
(e) => (e) =>
@ -36,6 +38,19 @@ export function computeELPeriodStats(
isPeriodContaining(period, e.Date) isPeriodContaining(period, e.Date)
) )
).length; ).length;
const famillesEntreesOverPeriod = familles.filter((f) => {
const por = periodOfResistance(f);
return por != null && isPeriodContaining(period, por.start);
});
const entreeApresMiseEnDemeure = famillesEntreesOverPeriod.filter(
(f) =>
f.ContexteEntree === "Après mise en demeure" ||
f.ContexteEntree === "Après poursuite procureur"
);
const pourcentageEntreeApresMiseEnDemeure =
(100 * entreeApresMiseEnDemeure.length) /
famillesEntreesOverPeriod.length;
const stats: ELPeriodStats = { const stats: ELPeriodStats = {
periodId: period.id, periodId: period.id,
nbFamilleResistantes: valueWithEvol( nbFamilleResistantes: valueWithEvol(
@ -54,6 +69,10 @@ export function computeELPeriodStats(
nbFamillesMiseEnDemeure, nbFamillesMiseEnDemeure,
previousELPeriodStats?.nbFamillesMisesEnDemeure.value previousELPeriodStats?.nbFamillesMisesEnDemeure.value
), ),
pourcentageEntreeApresMiseEnDemeure: valueWithEvol(
pourcentageEntreeApresMiseEnDemeure,
previousELPeriodStats?.pourcentageEntreeApresMiseEnDemeure.value
),
}; };
periodStats.push(stats); periodStats.push(stats);
previousELPeriodStats = stats; previousELPeriodStats = stats;

View file

@ -24,6 +24,12 @@ export function computeStatsActuelles(familles: Famille[]): ELStatsActuelles {
f.Evenements.find((e) => e.Type === "Mise en demeure de scolarisation") f.Evenements.find((e) => e.Type === "Mise en demeure de scolarisation")
); );
const entreeApresMiseEnDemeure = resistantsOrEx.filter(
(f) =>
f.ContexteEntree === "Après mise en demeure" ||
f.ContexteEntree === "Après poursuite procureur"
);
const actuelles: ELStatsActuelles = { const actuelles: ELStatsActuelles = {
nbFamilleResistantes: resistantsCount, nbFamilleResistantes: resistantsCount,
nbFamilleResistantesOrEx: resistantsOrEx.length, nbFamilleResistantesOrEx: resistantsOrEx.length,
@ -32,6 +38,8 @@ export function computeStatsActuelles(familles: Famille[]): ELStatsActuelles {
nbFamillesMiseEnDemeure: familleAvecMiseEnDemeure.length, nbFamillesMiseEnDemeure: familleAvecMiseEnDemeure.length,
pourcentageFamillesMisesEnDemeure: pourcentageFamillesMisesEnDemeure:
(100 * familleAvecMiseEnDemeure.length) / resistantsOrEx.length, (100 * familleAvecMiseEnDemeure.length) / resistantsOrEx.length,
pourcentageEntreeApresMiseEnDemeure:
(100 * entreeApresMiseEnDemeure.length) / resistantsOrEx.length,
}; };
return actuelles; return actuelles;
} }