import { eq, and, sql } from "drizzle-orm"; import { presences, inscriptions, datesFormation, sequences, apprenants } from "../drizzle/schema"; import { getDb } from "./db"; /** * Valider la présence d'un apprenant (par QR code ou manuellement) */ export async function validerPresence(params: { inscriptionId: number; dateFormationId: number; periode: "matin" | "apres_midi"; modeValidation: "qrcode" | "manuel"; validateurId?: number; commentaire?: string; signatureUrl?: string; signatureS3Key?: string; }) { const db = await getDb(); if (!db) throw new Error("Database not available"); // Vérifier si la présence existe déjà pour cette période const presenceExistante = await db .select() .from(presences) .where( and( eq(presences.inscriptionId, params.inscriptionId), eq(presences.dateFormationId, params.dateFormationId), sql`${presences.periode} = ${params.periode}` ) ); if (presenceExistante.length > 0) { throw new Error(`Présence déjà validée pour ${params.periode === 'matin' ? 'le matin' : 'l\'après-midi'}`); } // Créer la présence await db.insert(presences).values({ inscriptionId: params.inscriptionId, dateFormationId: params.dateFormationId, periode: params.periode, heurePresence: new Date(), modeValidation: params.modeValidation, validateurId: params.validateurId, commentaire: params.commentaire, signatureUrl: params.signatureUrl, signatureS3Key: params.signatureS3Key, dateSigned: params.signatureUrl ? new Date() : undefined, }); return { success: true }; } /** * Récupérer toutes les présences pour une séquence */ export async function getPresencesBySequence(sequenceId: number) { const db = await getDb(); if (!db) throw new Error("Database not available"); const result = await db .select({ presenceId: presences.id, inscriptionId: presences.inscriptionId, dateFormationId: presences.dateFormationId, periode: presences.periode, heurePresence: presences.heurePresence, modeValidation: presences.modeValidation, validateurId: presences.validateurId, commentaire: presences.commentaire, signatureUrl: presences.signatureUrl, signatureS3Key: presences.signatureS3Key, dateSigned: presences.dateSigned, apprenantId: apprenants.id, apprenantNom: apprenants.nom, apprenantPrenom: apprenants.prenom, apprenantEmail: apprenants.email, dateDebut: datesFormation.dateDebut, dateFin: datesFormation.dateFin, }) .from(presences) .innerJoin(inscriptions, eq(presences.inscriptionId, inscriptions.id)) .innerJoin(apprenants, eq(inscriptions.apprenantId, apprenants.id)) .innerJoin(datesFormation, eq(presences.dateFormationId, datesFormation.id)) .where(eq(datesFormation.sequenceId, sequenceId)); return result; } /** * Récupérer les présences pour une inscription spécifique */ export async function getPresencesByInscription(inscriptionId: number) { const db = await getDb(); if (!db) throw new Error("Database not available"); const result = await db .select({ presenceId: presences.id, dateFormationId: presences.dateFormationId, periode: presences.periode, heurePresence: presences.heurePresence, modeValidation: presences.modeValidation, validateurId: presences.validateurId, commentaire: presences.commentaire, signatureUrl: presences.signatureUrl, signatureS3Key: presences.signatureS3Key, dateSigned: presences.dateSigned, dateDebut: datesFormation.dateDebut, dateFin: datesFormation.dateFin, }) .from(presences) .innerJoin(datesFormation, eq(presences.dateFormationId, datesFormation.id)) .where(eq(presences.inscriptionId, inscriptionId)); return result; } /** * Vérifier si toutes les présences sont validées pour une inscription */ export async function checkAllPresencesValidated(inscriptionId: number): Promise { const db = await getDb(); if (!db) throw new Error("Database not available"); // Récupérer l'inscription avec la séquence const inscription = await db .select({ sequenceId: inscriptions.sequenceId, }) .from(inscriptions) .where(eq(inscriptions.id, inscriptionId)) .limit(1); if (inscription.length === 0) { throw new Error("Inscription not found"); } // Compter le nombre de dates de formation pour cette séquence const datesCount = await db .select({ count: datesFormation.id }) .from(datesFormation) .where(eq(datesFormation.sequenceId, inscription[0].sequenceId)); // Compter le nombre de présences validées pour cette inscription const presencesCount = await db .select({ count: presences.id }) .from(presences) .where(eq(presences.inscriptionId, inscriptionId)); return presencesCount.length === datesCount.length; } /** * Supprimer une présence */ export async function supprimerPresence(presenceId: number) { const db = await getDb(); if (!db) throw new Error("Database not available"); await db.delete(presences).where(eq(presences.id, presenceId)); return { success: true }; }