111 lines
3.3 KiB
TypeScript
111 lines
3.3 KiB
TypeScript
import { eq, sql } from "drizzle-orm";
|
|
import { getDb } from "./db";
|
|
import { apprenants, inscriptions } from "../drizzle/schema";
|
|
|
|
export async function getEtablissementsStats() {
|
|
const db = await getDb();
|
|
if (!db) return [];
|
|
|
|
// Récupérer tous les apprenants groupés par établissement
|
|
const apprenantsData = await db.select().from(apprenants);
|
|
|
|
// Grouper par code établissement
|
|
const etablissementsMap = new Map<string, {
|
|
codeEtablissement: string;
|
|
nombreApprenants: number;
|
|
apprenantsActifs: number;
|
|
apprenantIds: number[];
|
|
}>();
|
|
|
|
for (const apprenant of apprenantsData) {
|
|
const code = apprenant.codeEtablissement;
|
|
|
|
if (!etablissementsMap.has(code)) {
|
|
etablissementsMap.set(code, {
|
|
codeEtablissement: code,
|
|
nombreApprenants: 0,
|
|
apprenantsActifs: 0,
|
|
apprenantIds: [],
|
|
});
|
|
}
|
|
|
|
const etab = etablissementsMap.get(code)!;
|
|
etab.nombreApprenants++;
|
|
etab.apprenantIds.push(apprenant.id);
|
|
}
|
|
|
|
// Pour chaque établissement, compter les apprenants actifs
|
|
const etablissementsStats = await Promise.all(
|
|
Array.from(etablissementsMap.values()).map(async (etab) => {
|
|
// Compter le nombre d'apprenants ayant au moins une inscription
|
|
const apprenantsActifsCount = await Promise.all(
|
|
etab.apprenantIds.map(async (apprenantId) => {
|
|
const inscriptionsData = await db
|
|
.select()
|
|
.from(inscriptions)
|
|
.where(eq(inscriptions.apprenantId, apprenantId))
|
|
.limit(1);
|
|
return inscriptionsData.length > 0 ? 1 : 0;
|
|
})
|
|
);
|
|
|
|
const nombreActifs = apprenantsActifsCount.reduce((sum: number, count) => sum + count, 0);
|
|
const tauxParticipation = etab.nombreApprenants > 0
|
|
? Math.round((nombreActifs / etab.nombreApprenants) * 100)
|
|
: 0;
|
|
|
|
return {
|
|
codeEtablissement: etab.codeEtablissement,
|
|
nombreApprenants: etab.nombreApprenants,
|
|
apprenantsActifs: nombreActifs,
|
|
tauxParticipation,
|
|
};
|
|
})
|
|
);
|
|
|
|
// Trier par nombre d'apprenants décroissant
|
|
return etablissementsStats.sort((a, b) => b.nombreApprenants - a.nombreApprenants);
|
|
}
|
|
|
|
export async function getEtablissementDetail(codeEtablissement: string) {
|
|
const db = await getDb();
|
|
if (!db) return null;
|
|
|
|
// Récupérer tous les apprenants de cet établissement
|
|
const apprenantsData = await db
|
|
.select()
|
|
.from(apprenants)
|
|
.where(eq(apprenants.codeEtablissement, codeEtablissement));
|
|
|
|
// Pour chaque apprenant, récupérer ses inscriptions
|
|
const apprenantsWithInscriptions = await Promise.all(
|
|
apprenantsData.map(async (apprenant) => {
|
|
const inscriptionsData = await db
|
|
.select()
|
|
.from(inscriptions)
|
|
.where(eq(inscriptions.apprenantId, apprenant.id));
|
|
|
|
return {
|
|
...apprenant,
|
|
inscriptions: inscriptionsData,
|
|
};
|
|
})
|
|
);
|
|
|
|
const nombreApprenants = apprenantsData.length;
|
|
const apprenantsActifs = apprenantsWithInscriptions.filter(
|
|
(a) => a.inscriptions.length > 0
|
|
).length;
|
|
const tauxParticipation = nombreApprenants > 0
|
|
? Math.round((apprenantsActifs / nombreApprenants) * 100)
|
|
: 0;
|
|
|
|
return {
|
|
codeEtablissement,
|
|
nombreApprenants,
|
|
apprenantsActifs,
|
|
tauxParticipation,
|
|
apprenants: apprenantsWithInscriptions,
|
|
};
|
|
}
|