86 lines
1.8 KiB
TypeScript
86 lines
1.8 KiB
TypeScript
/**
|
|
* Logique métier pour le calcul des notes et moyennes.
|
|
*/
|
|
|
|
export interface Note {
|
|
note: number;
|
|
noteSession2: number | null;
|
|
}
|
|
|
|
export interface UEModule {
|
|
idModule: string;
|
|
coeff: number;
|
|
}
|
|
|
|
export interface Ajustement {
|
|
valeur: number;
|
|
malus: number;
|
|
}
|
|
|
|
/**
|
|
* Retourne la note effective (Session 2 si présente, sinon Session 1).
|
|
*/
|
|
export function getEffectiveNote(n: Note): number {
|
|
return n.noteSession2 ?? n.note;
|
|
}
|
|
|
|
/**
|
|
* Calcule la moyenne pondérée d'une liste de modules.
|
|
* Retourne null si aucun module n'est noté.
|
|
*/
|
|
export function calculateWeightedAverage(
|
|
ueModules: UEModule[],
|
|
notesMap: Record<string, Note>,
|
|
): number | null {
|
|
let weightedSum = 0;
|
|
let coveredCoeff = 0;
|
|
|
|
for (const um of ueModules) {
|
|
const noteObj = notesMap[um.idModule];
|
|
if (noteObj) {
|
|
const val = getEffectiveNote(noteObj);
|
|
weightedSum += val * um.coeff;
|
|
coveredCoeff += um.coeff;
|
|
}
|
|
}
|
|
|
|
if (coveredCoeff === 0) return null;
|
|
return weightedSum / coveredCoeff;
|
|
}
|
|
|
|
/**
|
|
* Applique l'ajustement et le malus à une moyenne.
|
|
* L'ajustement REMPLACE la moyenne calculée si présent.
|
|
*/
|
|
export function applyAjustement(
|
|
calculatedAvg: number | null,
|
|
ajustement: Ajustement | null,
|
|
): number | null {
|
|
let finalAvg = calculatedAvg;
|
|
|
|
if (ajustement) {
|
|
// L'ajustement remplace la moyenne
|
|
finalAvg = ajustement.valeur;
|
|
if (ajustement.malus > 0) {
|
|
finalAvg = (finalAvg ?? 0) - ajustement.malus;
|
|
}
|
|
}
|
|
|
|
return finalAvg;
|
|
}
|
|
|
|
/**
|
|
* Arrondit une note à 2 décimales.
|
|
*/
|
|
export function roundGrade(grade: number): number {
|
|
return Math.round(grade * 100) / 100;
|
|
}
|
|
|
|
/**
|
|
* Formate une note pour l'affichage (2 décimales).
|
|
*/
|
|
export function formatGrade(grade: number | null): string {
|
|
if (grade === null) return "—";
|
|
return grade.toFixed(2);
|
|
}
|