Checkpoint: Ajout de la fonctionnalité d'import Excel pour créer des formations et séquences en masse. Inclut le template Excel, la logique backend de parsing et validation, l'interface frontend avec prévisualisation, et la documentation utilisateur complète.
This commit is contained in:
@@ -10,6 +10,7 @@ import { generateAnalyticsExcel, generateAnalyticsPDF } from "./analyticsExportS
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { sendInscriptionConfirmation, sendGroupEmail } from "./emailService";
|
||||
import { generateExcelExport, generatePDFExport, generateFeuillePresence } from "./exportService";
|
||||
import { parseExcelFile, validateImportData, importToDatabase } from "./importExcel";
|
||||
|
||||
// Procédure admin uniquement
|
||||
const adminProcedure = protectedProcedure.use(({ ctx, next }) => {
|
||||
@@ -72,6 +73,68 @@ export const appRouter = router({
|
||||
await db.deleteFormation(input.id);
|
||||
return { success: true };
|
||||
}),
|
||||
|
||||
importExcel: adminProcedure.input(z.object({
|
||||
fileBase64: z.string(),
|
||||
})).mutation(async ({ input }) => {
|
||||
try {
|
||||
// Décoder le fichier base64
|
||||
const buffer = Buffer.from(input.fileBase64, 'base64');
|
||||
|
||||
// Parser le fichier Excel
|
||||
const { formations, sequences } = parseExcelFile(buffer);
|
||||
|
||||
// Valider les données
|
||||
const validation = validateImportData(formations, sequences);
|
||||
|
||||
if (!validation.valid) {
|
||||
return {
|
||||
success: false,
|
||||
formationsCreated: 0,
|
||||
sequencesCreated: 0,
|
||||
errors: validation.errors,
|
||||
warnings: validation.warnings,
|
||||
};
|
||||
}
|
||||
|
||||
// Importer dans la base de données
|
||||
const result = await importToDatabase(formations, sequences);
|
||||
|
||||
return {
|
||||
...result,
|
||||
warnings: [...validation.warnings, ...result.warnings],
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
success: false,
|
||||
formationsCreated: 0,
|
||||
sequencesCreated: 0,
|
||||
errors: [`Erreur lors du traitement du fichier: ${error.message}`],
|
||||
warnings: [],
|
||||
};
|
||||
}
|
||||
}),
|
||||
|
||||
previewExcel: adminProcedure.input(z.object({
|
||||
fileBase64: z.string(),
|
||||
})).mutation(async ({ input }) => {
|
||||
try {
|
||||
const buffer = Buffer.from(input.fileBase64, 'base64');
|
||||
const { formations, sequences } = parseExcelFile(buffer);
|
||||
const validation = validateImportData(formations, sequences);
|
||||
|
||||
return {
|
||||
formations,
|
||||
sequences,
|
||||
validation,
|
||||
};
|
||||
} catch (error: any) {
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: `Erreur lors de la lecture du fichier: ${error.message}`,
|
||||
});
|
||||
}
|
||||
}),
|
||||
}),
|
||||
|
||||
// ===== APPRENANTS =====
|
||||
|
||||
Reference in New Issue
Block a user