Skip to main content

Reportes

Los reportes de la consola web son Excel generados por un stored procedure. La buena noticia: agregar uno no requiere tocar el frontend.

Cómo funciona

  1. Una fila en configuration.REPORTS con name, description, icon y storeProcedureName (esa columna no se serializa hacia afuera).
  2. El SP vive en migrations/finances/store/ y recibe siempre la misma firma: CALL <sp>(startDate, endDate, userId).
  3. Una fila en configuration.REPORTUSERS por cada usuario que puede verlo.
  4. services/v2/ReportService.ts resuelve, valida, ejecuta, arma el Excel y registra la ejecución.

Reportes actuales: sp_report_deliverys, sp_view_stocks_report, sp_view_stocks_serial_report.

Checklist para agregar uno

  • Escribir el SP con la firma (IN startDate DATETIME, IN endDate DATETIME, IN userId INT).
  • INSERT en REPORTS con el storeProcedureName.
  • INSERT en REPORTUSERS para los usuarios que lo necesitan.
  • Nada en el front.

Los dos gotchas que ya rompieron todo

Un reporte sin fila en REPORTUSERS es invisible

No hay error ni log: get-types simplemente no lo lista, y find responde "el usuario no tiene acceso al reporte".

Si te dicen "el reporte no aparece", empezá por acá antes de mirar el SP.

Las fechas ISO del front rompían TODOS los reportes

El front manda Date.toISOString() ("2026-07-01T03:00:00.000Z"), y los parámetros de los SPs están declarados DATETIME. Con STRICT_TRANS_TABLES, MySQL rechaza el sufijo Z al asignar el parámetro — o sea que el CALL explota antes de ejecutar el cuerpo, incluso en los SPs que ni miran las fechas.

ReportService.normalizeDateParam() lo arregla: pasa la fecha por getMoment() y la reformatea; si no parsea, devuelve un mensaje claro en vez de dejar que MySQL falle con un error opaco.

No bypasees ese normalizador.

Como bonus del segundo caso: CustomResponse.error(e) no llena message, así que ReportController tiene un helper privado failure() que preserva el motivo real de MySQL/TypeORM (por ejemplo Incorrect datetime value: …). Sin eso, el front recibía un body sin nada que mostrar e inventaba un "Error de conexión" genérico.

No confundir con el otro ReportService

services/v1/ReportService.ts es otra cosa: un cliente axios (con cookie jar) contra un servicio externo de reportes (REPORT_API_URL) que devuelve el PDF del remito. Nada que ver con el Excel.

Power BI

La pantalla de reportes también embebe dashboards de Power BI. La configuración vive en powerBiTenantId (front) y POWER_BI_CLIENT_SECRET / CLIENT_ID / TENANT_ID (backend).