const { pool } = require('../database') const { matiereSysteme } = require('../function/System') /** * Function to insert notes into the database * @param {Object} formData - The form data containing subject names and values * @param {number} etudiant_id - The student ID * @param {string} etudiant_niveau - The student level * @returns {Promise} - Promise resolving to the database response or an error */ async function insertNote(etudiant_id, etudiant_niveau, mention_id, formData, annee_scolaire) { const matiere_id = Object.keys(formData) const values = Object.values(formData) const insertNoteSQL = ` INSERT INTO notes (etudiant_id, matiere_id, etudiant_niveau, mention_id, note, annee_scolaire) VALUES (?, ?, ?, ?, ?, ?) ` const insertRepechSQL = ` INSERT INTO notesrepech (etudiant_id, matiere_id, etudiant_niveau, mention_id, note, annee_scolaire) VALUES (?, ?, ?, ?, ?, ?) ` const connection = await pool.getConnection() let newMatiereId = [] try { await connection.beginTransaction() // Insert into notes table for (let j = 0; j < matiere_id.length; j++) { const noteValue = parseFloat(values[j].replace(',', '.')) || 0 if (noteValue < 10) { newMatiereId.push(matiere_id[j]) } await connection.execute(insertNoteSQL, [ etudiant_id, matiere_id[j], etudiant_niveau, mention_id, noteValue, annee_scolaire ]) } // Insert into notesrepech with note = 0 for (let j = 0; j < newMatiereId.length; j++) { await connection.execute(insertRepechSQL, [ etudiant_id, newMatiereId[j], etudiant_niveau, mention_id, 0, annee_scolaire ]) } await connection.commit() return { success: true } } catch (error) { await connection.rollback() console.error('Error inserting notes:', error) return { error: error.message } } finally { connection.release() } } /** * * @returns promise */ async function getNoteOnline() { const sql = 'SELECT notes.* FROM notes ' try { let [rows] = await pool.query(sql) return rows } catch (error) { return error } } /** * * @returns promise */ async function getNote(id, niveau) { let connection try { connection = await pool.getConnection() // 1. Get all notes joined with matieres const [response] = await connection.execute( ` SELECT notes.*, matieres.* FROM notes JOIN matieres ON notes.matiere_id = matieres.id WHERE notes.etudiant_id = ? AND notes.etudiant_niveau = ? `, [id, niveau] ) // 2. Optional: Build list of matiere_id (not used here but kept from original) const arrayResponseIdMatiere = response.map((note) => note.matiere_id) // 3. Same query again (as in your original) — this is redundant unless changed const [response2] = await connection.execute( ` SELECT notes.*, matieres.* FROM notes JOIN matieres ON notes.matiere_id = matieres.id WHERE notes.etudiant_id = ? AND notes.etudiant_niveau = ? `, [id, niveau] ) return response2 } catch (error) { console.error('Error in getNote:', error) return { error: error.message } } finally { if (connection) connection.release() } } /** * Verify if a student has notes * @returns {Promise} - Promise resolving to an array of notes or an empty array */ async function verifyEtudiantIfHeHasNotes() { try { // Prepare the query to filter by etudiant_id and etudiant_niveau const sql = 'SELECT DISTINCT etudiant_id, etudiant_niveau FROM notes' // Execute the query with the provided parameters const [rows] = await pool.query(sql) // Return the response return rows } catch (error) { console.error('Error verifying student notes:', error) throw error } } /** * function to show moyenne in screen * * @returns promise */ async function showMoyen(niveau, scolaire) { try { // 1. Get distinct student IDs const [etudiantWithNotes] = await pool.query( `SELECT DISTINCT etudiant_id FROM notes WHERE etudiant_niveau = ? AND annee_scolaire = ?`, [niveau, scolaire] ) let allEtudiantWithNotes = [] // 2. Prepare the second query const query2 = ` SELECT notes.*, etudiants.*, matieres.id AS matiere_id, matieres.nom AS nomMat, matieres.credit FROM notes INNER JOIN etudiants ON notes.etudiant_id = etudiants.id INNER JOIN matieres ON notes.matiere_id = matieres.id WHERE notes.etudiant_id = ? ` // 3. Loop over each student and fetch their notes for (let index = 0; index < etudiantWithNotes.length; index++) { const etudiantId = etudiantWithNotes[index].etudiant_id const [rows] = await pool.query(query2, [etudiantId]) allEtudiantWithNotes.push(rows) // push just the rows, not [rows, fields] } return allEtudiantWithNotes } catch (error) { console.error('Error in showMoyen:', error) return { error: error.message } } } /** * function used when updating note * @param {Object} formData - The form data containing subject names and values * @param {string} niveau - The student level * @returns {Promise} - Promise resolving to the database response or an error */ async function updateNote(formData, niveau, id, mention_id, annee_scolaire) { const matiere_id = Object.keys(formData) const values = Object.values(formData) try { let response for (let index = 0; index < matiere_id.length; index++) { let data = values[index] // Convert string to float safely if (typeof data === 'string') { data = parseFloat(data.replace(',', '.')) } else { data = parseFloat(String(data).replace(',', '.')) } // 1. Check if already in notesrepech const [check] = await pool.query( 'SELECT * FROM notesrepech WHERE etudiant_id = ? AND matiere_id = ? AND etudiant_niveau = ?', [id, matiere_id[index], niveau] ) if (data < 10) { // 2. If not already present, insert into notesrepech if (check.length === 0) { await pool.query( `INSERT INTO notesrepech (etudiant_id, matiere_id, etudiant_niveau, mention_id, note, annee_scolaire) VALUES (?, ?, ?, ?, ?, ?)`, [id, matiere_id[index], niveau, mention_id, 0, annee_scolaire] ) } // 3. Update main note anyway ;[response] = await pool.query( 'UPDATE notes SET note = ? WHERE etudiant_id = ? AND etudiant_niveau = ? AND matiere_id = ?', [data, id, niveau, matiere_id[index]] ) } else { // 4. Remove from notesrepech if note >= 10 await pool.query( 'DELETE FROM notesrepech WHERE etudiant_id = ? AND etudiant_niveau = ? AND matiere_id = ?', [id, niveau, matiere_id[index]] ) // 5. Update main note ;[response] = await pool.query( 'UPDATE notes SET note = ? WHERE etudiant_id = ? AND etudiant_niveau = ? AND matiere_id = ?', [data, id, niveau, matiere_id[index]] ) } } return response } catch (error) { console.error('Error updating note:', error) return error } } async function blockShowMoyene() { const query = 'SELECT DISTINCT etudiant_niveau, annee_scolaire FROM notes ORDER BY annee_scolaire DESC' const queryMention = 'SELECT * FROM mentions' const query2 = ` SELECT notes.*, etudiants.id AS etudiantsId, etudiants.mention_id AS mentionId, etudiants.niveau, matieres.* FROM notes INNER JOIN etudiants ON notes.etudiant_id = etudiants.id INNER JOIN matieres ON notes.matiere_id = matieres.id WHERE notes.etudiant_niveau = ? AND notes.annee_scolaire = ? ` try { const [response] = await pool.query(query) const [mention] = await pool.query(queryMention) const niveau = response.map((item) => item.etudiant_niveau) const annee_scolaire = response.map((item) => item.annee_scolaire) let allData = [] for (let i = 0; i < niveau.length; i++) { const [rows] = await pool.query(query2, [niveau[i], annee_scolaire[i]]) allData.push(rows) } return { response, allData, mention } } catch (error) { console.error(error) return error } } /** * get all note with matiere for single student * @param {*} id * @param {*} niveau * @param {*} annee_scolaire * @returns promise */ async function getMatiereAndNote(id, niveau, annee_scolaire) { const query = ` SELECT * FROM notes INNER JOIN matieres ON notes.matiere_id = matieres.id WHERE notes.etudiant_id = ? AND notes.etudiant_niveau = ? AND notes.annee_scolaire = ? ` try { const [rows] = await pool.query(query, [id, niveau, annee_scolaire]) return rows } catch (error) { return error } } async function getNotesWithRepechToDisplay(id, anneescolaire, niveau) { try { // Query for normal notes const [noteNormal] = await pool.query( `SELECT * FROM notes INNER JOIN matieres ON notes.matiere_id = matieres.id WHERE notes.etudiant_id = ? AND notes.annee_scolaire = ? AND notes.etudiant_niveau = ?`, [id, anneescolaire, niveau] ) // Query for repechage notes const [noteRepech] = await pool.query( `SELECT * FROM notesrepech INNER JOIN matieres ON notesrepech.matiere_id = matieres.id WHERE notesrepech.etudiant_id = ? AND notesrepech.annee_scolaire = ? AND notesrepech.etudiant_niveau = ?`, [id, anneescolaire, niveau] ) // Query for semesters and matiere-semestre mapping const [semestre] = await pool.query( `SELECT * FROM semestres INNER JOIN matiere_semestre ON semestres.id = matiere_semestre.semestre_id` ) return { noteNormal, noteRepech, semestre } } catch (error) { return error } } module.exports = { insertNote, getNote, showMoyen, getNoteOnline, verifyEtudiantIfHeHasNotes, updateNote, blockShowMoyene, getMatiereAndNote, getNotesWithRepechToDisplay }