const fs = require('fs') const path = require('path') const XLSX = require('xlsx') const { getCompressedDefaultImage } = require('../function/GetImageDefaault') const { parse } = require('csv-parse/sync') const { pool } = require('../database') const dayjs = require('dayjs') // const { getStatusMention } = require('../function/Helper') const customParseFormat = require('dayjs/plugin/customParseFormat') // const { log } = require('console') // const customParseFormatt = require('dayjs/plu') dayjs.extend(customParseFormat) // Function to convert any date format to 'YYYY-MM-DD' function convertToISODate(input) { // Try parsing the date with different formats const formats = [ 'DD/MM/YYYY', 'MM/DD/YYYY', 'YYYY-MM-DD', 'DD-MM-YYYY', 'MM-DD-YYYY', 'DD/MM/YY', 'MM/DD/YY', 'DD-MMM-YY' ] const parsedDate = dayjs(input, formats, true) // Strict parsing to ensure formats are matched correctly // If the date is valid, return it in the YYYY-MM-DD format if (parsedDate.isValid()) { return parsedDate.format('YYYY-MM-DD') } // Handle cases like "Vers 2000" const versMatch = typeof input === 'string' && input.match(/vers\s*(\d{4})/i); if (versMatch) { return `${versMatch[1]}-01-01`; // Return in ISO format } function excelDateToJSDate(serial) { const utc_days = Math.floor(serial - 25569); // days from Jan 1, 1970 const utc_value = utc_days * 86400; // seconds in a day return new Date(utc_value * 1000); // JS Date uses milliseconds } let jsDate = excelDateToJSDate(input); // If the input is not a valid date, return 'Invalid Date' return jsDate } async function insertMultipleEtudiants(etudiants) { const sql = ` INSERT INTO etudiants ( nom, prenom, photos, date_de_naissances, niveau, annee_scolaire, status, mention_id, num_inscription, sexe, cin, date_delivrance, nationalite, annee_bacc, serie, boursier, domaine, contact, parcours ) VALUES ? ` // Prepare values as array of arrays const values = etudiants.map((row) => [ row.nom, row.prenom, getCompressedDefaultImage(), // photos (you can adjust this if needed) convertToISODate(row.date_naissance), row.niveau, row.annee_scolaire, row.code_redoublement, row.mention, row.num_inscription, row.sexe, row.cin, convertToISODate(row.date_de_delivrance), row.nationaliter, row.annee_baccalaureat, row.serie, row.boursier, row.domaine, row.contact, null // parcours ]) try { const [result] = await pool.query(sql, [values]) return { success: true, affectedRows: result.affectedRows, insertId: result.insertId } } catch (error) { return { success: false, error: error.message } } } /** * Function to import data from XLSX or CSV file into SQLite database * @param {string} filePath - Path to the file (either .xlsx or .csv) */ async function importFileToDatabase(filePath) { const fileExtension = path.extname(filePath).toLowerCase() // Determine the file type and parse accordingly let records if (fileExtension === '.xlsx') { // Read and parse XLSX file const workbook = XLSX.readFile(filePath) const worksheet = workbook.Sheets[workbook.SheetNames[0]] // Assuming data is in the first sheet records = XLSX.utils.sheet_to_json(worksheet, { defval: '', raw: false }) } else if (fileExtension === '.csv') { // Read and parse CSV file const fileContent = fs.readFileSync(filePath, 'utf8') records = parse(fileContent, { columns: true, skip_empty_lines: true }) } else { console.error('Unsupported file format. Only .xlsx and .csv are allowed.') return } // ✅ Count number of data rows const numberOfLines = records.length console.log(`Number of data rows: ${numberOfLines}`) try { let error = true let message = '' // Vérifier les données en une seule boucle let oldNum = '' for (const row of records) { if ( !row.nom || // !row.prenom || !row.date_naissance || !row.niveau || !row.annee_scolaire || !row.mention || !row.num_inscription || !row.nationaliter || !row.sexe || // !row.cin || // !row.date_de_delivrance || !row.annee_baccalaureat || !row.serie || !row.code_redoublement || !row.boursier || !row.domaine // || // !row.contact ) { if (!row.nom) { message = "Le champ 'nom' est inconnu" } // else if (!row.prenom) { // message = "Le champ 'prenom' est inconnu" // } else if (!row.date_naissance) { message = "Le champ 'date_naissance' est inconnu" } else if (!row.niveau) { message = "Le champ 'niveau' est inconnu" } else if (!row.annee_scolaire) { message = "Le champ 'annee_scolaire' est inconnu" } else if (!row.mention) { message = "Le champ 'mention' est inconnu" } else if (!row.num_inscription) { message = "Le champ 'num_inscription' est inconnu" } else if (!row.nationaliter) { message = "Le champ 'nationaliter' est inconnu" } else if (!row.sexe) { message = "Le champ 'sexe' est inconnu" } // else if (!row.cin) { // message = "Le champ 'cin' est inconnu" // } else if (!row.date_de_delivrance) { // message = "Le champ 'date_de_delivrance' est inconnu" // } else if (!row.annee_baccalaureat) { message = "Le champ 'annee_baccalaureat' est inconnu" } else if (!row.serie) { message = "Le champ 'serie' est inconnu" } else if (!row.code_redoublement) { message = "Le champ 'code_redoublement' est inconnu" } else if (!row.boursier) { message = "Le champ 'boursier' est inconnu" } else if (!row.domaine) { message = "Le champ 'domaine' est inconnu" } // else if (!row.contact) { // message = "Le champ 'contact' est inconnu" // } error = false break } } const query = 'SELECT * FROM mentions' const [rows] = await pool.query(query) const MentionList = rows console.log(MentionList) if (error !== false) { let newReccord = [] // Utiliser transaction pour éviter une latence si l'insertion dépasse 100 for (const row of records) { // Convert row.mention to uppercase and compare with ListMention.nom and ListMention.uniter (also converted to uppercase) const matchedMention = MentionList.find( (mention) => mention.nom.toUpperCase() === row.mention.toUpperCase() || mention.uniter.toUpperCase() === row.mention.toUpperCase() ) // If a match is found, update row.mention with ListMention.id if (matchedMention) { row.mention = matchedMention.id } const query = 'SELECT * FROM status' let [rows] = await pool.query(query) let response = rows let statutCode for (let index = 0; index < response.length; index++) { let nom = response[index].nom let nomLower = nom.toLowerCase() // Correct method let find1 = row.code_redoublement.slice(0, 1) let find2 = row.code_redoublement.slice(0, 3) if (nomLower.slice(0, 1) == find1.toLowerCase()) { statutCode = response[index].id } else if (nomLower.slice(0, 3) == find2.toLowerCase()) { statutCode = response[index].id } } row.code_redoublement = statutCode row.num_inscription = row.num_inscription.toString() try { let compare = row.num_inscription if (compare == oldNum) { row.num_inscription = String(row.num_inscription) } console.log(row.code_redoublement) newReccord.push(row) oldNum = compare } catch (error) { console.log(error) } } console.log(insertMultipleEtudiants(newReccord)) } return { error, message } } catch (error) { console.error('Error inserting record:', error) return { error: 'error' } } } module.exports = { importFileToDatabase }