test : changed test format + added playwright support
Check Deno code / Check Deno code (pull_request) Has been cancelled
Tests / Unit tests (pull_request) Has been cancelled
Tests / Integration tests (pull_request) Has been cancelled
Check Deno code / Check Deno code (push) Has been cancelled
Tests / Unit tests (push) Has been cancelled
Tests / Integration tests (push) Has been cancelled
Check Deno code / Check Deno code (pull_request) Has been cancelled
Tests / Unit tests (pull_request) Has been cancelled
Tests / Integration tests (pull_request) Has been cancelled
Check Deno code / Check Deno code (push) Has been cancelled
Tests / Unit tests (push) Has been cancelled
Tests / Integration tests (push) Has been cancelled
This commit was merged in pull request #153.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
Reference in New Issue
Block a user