You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

312 lines
9.9 KiB

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()
const today = dayjs().format('YYYY-MM-DD')
// 1. Récupérer toutes les années scolaires triées par debut
const [allYears] = await connection.query(
'SELECT * FROM anneescolaire ORDER BY debut ASC'
)
if (allYears.length < 2) {
await connection.rollback()
connection.release()
return { message: 'Pas assez d\'années scolaires configurées.' }
}
// 2. Seuils de notes
const [noteSystemRows] = await connection.query('SELECT * FROM notesystems LIMIT 1')
const noteSystem = noteSystemRows[0]
let totalProcessed = 0
// 3. Pour chaque paire d'années consécutives (annéeN → annéeN+1)
for (let i = 0; i < allYears.length - 1; i++) {
const prevYear = allYears[i]
const nextYear = allYears[i + 1]
// Traiter uniquement si l'année suivante a déjà commencé
if (nextYear.debut > today) continue
// Trouver les étudiants inscrits en annéeN mais PAS encore en annéeN+1
const [studentsToProcess] = await connection.query(
`SELECT i.*, e.nom, e.prenom, e.photos
FROM inscriptions i
JOIN etudiants e ON i.etudiant_id = e.id
WHERE i.annee_scolaire_id = ?
AND i.etudiant_id NOT IN (
SELECT etudiant_id FROM inscriptions WHERE annee_scolaire_id = ?
)`,
[prevYear.id, nextYear.id]
)
if (studentsToProcess.length === 0) continue
for (const inscription of studentsToProcess) {
const inscStatus = parseInt(inscription.status)
// Renvoyé → pas de nouvelle inscription
if (inscStatus === 4) continue
let newNiveau, newStatus
// Vérifier si l'étudiant a des notes pour l'année précédente
const [notesRows] = await connection.query(
`SELECT n.note, n.matiere_id, m.credit
FROM notes n
JOIN matieres m ON n.matiere_id = m.id
WHERE n.etudiant_id = ? AND n.annee_scolaire = ?`,
[inscription.etudiant_id, prevYear.code]
)
if (notesRows.length > 0) {
// Calculer la moyenne avec prise en compte du rattrapage
const [repechRows] = await connection.query(
`SELECT n.note, n.matiere_id, m.credit
FROM notesrepech n
JOIN matieres m ON n.matiere_id = m.id
WHERE n.etudiant_id = ? AND n.annee_scolaire = ?`,
[inscription.etudiant_id, prevYear.code]
)
let total = 0
let totalCredit = 0
for (const note of notesRows) {
const repNote = repechRows.find(r => r.matiere_id === note.matiere_id)
const noteToUse = compareSessionNotes(note.note, checkNull(repNote))
total += (noteToUse ?? 0) * note.credit
totalCredit += note.credit
}
const moyenne = totalCredit > 0 ? total / totalCredit : 0
if (moyenne >= noteSystem.admis) {
newNiveau = nextLevel(inscription.niveau)
newStatus = 2 // Passant
} else if (moyenne >= noteSystem.renvoyer) {
newNiveau = inscription.niveau
newStatus = 3 // Redoublant
} else {
newNiveau = inscription.niveau
newStatus = 4 // Renvoyé
continue // Pas de nouvelle inscription pour les renvoyés
}
} else {
// Pas de notes → utiliser le statut de l'inscription
if (inscStatus === 2) {
// Passant → niveau supérieur
newNiveau = nextLevel(inscription.niveau)
newStatus = 2
} else {
// Redoublant, Nouveau, Ancien → même niveau
newNiveau = inscription.niveau
newStatus = 3
}
}
// Créer l'inscription pour l'année suivante
await connection.query(
`INSERT INTO inscriptions
(etudiant_id, annee_scolaire_id, niveau, mention_id, parcours, status, num_inscription)
VALUES (?, ?, ?, ?, ?, ?, ?)`,
[
inscription.etudiant_id, nextYear.id, newNiveau,
inscription.mention_id, inscription.parcours, newStatus,
inscription.num_inscription
]
)
// Pour les redoublants, copier les notes de l'année précédente (seulement si pas encore copiées)
if (newStatus === 3) {
const [existingNotes] = await connection.query(
`SELECT COUNT(*) as cnt FROM notes WHERE etudiant_id = ? AND annee_scolaire = ?`,
[inscription.etudiant_id, nextYear.code]
)
if (existingNotes[0].cnt === 0) {
await connection.query(
`INSERT INTO notes (etudiant_id, matiere_id, etudiant_niveau, mention_id, note, annee_scolaire)
SELECT etudiant_id, matiere_id, etudiant_niveau, mention_id, note, ?
FROM notes
WHERE etudiant_id = ? AND annee_scolaire = ?`,
[nextYear.code, inscription.etudiant_id, prevYear.code]
)
await connection.query(
`INSERT INTO notesrepech (etudiant_id, matiere_id, etudiant_niveau, mention_id, note, annee_scolaire)
SELECT etudiant_id, matiere_id, etudiant_niveau, mention_id, note, ?
FROM notesrepech
WHERE etudiant_id = ? AND annee_scolaire = ?`,
[nextYear.code, inscription.etudiant_id, prevYear.code]
)
}
}
totalProcessed++
}
}
// 4. Mettre à jour traitmentsystem (nettoyage)
await connection.query(
'UPDATE traitmentsystem SET is_finished = 1 WHERE is_finished = 0'
)
await connection.commit()
connection.release()
console.log(`✅ updateStudents: ${totalProcessed} inscription(s) créée(s).`)
return { success: true, message: `${totalProcessed} inscription(s) créée(s).`, totalProcessed }
} catch (error) {
await connection.rollback()
connection.release()
console.error('❌ updateStudents 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[0]
} 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
}