Files
mini-erp/mini-frontend/docs/reportes.md
T

187 lines
9.1 KiB
Markdown
Raw Normal View History

2026-08-17 11:58:38 -05:00
# 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
```mermaid
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")
```mermaid
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")
```mermaid
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 |