3.6 KiB
3.6 KiB
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
Nonesi no hay columnas). - Mapa
path -> alias finalaplicado.
Notas:
radicadosiempre se incluye como columna.- Duplicados de alias se desambiguarán con sufijos
(n).
process_radicados_parallel(...) -> None
Procesa en paralelo los radicados, realizando:
- Extracción de datos de factura y preformato (si está habilitado).
- Emisión de JSON via
on_output. - Escritura incremental en CSV con encabezado dado (
csv_header_union) o derivado.
Parámetros clave:
service: Debe exponerextract_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 (siNone, 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
ThreadPoolExecutorconmax_workers=4para 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_selectedselecciona la lista principal y las listas a agregar; si no hay inferencia, se consultaprofiles. on_outputyon_progressson opcionales y tolerantes a errores (capturados).
Ejemplos
Cálculo de encabezado
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)
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}"),
)