Checkpoint: Module Ventilation FreePro complet : import Excel FreePro, transformation automatique (script/TTC/type XOAUTH2), tableau de ventilation par structure+type, historique par mois, export PDF. Menu Ventilations ajouté dans la navigation.

This commit is contained in:
Manus
2026-06-05 08:02:29 -04:00
parent 4ef130f21d
commit 7f56fa7045
13 changed files with 3123 additions and 3 deletions

View File

@@ -944,3 +944,70 @@ export async function updateBapHistoryPdfUrl(id: number, pdfUrl: string): Promis
if (!db) return;
await db.update(bapHistory).set({ pdfUrl }).where(eq(bapHistory.id, id));
}
// ============= FREEPRO VENTILATION OPERATIONS =============
import {
freeproImports,
InsertFreeproImport,
FreeproImport,
freeproVentilationLines,
InsertFreeproVentilationLine,
FreeproVentilationLine,
} from "../drizzle/schema";
/** Crée un import FreePro et ses lignes de ventilation */
export async function createFreeproImport(
data: InsertFreeproImport,
lines: Omit<InsertFreeproVentilationLine, "importId">[]
): Promise<number> {
const db = await getDb();
if (!db) throw new Error("Database not available");
const result = await db.insert(freeproImports).values(data);
const importId = (result as unknown as { insertId: number }).insertId;
if (lines.length > 0) {
await db.insert(freeproVentilationLines).values(
lines.map((l) => ({ ...l, importId }))
);
}
return importId;
}
/** Récupère tous les imports FreePro d'un utilisateur (sans les lignes) */
export async function getFreeproImportsByUser(userId: number): Promise<FreeproImport[]> {
const db = await getDb();
if (!db) return [];
return db
.select()
.from(freeproImports)
.where(eq(freeproImports.userId, userId))
.orderBy(desc(freeproImports.annee), desc(freeproImports.mois));
}
/** Récupère un import FreePro avec ses lignes */
export async function getFreeproImportWithLines(
importId: number
): Promise<{ import: FreeproImport; lines: FreeproVentilationLine[] } | null> {
const db = await getDb();
if (!db) return null;
const imports = await db
.select()
.from(freeproImports)
.where(eq(freeproImports.id, importId))
.limit(1);
if (!imports[0]) return null;
const lines = await db
.select()
.from(freeproVentilationLines)
.where(eq(freeproVentilationLines.importId, importId))
.orderBy(freeproVentilationLines.structure, freeproVentilationLines.type);
return { import: imports[0], lines };
}
/** Supprime un import FreePro et ses lignes */
export async function deleteFreeproImport(importId: number): Promise<void> {
const db = await getDb();
if (!db) return;
await db.delete(freeproVentilationLines).where(eq(freeproVentilationLines.importId, importId));
await db.delete(freeproImports).where(eq(freeproImports.id, importId));
}