9.1 KiB
Módulo de Reportes
El frontend expone tres sistemas de reportes distintos, con configuración, rutas y componentes propios cada uno. No son variantes del mismo flujo: apuntan a integraciones distintas del lado del backend, y uno de ellos (informes) no tiene backend real detrás todavía.
| Sistema | Ruta base | Config | Componente runner | Backend real |
|---|---|---|---|---|
| Reportes HTML | /reportes-html/:module |
config/htmlReports.ts → htmlReportsConfig |
HtmlReportRunner.tsx |
mini-backend/routers/reports.py (Jinja2 + WeasyPrint, datos de HANA) — sí implementado |
| Reportes Crystal | /reportes-crystal/:module |
config/crystalReports.ts → crystalReportsConfig |
CrystalReportRunner.tsx |
mini-backend/routers/apigateway.py (SAP B1 API Gateway / Crystal Reports Server) — sí implementado |
| Informes | /informes/:module |
config/reports.ts → reportsConfig |
ReportRunner.tsx |
Ninguno confirmado — ver nota abajo |
Nota sobre informes (ReportRunner.tsx + reportsConfig)
reportsConfig (en config/reports.ts) define reportes como "Estado de Cuenta", "Saldos de Clientes", "Ventas por Artículo", "Kardex de Artículos", etc., cada uno con un endpoint del tipo /api/reports/socios/estado-cuenta, /api/reports/inventario/kardex, etc. El único endpoint que mini-backend/routers/reports.py expone bajo /api/reports/ es POST /api/reports/stickers. Ninguno de los endpoints que reportsConfig referencia existe en el backend actual. Esto sugiere que ReportRunner.tsx y reportsConfig son un scaffold frontend para reportes planeados a futuro, no un flujo funcional hoy — cualquier reporte del módulo "Informes" fallará al generar hasta que se implemente su endpoint correspondiente en el backend.
Arquitectura General
graph TB
subgraph "Listados (elegir reporte)"
RHL[HtmlReportsList.tsx]
RCL[CrystalReportsList.tsx]
MRL[ModuleReportsList.tsx]
end
subgraph "Runners (parámetros + ejecución)"
HRR[HtmlReportRunner.tsx]
CRR[CrystalReportRunner.tsx]
RR[ReportRunner.tsx]
RPF[ReportParameterForm.tsx]
RRV[ReportResultsView.tsx]
MST[ModalSearchTemplate.tsx<br/>búsqueda F4]
end
subgraph "Config"
CFG_H[htmlReportsConfig]
CFG_C[crystalReportsConfig]
CFG_R[reportsConfig]
end
subgraph "Backend FastAPI (mini-backend)"
REP[routers/reports.py<br/>POST /api/reports/stickers]
APIGW[routers/apigateway.py<br/>GET/POST /api/apigateway/reports/*]
HANA[core/hana.py<br/>hana_connection]
AGW_CORE[core/api_gateway.py<br/>forward_to_api_gateway]
end
subgraph "Externo"
HANADB[(HANA DB)]
SAPGW[SAP B1 API Gateway<br/>rs/v1 Crystal Reports Server]
end
RHL --> CFG_H --> HRR
RCL --> CFG_C --> CRR
MRL --> CFG_R --> RR
HRR --> RPF
CRR --> RPF
RR --> RPF
RR --> RRV
HRR -.f4-modal.-> MST
CRR -.f4-modal.-> MST
HRR -->|POST /api/reports/:endpoint| REP
REP --> HANA --> HANADB
CRR -->|POST /api/apigateway/reports/:docCode/export| APIGW
RCL -.al listar.-> APIGW
APIGW --> AGW_CORE --> SAPGW
RR -.->|"endpoint del reportsConfig<br/>(no existe en el backend)"| REP
Flujo real: Reporte HTML (ejemplo "stickers")
sequenceDiagram
actor User as Usuario
participant List as HtmlReportsList
participant Runner as HtmlReportRunner
participant Modal as ModalSearchTemplate
participant API as api.ts
participant Backend as reports.py
participant HANA as HANA
User->>List: /reportes-html/inventario
List->>List: lee htmlReportsConfig["inventario"]
List-->>User: tarjeta "Impresión de Etiquetas"
User->>Runner: clic → /reportes-html/inventario/stickers
Runner->>Runner: busca definition por docCode "stickers"
Runner-->>User: formulario (Documento f4-modal, Cantidad, Formato, Papel)
User->>Runner: clic en campo "Documento"
Runner->>Modal: abre ModalSearchTemplate (endpoint DeliveryNotes)
Modal-->>User: tabla de guías de remisión
User->>Modal: selecciona guía
Modal-->>Runner: DocEntry seleccionado
User->>Runner: completa cantidad/formato y clic "Generar Reporte"
Runner->>API: POST /api/reports/stickers {doc_entry, cantidad, formato, papel}
API->>Backend: fetch con X-Session-Token
Backend->>HANA: STICKERS_QUERY (datos de la guía por DocEntry)
HANA-->>Backend: fila con cliente, dirección, etc.
Backend->>Backend: renderiza templates/reports/stickers.html (Jinja2)
alt formato = pdf
Backend->>Backend: WeasyPrint HTML → PDF
Backend-->>API: StreamingResponse application/pdf
else formato = html
Backend-->>API: HTMLResponse
end
API-->>Runner: blob
Runner-->>User: <iframe> con vista previa
Flujo real: Reporte Crystal (ejemplo "DLN20015")
sequenceDiagram
actor User as Usuario
participant List as CrystalReportsList
participant Runner as CrystalReportRunner
participant API as api.ts
participant Backend as apigateway.py
participant Core as core/api_gateway.py
participant SAPGW as SAP API Gateway
User->>List: /reportes-crystal/inventario
List->>List: lee crystalReportsConfig["inventario"]
List-->>User: tarjeta "Impresión de Etiquetas" (docCode DLN20015)
User->>Runner: clic → /reportes-crystal/inventario/DLN20015
Runner-->>User: formulario (Documento f4-modal, Cantidad)
User->>Runner: completa parámetros y clic "Exportar PDF"
Runner->>API: POST /api/apigateway/reports/DLN20015/export<br/>[{name, type, value}]
API->>Backend: fetch con X-Session-Token
Backend->>Core: forward_to_api_gateway(POST rs/v1/ExportPDFData?DocCode=DLN20015)
Core->>SAPGW: request con credenciales APIGATEWAY_* del .env
SAPGW-->>Core: PDF en base64
Core-->>Backend: response
Backend->>Backend: decodifica base64 → bytes
Backend-->>API: StreamingResponse application/pdf
API-->>Runner: blob
Runner-->>User: <iframe> con vista previa PDF
Nota: crystalReportsConfig solo tiene un reporte cargado, en inventario (DLN20015, "Impresión de Etiquetas"). Los otros módulos (socios, ventas, compras) están declarados con arrays vacíos — no hay reportes Crystal configurados para ellos todavía. Curiosamente, el comentario en mini-backend/routers/reports.py indica que la consulta SQL de stickers (el reporte HTML) es "la query original de Crystal Reports para DLN20015, adaptada" — es decir, el mismo reporte de negocio (etiquetas de guía de remisión) existe hoy por dos caminos en paralelo: el Crystal Report original vía API Gateway, y su reimplementación propia vía HANA + Jinja + WeasyPrint.
Árbol de Componentes y Rutas
App.tsx (BrowserRouter)
└── / (ProtectedRoute → MainLayout)
├── /informes/:module → ModuleReportsList.tsx
│ └── /informes/:module/:reportId → ReportRunner.tsx
│ ├── ReportParameterForm.tsx
│ └── ReportResultsView.tsx
├── /reportes-crystal/:module → CrystalReportsList.tsx
│ └── /reportes-crystal/:module/:docCode → CrystalReportRunner.tsx
│ └── ModalSearchTemplate.tsx (f4-modal)
└── /reportes-html/:module → HtmlReportsList.tsx
└── /reportes-html/:module/:docCode → HtmlReportRunner.tsx
└── ModalSearchTemplate.tsx (f4-modal)
:module es uno de socios | ventas | compras | inventario (moduleLabels/moduleIcons en config/reports.ts), compartido por los tres sistemas.
Archivos Clave
| Archivo | Ruta | Propósito |
|---|---|---|
ModuleReportsList.tsx |
src/views/informes/ |
Lista reportes de reportsConfig por módulo |
ReportRunner.tsx |
src/components/report/ |
Ejecuta reportes de reportsConfig (endpoints aún no implementados en backend) |
ReportParameterForm.tsx |
src/components/report/ |
Formulario de parámetros para ReportRunner |
ReportResultsView.tsx |
src/components/report/ |
Renderiza tabla/totales/PDF según outputType |
CrystalReportsList.tsx |
src/views/reportes/ |
Lista reportes de crystalReportsConfig por módulo |
CrystalReportRunner.tsx |
src/components/report/ |
Arma el body y llama a /api/apigateway/reports/:docCode/export |
HtmlReportsList.tsx |
src/views/reportes/ |
Lista reportes de htmlReportsConfig por módulo |
HtmlReportRunner.tsx |
src/components/report/ |
Arma el body y llama a /api/reports/:endpoint |
ModalSearchTemplate.tsx |
src/components/ui/ |
Modal de búsqueda F4 reutilizado por ambos runners reales |
config/reports.ts |
src/config/ |
reportsConfig, moduleLabels, moduleIcons |
config/crystalReports.ts |
src/config/ |
crystalReportsConfig |
config/htmlReports.ts |
src/config/ |
htmlReportsConfig |
types/reports.ts |
src/types/ |
Tipos ReportDefinition, F4Config, etc. |
reports.py |
mini-backend/routers/ |
POST /api/reports/stickers (Jinja2 + WeasyPrint, datos vía core/hana.py) |
apigateway.py |
mini-backend/routers/ |
GET /api/apigateway/reports, GET .../{docCode}/parameters, POST .../{docCode}/export |
api_gateway.py |
mini-backend/core/ |
forward_to_api_gateway, proxy hacia el SAP API Gateway |