90 lines
3.6 KiB
Markdown
90 lines
3.6 KiB
Markdown
# `application/flows.py`
|
|
|
|
## Propósito
|
|
Orquesta el procesamiento por radicado para:
|
|
- Calcular encabezados CSV unificados a partir de muestras y selección de campos.
|
|
- Extraer información de factura y, opcionalmente, preformato.
|
|
- Escribir filas en CSV y emitir JSON a la interfaz gráfica mediante callbacks.
|
|
|
|
Incluye una heurística para inferir qué listas deben expandirse por filas y cuáles agregarse como columnas (en preformato).
|
|
|
|
## API pública
|
|
|
|
### `compute_csv_header_union(...) -> tuple[list[str] | None, dict[str, str]]`
|
|
Calcula el encabezado CSV común (unión) desde datos de muestra y paths seleccionados, aplicando alias y resolviendo duplicados.
|
|
|
|
Parámetros clave:
|
|
- `sample_fact`, `sample_pre`: ejemplos (dict o compatible) para derivar columnas.
|
|
- `selected_fields_fact`, `selected_fields_pre`: paths seleccionados por documento.
|
|
- `pre_enabled`: habilita el cálculo para preformato.
|
|
- `alias_map_fact`, `alias_map_pre`: alias opcionales path->nombre.
|
|
|
|
Devuelve:
|
|
- Lista de encabezados finales (o `None` si no hay columnas).
|
|
- Mapa `path -> alias final` aplicado.
|
|
|
|
Notas:
|
|
- `radicado` siempre se incluye como columna.
|
|
- Duplicados de alias se desambiguarán con sufijos `(n)`.
|
|
|
|
### `process_radicados_parallel(...) -> None`
|
|
Procesa en paralelo los radicados, realizando:
|
|
1) Extracción de datos de factura y preformato (si está habilitado).
|
|
2) Emisión de JSON via `on_output`.
|
|
3) Escritura incremental en CSV con encabezado dado (`csv_header_union`) o derivado.
|
|
|
|
Parámetros clave:
|
|
- `service`: Debe exponer `extract_full_from_pdf(...)` y `_append_rows_to_csv(...)`.
|
|
- `root`, `keywords`, `pre_keywords`: Búsqueda de documentos por radicado.
|
|
- `selected_fields_fact`, `selected_fields_pre`: paths de salida.
|
|
- `csv_path`: Archivo CSV destino (si `None`, no escribe).
|
|
- `on_output`: Callback que recibe texto JSON por radicado.
|
|
- `on_progress`: Callback `(radicado, done, total)` para progreso.
|
|
- `instruction_invoice`, `instruction_pre`: instrucciones LLM.
|
|
- `alias_final_map`: alias finales a aplicar a encabezados/filas.
|
|
|
|
Concurrencia:
|
|
- Usa `ThreadPoolExecutor` con `max_workers=4` para balancear IO/CPU.
|
|
- Los errores por documento se capturan y se registran sin detener el flujo.
|
|
|
|
## Consideraciones
|
|
- Si se define `csv_header_union`, éste manda sobre encabezados derivados por radicado.
|
|
- Para preformato, la heurística `_infer_aggregate_list_paths_from_selected` selecciona la lista principal y las listas a agregar; si no hay inferencia, se consulta `profiles`.
|
|
- `on_output` y `on_progress` son opcionales y tolerantes a errores (capturados).
|
|
|
|
## Ejemplos
|
|
|
|
### Cálculo de encabezado
|
|
```python
|
|
from application.flows import compute_csv_header_union
|
|
|
|
header, alias_map = compute_csv_header_union(
|
|
sample_fact={'radicado': 'x', 'items': [{'codigo': 'A1', 'cantidad': 2}]},
|
|
sample_pre=None,
|
|
selected_fields_fact=['radicado', 'items/*/codigo', 'items/*/cantidad'],
|
|
selected_fields_pre=None,
|
|
pre_enabled=False,
|
|
)
|
|
# header ~= ['radicado', 'items/*/codigo', 'items/*/cantidad']
|
|
```
|
|
|
|
### Proceso por radicado (escritura CSV)
|
|
```python
|
|
from application.flows import process_radicados_parallel
|
|
|
|
process_radicados_parallel(
|
|
service=my_service, # Debe implementar extract_full_from_pdf y _append_rows_to_csv
|
|
root="C:/carpeta/raiz",
|
|
keywords=["FACTURA", "RADICADO"],
|
|
pre_enabled=True,
|
|
pre_keywords=["PREFORMATO"],
|
|
selected_fields_fact=['radicado', 'items/*/codigo', 'items/*/cantidad'],
|
|
selected_fields_pre=['radicado', 'dx/*/descripcion'],
|
|
csv_path="salida.csv",
|
|
on_output=lambda txt: print(txt),
|
|
on_progress=lambda r,d,t: print(f"{d}/{t} -> {r}"),
|
|
)
|
|
```
|
|
|
|
|