primer commit
This commit is contained in:
1 parent
ab3c613165
commit
b2fb4e2d0a
18 files changed
+1291
-277
No files matched your search
@@ -0,0 +1,187 @@
|
||||
# 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 |
|
||||
Reference in new issue
Block a user