const { pool } = require('../database') const dayjs = require('dayjs') async function updateCurrentYears() { const fullDate = dayjs().format('YYYY-MM-DD') // Clear current year flag const clearCurrent = 'UPDATE anneescolaire SET is_Current = 0 WHERE id > 0' pool.query(clearCurrent) // Set the new current year const updateCurrent = ` UPDATE anneescolaire SET is_Current = 1 WHERE ? >= debut AND ? <= fin ` // console.log(); pool.query(updateCurrent, [fullDate, fullDate]) // Check if the update was successful const sql = ` SELECT * FROM anneescolaire WHERE ? >= debut AND ? <= fin ` const [rows] = await pool.query(sql, [fullDate, fullDate]) const check = rows[0] if (!check) return // 2. Check if already in traitmentsystem const searchSql = `SELECT * FROM traitmentsystem WHERE code = ?` const [searchRows] = await pool.query(searchSql, [check.code]) if (searchRows.length === 0) { // 3. Insert into traitmentsystem const insertSql = ` INSERT INTO traitmentsystem (code, debut, fin) VALUES (?, ?, ?) ` await pool.query(insertSql, [check.code, check.debut, check.fin]) } else { console.log('No active school year found for the current date.') } } // Helper functions (unchanged) function checkNull(params) { if (params === null || params === undefined) return null return params } function compareSessionNotes(session1, session2) { if (session2) { return session1 < session2.note ? session2.note : session1 } return session1 } function nextLevel(niveau) { const levels = ['L1', 'L2', 'L3', 'M1', 'M2', 'D1', 'D2', 'D3', 'PHD'] const idx = levels.indexOf(niveau) return idx === -1 || idx === levels.length - 1 ? niveau : levels[idx + 1] } function updateSchoolYear(year) { const [startYear, endYear] = year.split('-').map(Number) return `${startYear + 1}-${endYear + 1}` } async function updateStudents() { const connection = await pool.getConnection() try { await connection.beginTransaction() // Get unfinished years (only one record assumed) const [unfinishedYearsRows] = await connection.query( 'SELECT * FROM traitmentsystem WHERE is_finished = 0 ORDER BY id ASC LIMIT 1' ) if (unfinishedYearsRows.length === 0) { await connection.release() return { message: 'No unfinished years found.' } } const unfinishedYear = unfinishedYearsRows[0] // Get all students of that unfinished year const [allEtudiants] = await connection.query( 'SELECT * FROM etudiants WHERE annee_scolaire = ?', [unfinishedYear.code] ) // Get distinct student IDs with notes let etudiantWithNotes = [] for (const etudiant of allEtudiants) { const [results] = await connection.query( 'SELECT DISTINCT etudiant_id FROM notes WHERE etudiant_niveau = ? AND annee_scolaire = ?', [etudiant.niveau, etudiant.annee_scolaire] ) etudiantWithNotes.push(...results) } // Unique IDs const uniqueId = [ ...new Map(etudiantWithNotes.map((item) => [item.etudiant_id, item])).values() ] // Get notes details per student let allEtudiantWithNotes = [] for (const student of uniqueId) { const [rows] = await connection.query( `SELECT notes.*, etudiants.*, matieres.id, matieres.nom AS nomMat, matieres.credit FROM notes LEFT JOIN etudiants ON notes.etudiant_id = etudiants.id LEFT JOIN matieres ON notes.matiere_id = matieres.id WHERE notes.etudiant_id = ?`, [student.etudiant_id] ) allEtudiantWithNotes.push(rows) } // Get distinct student IDs with notesrepech let etudiantWithNotesRepech = [] for (const etudiant of allEtudiants) { const [results] = await connection.query( 'SELECT DISTINCT etudiant_id FROM notesrepech WHERE etudiant_niveau = ? AND annee_scolaire = ?', [etudiant.niveau, etudiant.annee_scolaire] ) etudiantWithNotesRepech.push(...results) } // Unique IDs for repech const uniqueIdRepech = [ ...new Map(etudiantWithNotesRepech.map((item) => [item.etudiant_id, item])).values() ] // Get notesrepech details per student let allEtudiantWithNotesRepech = [] for (const student of uniqueIdRepech) { const [rows] = await connection.query( `SELECT notesrepech.*, etudiants.*, matieres.id, matieres.nom AS nomMat, matieres.credit FROM notesrepech INNER JOIN etudiants ON notesrepech.etudiant_id = etudiants.id INNER JOIN matieres ON notesrepech.matiere_id = matieres.id WHERE notesrepech.etudiant_id = ?`, [student.etudiant_id] ) allEtudiantWithNotesRepech.push(rows) } // Compute averages and prepare data let dataToMap = [] for (let i = 0; i < allEtudiantWithNotes.length; i++) { const notesNormal = allEtudiantWithNotes[i] const notesRepech = allEtudiantWithNotesRepech[i] || [] let total = 0 let totalCredit = 0 let modelJson = { id: '', nom: '', prenom: '', photos: '', moyenne: '', mention: '', niveau: '', annee_scolaire: '' } for (let j = 0; j < notesNormal.length; j++) { const normalNote = notesNormal[j] modelJson.id = normalNote.etudiant_id modelJson.nom = normalNote.nom modelJson.prenom = normalNote.prenom modelJson.photos = normalNote.photos modelJson.mention = normalNote.mention_id modelJson.niveau = normalNote.niveau modelJson.annee_scolaire = normalNote.annee_scolaire // Find repech note for same matiere if exists const repechNoteObj = notesRepech.find((r) => r.matiere_id === normalNote.matiere_id) const noteToUse = compareSessionNotes(normalNote.note, checkNull(repechNoteObj)) total += (noteToUse ?? 0) * normalNote.credit totalCredit += normalNote.credit } modelJson.moyenne = (totalCredit > 0 ? total / totalCredit : 0).toFixed(2) dataToMap.push(modelJson) } // Get note system thresholds const [noteSystemRows] = await connection.query('SELECT * FROM notesystems LIMIT 1') const noteSystem = noteSystemRows[0] // Update etudiants based on moyenne for (const student of dataToMap) { let status, newNiveau, newAnnee newAnnee = updateSchoolYear(student.annee_scolaire) if (student.moyenne >= noteSystem.admis) { newNiveau = nextLevel(student.niveau) status = 2 // Passed } else if (student.moyenne >= noteSystem.redouble) { newNiveau = student.niveau status = 3 // Repeat } else { newNiveau = student.niveau status = 4 // Fail } await connection.query( 'UPDATE etudiants SET niveau = ?, annee_scolaire = ?, status = ? WHERE id = ?', [newNiveau, newAnnee, status, student.id] ) } // Mark unfinished year as finished await connection.query('UPDATE traitmentsystem SET is_finished = 1 WHERE id = ?', [ unfinishedYear.id ]) await connection.commit() connection.release() return { success: true, message: 'Students updated successfully' } } catch (error) { await connection.rollback() connection.release() console.error(error) throw error } } async function matiereSysteme(etudiant_niveau) { let systeme if (etudiant_niveau == 'L1') { systeme = ['S1', 'S2'] } else if (etudiant_niveau == 'L2') { systeme = ['S3', 'S4'] } else if (etudiant_niveau == 'L3') { systeme = ['S5', 'S6'] } else if (etudiant_niveau == 'M1') { systeme = ['S7', 'S8'] } else if (etudiant_niveau == 'M2') { systeme = ['S9', 'S10'] } else if (etudiant_niveau == 'D1') { systeme = ['S11', 'S12'] } else if (etudiant_niveau == 'D2') { systeme = ['S13', 'S14'] } else if (etudiant_niveau == 'D3') { systeme = ['S15', 'S16'] } return systeme } async function matiereSystemReverse(semestre) { if (semestre == 'S1' || semestre == 'S2') { return 'L1' } else if (semestre == 'S3' || semestre == 'S4') { return 'L2' } else if (semestre == 'S5' || semestre == 'S6') { return 'L3' } else if (semestre == 'S7' || semestre == 'S8') { return 'M1' } else if (semestre == 'S9' || semestre == 'S10') { return 'M2' } else if (semestre == 'S11' || semestre == 'S12') { return 'D1' } else if (semestre == 'S13' || semestre == 'S14') { return 'D2' } else if (semestre == 'S15' || semestre == 'S16') { return 'D3' } } async function getNessesarytable() { try { const sql = 'SELECT * FROM nessesaryTable' const [rows] = await pool.query(sql) return rows } catch (error) { return error } } async function updateNessesaryTable(id, multiplicateur) { const sql = 'UPDATE nessesaryTable SET uniter_heure = ? WHERE id = ?' try { const [result] = await pool.query(sql, [multiplicateur, id]) if (result.affectedRows === 0) { return { success: false, message: 'Année universitaire non trouvé.' } } return { success: true, message: 'Année universitaire supprimé avec succès.' } } catch (error) { return error } } module.exports = { matiereSysteme, updateCurrentYears, updateStudents, getNessesarytable, updateNessesaryTable, matiereSystemReverse }