import type { Request, Response, NextFunction } from 'express'; import * as dashboardService from '../services/dashboard.service.js'; import { generarAlertasAutomaticas } from '../services/alertas-auto.service.js'; import { getAlertasManualesPendientes } from '../services/alertas-manuales.service.js'; import { AppError } from '../middlewares/error.middleware.js'; function getDefaultRange() { const now = new Date(); const y = now.getFullYear(); const m = now.getMonth() + 1; const lastDay = new Date(y, m, 0).getDate(); return { fechaInicio: `${y}-${String(m).padStart(2, '0')}-01`, fechaFin: `${y}-${String(m).padStart(2, '0')}-${String(lastDay).padStart(2, '0')}`, año: y, mes: m, }; } function parseConciliacion(req: Request): boolean { return req.query.conciliacion === 'true' || req.query.conciliacion === '1'; } export async function getKpis(req: Request, res: Response, next: NextFunction) { try { if (!req.tenantPool) { return next(new AppError(400, 'Tenant no configurado')); } const defaults = getDefaultRange(); const fechaInicio = (req.query.fechaInicio as string) || defaults.fechaInicio; const fechaFin = (req.query.fechaFin as string) || defaults.fechaFin; const conciliacion = parseConciliacion(req); const contribuyenteId = (req.query.contribuyenteId as string) || null; const tenantId = req.viewingTenantId || req.user!.tenantId; const kpis = await dashboardService.getKpis(req.tenantPool, fechaInicio, fechaFin, tenantId, conciliacion, contribuyenteId); res.json(kpis); } catch (error) { next(error); } } export async function getIngresosEgresos(req: Request, res: Response, next: NextFunction) { try { if (!req.tenantPool) { return next(new AppError(400, 'Tenant no configurado')); } const año = parseInt(req.query.año as string) || new Date().getFullYear(); const conciliacion = parseConciliacion(req); const contribuyenteId = (req.query.contribuyenteId as string) || null; const tenantId = req.viewingTenantId || req.user!.tenantId; const data = await dashboardService.getIngresosEgresos(req.tenantPool, año, tenantId, conciliacion, contribuyenteId); res.json(data); } catch (error) { next(error); } } export async function getRegimenesDelPeriodo(req: Request, res: Response, next: NextFunction) { try { if (!req.tenantPool) { return next(new AppError(400, 'Tenant no configurado')); } const defaults = getDefaultRange(); const fechaInicio = (req.query.fechaInicio as string) || defaults.fechaInicio; const fechaFin = (req.query.fechaFin as string) || defaults.fechaFin; const conciliacion = parseConciliacion(req); const contribuyenteId = (req.query.contribuyenteId as string) || null; const tenantId = req.viewingTenantId || req.user?.tenantId; const regimenes = await dashboardService.getRegimenesDelPeriodo(req.tenantPool, fechaInicio, fechaFin, conciliacion, contribuyenteId, tenantId); res.json(regimenes); } catch (error) { next(error); } } export async function getAlertas(req: Request, res: Response, next: NextFunction) { try { if (!req.tenantPool) { return next(new AppError(400, 'Tenant no configurado')); } const limit = parseInt(req.query.limit as string) || 5; const tenantId = req.viewingTenantId || req.user!.tenantId; const contribuyenteId = (req.query.contribuyenteId as string) || null; // Combinar alertas persistidas (manuales, filtered by role) + automáticas (calculadas) const [manuales, automaticas] = await Promise.all([ getAlertasManualesPendientes(req.tenantPool, contribuyenteId, req.user!.userId, req.user!.role), generarAlertasAutomaticas(req.tenantPool, tenantId, contribuyenteId), ]); // Unir, ordenar por prioridad, y limitar const prioridadOrden: Record = { alta: 1, media: 2, baja: 3 }; const alertas = [...automaticas, ...manuales] .sort((a, b) => (prioridadOrden[a.prioridad] || 3) - (prioridadOrden[b.prioridad] || 3)) .slice(0, limit); res.json(alertas); } catch (error) { next(error); } }