FINORA ERP · Reference
FINORA Reportes: informe técnico
This content is not available in your language yet.
FINORA Reportes (bundle com.finora.lve.reportes, módulo REPORTES, ADR-LVE-020) es el diseñador y motor de
reportes de FINORA ERP. Un reporte es una consulta SQL de solo lectura con parámetros con nombre, más sus columnas
y, si se quiere, plantillas Excel. Al publicarlo se convierte en un proceso normal de iDempiere: tiene diálogo de
parámetros, acceso por rol, entrada de menú y endpoint REST, sin código nuevo. El modelo es el de Jmix Reports
(consulta, parámetros, plantillas; el usuario elige el formato al ejecutar) construido sobre el diccionario de
iDempiere.
Por qué no Print Format ni Jasper
Sección titulada «Por qué no Print Format ni Jasper»| Pieza del core | Qué da | Qué le falta |
|---|---|---|
| Print Format | Listados de una tabla o vista, exporta PDF y XLSX | Una consulta con joins exige crear una vista en la base de datos |
| JasperReports | Documentos de diseño fino (recibo, ARC) | Diseñar exige Jaspersoft Studio; el Excel sale «pixelado» |
| FINORA Reportes | Consulta + parámetros + columnas + plantillas desde una ventana | — |
Jasper sigue siendo la herramienta para los documentos con diseño propio (recibo de pago, comprobantes). FINORA Reportes cubre los listados y resúmenes que un administrador quiere crear y ajustar sin desarrolladores.
Arquitectura
Sección titulada «Arquitectura»Diseñador de reportes (ventana) Menú «Reportes» / proceso FVE_RPT_<código> / REST │ Publicar │ ▼ ▼ FVE_ReportDef ── FVE_ReportParam RunReport (clase genérica) ├──────── FVE_ReportColumn │ └──────── FVE_ReportTemplate (+ adjunto .xlsx) ▼ ReportEngine: valida, enlaza, ejecuta en solo lectura │ filas en streaming ┌──────────┬─────────┴──────────┬────────────┐ ▼ ▼ ▼ ▼ PDF (OpenPDF) XLSX (POI SXSSF) XLSX plantilla CSV- Sin motor nuevo. OpenPDF 1.3.39 y Apache POI 5.2.2 ya vienen con iDempiere 13 (los usa
org.adempiere.base); el bundle los toma porRequire-Bundle. - Dominio puro y probado. El lector de la consulta, los tipos, los totales, la huella y los cuatro escritores no dependen de iDempiere y tienen pruebas unitarias que releen cada PDF y cada Excel generado.
- Un solo recorrido de las filas. Los grupos, subtotales, totales y la huella SHA-256 se calculan mientras las filas pasan hacia el escritor; ninguna fila se guarda en memoria salvo en la plantilla Excel, que necesita el libro completo.
Modelo de datos
Sección titulada «Modelo de datos»Las cuatro tablas son AccessLevel 6 (System + empresa): una empresa ve los reportes del sistema de solo lectura y los suyos con permiso de escritura.
| Tabla | Columnas clave |
|---|---|
FVE_ReportDef | Value (código único por empresa, [A-Z][A-Z0-9_]{1,39}), Name, Description, Help, FVE_ReportCategory, FVE_ReportSQL, FVE_Orientation (P/L), FVE_OutputFormats (PDF,XLSX,CSV), FVE_DefaultFormat, FVE_GroupColumn, FVE_FileNamePattern, FVE_MaxRows (50 000, tope 1 000 000), AD_Process_ID |
FVE_ReportParam | ColumnName (el marcador), Name (etiqueta), FVE_ParamType (DATE, INTEGER, NUMBER, TEXT, YESNO, RECORD), AD_Table_ID, IsMandatory, IsRange, DefaultValue, SeqNo |
FVE_ReportColumn | ColumnName (alias del SELECT), Name (encabezado), FVE_ColumnType (TEXT, INTEGER, NUMBER, AMOUNT, DATE, PERCENT), IsSummarized, FVE_Width, IsDisplayed, SeqNo |
FVE_ReportTemplate | Name, FVE_TemplateType (XLSX), IsDefault, FVE_TemplateResource (bundle:<bundle>:<ruta>); sin recurso, el .xlsx adjunto |
Los códigos CATALOGO y EJECUTAR están reservados para la API. FVE_OutputFormat (lista) tiene los valores PDF,
XLSX (Excel automático), XLSXT (Excel con plantilla) y CSV; un reporte que ofrece XLSX también admite su
plantilla.
La consulta
Sección titulada «La consulta»- Una sola sentencia
SELECToWITH. Un;final se acepta; texto después de él, no. - Marcadores con nombre
:Nombre, uno por parámetro. Un parámetro con rango da:Nombrey:Nombre_To. Los del sistema::AD_Client_ID,:AD_Org_ID,:AD_User_ID,:AD_Role_IDy:Today. :AD_Client_IDes obligatorio: una consulta que no lo usa no se guarda. Así una empresa nunca ve datos de otra.- Parámetro opcional vacío = NULL tipado. El patrón es
(:X IS NULL OR col = :X). Las fechas viajan comodate, los números comonumericy los textos comovarchar, de modo que PostgreSQL resuelve el tipo incluso en:X IS NULL. - El lector respeta literales (
'…',E'…'), nombres entre comillas dobles, bloques$$…$$, comentarios y el::de los casts: nada de eso se confunde con un marcador. - Un
?suelto se rechaza (el driver lo tomaría por marcador); los operadores JSON tienen funciones equivalentes comojsonb_exists. - Las columnas salen de la pestaña Columnas (orden, encabezado, tipo, totales, ancho). Si no hay ninguna, de los metadatos del resultado. Los alias se comparan sin distinguir mayúsculas: PostgreSQL los devuelve en minúscula.
SELECT bp.Name AS cliente, o.DocumentNo AS orden, o.DateOrdered AS fecha, o.GrandTotal AS totalFROM C_Order o JOIN C_BPartner bp ON bp.C_BPartner_ID = o.C_BPartner_IDWHERE o.AD_Client_ID = :AD_Client_ID AND o.IsSOTrx = 'Y' AND o.DocStatus IN ('CO', 'CL') AND (:DateOrdered IS NULL OR o.DateOrdered >= :DateOrdered) AND (:DateOrdered_To IS NULL OR o.DateOrdered::date <= :DateOrdered_To) AND (:C_BPartner_ID IS NULL OR o.C_BPartner_ID = :C_BPartner_ID)ORDER BY bp.Name, o.DateOrderedSeguridad
Sección titulada «Seguridad»| Capa | Qué hace |
|---|---|
| Transacción propia | Conexión aparte con SET TRANSACTION READ ONLY: una consulta que intenta escribir falla. Siempre se revierte |
| Tiempo límite | SET LOCAL statement_timeout con FVE_REPORT_TIMEOUT_S (FVE_Config, 120 s por defecto) |
| Límite de filas | FVE_MaxRows (+1 para detectarlo): más filas es un error claro, no un archivo truncado |
| Funciones prohibidas | pg_sleep, pg_terminate_backend, pg_read_file, lo_import, dblink, set_config, bloqueos advisory… |
| Aislamiento | :AD_Client_ID obligatorio |
| Diseño | Los botones del diseñador exigen lectura y escritura en la ventana Diseñador de reportes, comprobado en el servidor (también por REST) |
| Ejecución | Cada reporte publicado es un AD_Process: se ejecuta con el acceso de proceso del rol |
Formatos
Sección titulada «Formatos»| Formato | Cómo sale |
|---|---|
OpenPDF, A4 vertical u horizontal: logo (organización, luego LogoReport_ID, luego Logo_ID de la empresa), razón social, RIF (perfil fiscal vigente o AD_OrgInfo.TaxID), título, parámetros usados, tabla con cabecera oscura repetida en cada página, filas alternas, grupos con subtotal, total general, pie «Página X de Y» y el inicio de la huella; la huella completa al final | |
| XLSX | POI en streaming (SXSSF, 200 filas en memoria): mismo encabezado, celdas tipadas (#,##0.00, dd/mm/aaaa), paneles fijos, autofiltro, subtotales y total como SUBTOTAL(9,…) (siguen al filtro y no suman dos veces) |
| XLSXT | La plantilla del usuario (XSSF): la fila con ${COLUMNA} se repite por registro con su estilo y sus fórmulas por fila; se sustituyen ${param.X}, ${report.name}, ${report.code}, ${report.generated}, ${report.user}, ${report.rows}, ${report.sha256}, ${company.name}, ${company.rif} y ${total.COLUMNA} |
| CSV | UTF-8 con BOM, separador ;, coma decimal, fechas dd/mm/aaaa; sin subtotales; un texto que empieza por = + - @ lleva ' delante (inyección de fórmulas) |
La huella SHA-256 se calcula sobre los valores mostrados de todas las filas, independiente del formato y de la escala de los números: el mismo dato da la misma huella en PDF, Excel y CSV.
El nombre del archivo sale de FVE_FileNamePattern con ${code}, ${name}, ${date}, ${time} y ${param.X}
(por defecto ${code}_${date}_${time}), reducido a letras sin acentos, dígitos, ., _ y -.
Procesos
Sección titulada «Procesos»| Value | Clase | Qué hace |
|---|---|---|
FVE_ReportRun | com.finora.lve.reportes.process.RunReport | La clase de todo reporte publicado. Busca la definición por AD_Process_ID (la copia de la empresa con el mismo código gana); toma los parámetros por ColumnName, más FVE_OutputFormat, EMail y FVE_ReportTemplate_ID; deja el archivo en exportFile y lo descarga en la web |
FVE_ReportPublish | PublishReport | Crea o actualiza FVE_RPT_<código> (sistema) o FVE_RPT_<empresa>_<código>, sus parámetros, el acceso del rol que publica y la entrada bajo Reportes |
FVE_ReportDetectColumns | DetectColumns | Describe la consulta sin leer filas y crea las columnas que faltan con el tipo deducido |
FVE_ReportTemplateBase | GenerateTemplate | Plantilla XLSX base, adjunta a una fila nueva de Plantillas |
FVE_ReportPreview | PreviewReport | PDF con 50 filas y los parámetros por defecto |
FVE_ReportCopy | CopyReport | Copia la definición, sus parámetros, columnas y plantillas a la empresa |
FVE_RPT_Catalogo | process.api.ReportCatalog | API: reportes que el rol puede ejecutar |
FVE_RPT_Ejecutar | process.api.ExecuteReport | API: ejecuta un reporte por código |
AD_Process y AD_Menu son diccionario del sistema: al publicar un reporte de empresa se escriben como cliente 0, con
EntityType U y el id de la empresa en el nombre, y solo los roles con acceso lo ven. Nunca se toca un proceso que vino
en el 2Pack de un módulo.
API REST
Sección titulada «API REST»POST /api/v1/processes/fve_rpt_catalogo{"FVE_ReportCategory": "Nómina"}
POST /api/v1/processes/fve_rpt_ejecutar{"FVE_ReportCode": "NOM_RESUMEN_CORRIDA", "FVE_OutputFormat": "XLSX", "FVE_ReportParams": "{\"HR_Process_ID\": 1000042}"}- El catálogo responde un objeto JSON por reporte en
logs[](codigo,nombre,categoria,formatos,formato,parametrosconnombre,etiqueta,tipo,obligatorio,rango,defecto,tabla) y el resumen{"reportes": n}. Solo lista lo que el rol puede ejecutar. - Ejecutar devuelve el archivo en
exportFile(base64) y el resumen{"archivo","formato","filas","sha256"}. Las fechas van comoAAAA-MM-DD; el fin de un rango, comoNombre_To; un parámetro omitido toma su valor por defecto. Exige el mismo acceso que el menú. - Cada reporte publicado es también un proceso REST:
POST /api/v1/processes/fve_rpt_<código>con sus parámetros yFVE_OutputFormat.
Cómo declara un módulo sus reportes del sistema
Sección titulada «Cómo declara un módulo sus reportes del sistema»Un módulo que trae reportes (Nómina es el primero) depende de REPORTES en tres lugares: Require-Bundle del
manifiesto, requiredBundles() de su LvePackActivator (para que sus filas se apliquen después de las tablas de
reportes) y requires de tools/apps/modules.json, con "reports": true (el publicador del catálogo rechaza un
módulo con reportes que no requiera REPORTES). FINORA Aplicaciones instala la dependencia sola.
En un 2Pack de datos del módulo:
- Un
AD_ProcessFVE_RPT_<código>conClassnamecom.finora.lve.reportes.process.RunReporty unAD_Process_Parapor parámetro (mismoColumnNameque el marcador; la referencia la elige el módulo: búsqueda, lista, tabla propia o rango), másFVE_OutputFormat(listauid("AD_Reference","FVE_OutputFormat"), elementouid("AD_Element","FVE_OutputFormat"), largo 5) y, si se quiere,EMail. - La fila
FVE_ReportDefconAD_Client_ID0 yAD_Process_ID= ese proceso, con sus filasFVE_ReportParamyFVE_ReportColumn, todas con UUID estables. - Su entrada de menú, donde el módulo quiera; el acceso sigue al módulo del rol.
- Una plantilla del sistema va en el propio bundle y se declara con
FVE_TemplateResource = bundle:<bundle>:<ruta>.
Una empresa que quiere cambiar un reporte del sistema pulsa Copiar a mi empresa: su copia, con el mismo código, reemplaza al original en el menú del módulo, en la API y en el proceso, sin tocar la fila del sistema.
Qué sigue
Sección titulada «Qué sigue»- Crear tu primer reporte, la guía funcional paso a paso.
- Reportes: Print Formats y Jasper, las herramientas del core.
- FINORA Aplicaciones, para instalar el módulo.