se divide pipeline.py en módulos (adjuntos, documentos, persistencia, draft_sap, notificaciones)

Las funciones anidadas de _procesar_un_correo pasan a funciones de módulo
con parámetros explícitos; pipeline.py queda solo como orquestador.
copiar_a_red lee las variables de entorno al ejecutarse. Se actualizan docs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5.5 committed 2026-10-20 22:03:38 -05:00
1 parent ee64e5f773
commit 7d2f3212c0
9 files changed
+1309 -1228

No files matched your search

+53 -36
View File
@@ -5,7 +5,13 @@
| Archivo | Líneas | Rol |
|---------|--------|-----|
| `main.py` | 134 | Demonio orquestador (loop de horarios) |
| `pipeline.py` | 1284 | Pipeline core (procesar un correo completo) |
| `pipeline.py` | 230 | Orquestador del pipeline (autenticar, descargar correos, procesar un correo) |
| `pipeline_utils.py` | 15 | `log()` con indentación de árbol y `ruta_carpeta()` |
| `adjuntos.py` | 81 | Descarga de adjuntos (Graph) y filtrado PDF/XML |
| `documentos.py` | 371 | Extracción PDF/XML, asignación de guías, copia a red |
| `persistencia.py` | 163 | Guardado de JSON de resultados y de drafts |
| `draft_sap.py` | 413 | Validación de precios contra SAP, valor referencial y construcción del draft |
| `notificaciones.py` | 117 | Cuerpos HTML de los correos de notificación |
| `sunat_schema.py` | 720 | Parseo de XML SUNAT (Invoice, DespatchAdvice) |
| `pdf_utilities.py` | 464 | Parseo de PDFs (factura, guías) |
| `sapb1_manager.py` | 321 | Comunicación con SAP B1 Service Layer |
@@ -32,6 +38,17 @@ main.py
├── outlook_utilities.py
├── email_utilities.py
└── database_utilities.py
```
Módulos que `pipeline.py` orquesta (todos usan `pipeline_utils.py`):
```
pipeline.py
├── adjuntos.py → outlook_utilities
├── documentos.py → sunat_schema, pdf_utilities
├── persistencia.py → sunat_schema, pdf_utilities
├── draft_sap.py → sapb1_manager, hana_manager
└── notificaciones.py
consulta_rapida.py
├── logger_manager.py
@@ -50,28 +67,28 @@ main()
├── step_fetch_emails() → emails[]
└── _procesar_un_correo() (por cada email)
├── BD: verificar duplicado
├── _descargar_adjuntos() → archivos
├── _descomprimir() ZIPs
├── _filtrar_y_limpiar() → solo PDF/XML
├── _procesar_pdfs() → pdf_cache
├── adjuntos.descargar_adjuntos() → archivos
├── email_utilities.descomprimir_adjuntos() ZIPs
├── adjuntos.filtrar_y_limpiar() → solo PDF/XML
├── documentos.procesar_pdfs() → pdf_cache
│ └── pdf_utilities.extraer_datos_pdf()
├── _procesar_xmls(pdf_cache) → documentos[]
├── documentos.procesar_xmls(pdf_cache) → documentos[]
│ ├── sunat_schema.extraer_datos_xml()
│ └── _copiar_a_red() → copia PDF/XML a ruta de red (RUTA_RED_FACTURACION)
├── _completar_guias(documentos, pdf_cache) → completa guías faltantes desde PDF
├── _validar_guias(documentos) → advierte guías con datos incompletos
├── _guardar_resultado(documentos)
├── _validate_prices(factura) → (ok, resultados)
│ └── documentos.copiar_a_red() → copia PDF/XML a ruta de red (RUTA_RED_FACTURACION)
├── documentos.completar_guias(documentos, pdf_cache) → completa guías faltantes desde PDF
├── documentos.validar_guias(documentos) → advierte guías con datos incompletos
├── persistencia.guardar_resultado(documentos)
├── draft_sap.validate_prices(factura) → (ok, resultados)
│ └── sapb1_manager.get_delivery_notes()
│ ├── SL (Service Layer) GET /DeliveryNotes
│ ├── HANA fallback (get_delivery: ODLN, luego OWTR)
│ └── si vino de OWTR: GET StockTransfers(DocEntry)
│ → U_IDC_NUMOV → GET Orders(U_IDC_NUMOV)
├── _obtener_valor_referencial_sap(factura) → guias_valor_ref
├── draft_sap.obtener_valor_referencial_sap(factura) → guias_valor_ref
│ └── hana_manager.obtener_valor_referencial() (Sp_ObtenerValorReferencial)
├── _build_sap_draft(factura, resultados) → draft (incluye U_VS_ANEXO_PDF/XML)
├── draft_sap.build_sap_draft(factura, resultados) → draft (incluye U_VS_ANEXO_PDF/XML)
│ └── sapb1_manager.obtener_condicion_pago(CardCode) → DocDueDate
├── _guardar_draft_json(draft)
├── persistencia.guardar_draft_json(draft)
├── sapb1_manager.create_draft(draft)
└── outlook_utilities.send_email(notificación)
```
@@ -109,27 +126,27 @@ main()
---
## Funciones internas en `_procesar_un_correo` (pipeline.py)
## Funciones por módulo
> Nota: `_ruta_carpeta` y `_copiar_a_red` son helpers a nivel de módulo (no anidados en `_procesar_un_correo`); el resto son funciones anidadas dentro de `_procesar_un_correo` (líneas 142-1304).
> Antes eran funciones anidadas en `_procesar_un_correo`; ahora son funciones de módulo que reciben explícitamente `email`, `download_folder`, `output_folder`, etc. `pipeline.py` solo las orquesta.
| Función | Líneas | Propósito |
|---------|--------|-----------|
| `_ruta_carpeta` (módulo) | 33-34 | Resuelve una ruta relativa al directorio del script |
| `_copiar_a_red` (módulo) | 37-94 | Copia PDF/XML a la ruta de red de Facturación Electrónica (`RUTA_RED_FACTURACION`) |
| `_descargar_adjuntos` | 169-196 | Descarga adjuntos vía Graph API |
| `_descomprimir` | 198-211 | Descomprime ZIPs |
| `_filtrar_y_limpiar` | 213-253 | Filtra PDF/XML, elimina el resto |
| `_procesar_pdfs` | 255-308 | Extrae datos de PDFs, renombra, genera cache |
| `_procesar_xmls` | 310-463 | Procesa XMLs, cruza con PDF, asigna guías, copia a red |
| `_completar_guias` | 465-522 | Completa guías faltantes en líneas XML desde el PDF cache |
| `_validar_guias` | 524-532 | Advierte (log) guías con datos incompletos |
| `_guardar_resultado` | 534-653 | Guarda JSON con datos extraídos (XML y PDF) |
| `_calcular_fecha_vencimiento` | 665-692 | Calcula `DocDueDate` = fecha de contabilización + días de la condición de pago (`PaymentTermsTypes`) |
| `_build_sap_draft` | 694-855 | Construye payload del draft SAP B1 |
| `_validate_prices` | 856-1030 | Valida precios contra DeliveryNotes / Orders (SAP) |
| `_build_validation_html` | 1032-1061 | Genera tabla HTML de validación de precios |
| `_obtener_valor_referencial_sap` | 1062-1090 | Consulta `Sp_ObtenerValorReferencial` en HANA por guía |
| `_build_valor_referencial_html` | 1091-1126 | Genera tabla HTML comparando valor referencial XML vs SAP |
| `_build_notification_body` | 1127-1168 | Arma cuerpo del email de notificación |
| `_guardar_draft_json` | 1169-1195 | Guarda draft JSON para depuración |
| Módulo | Función | Propósito |
|--------|---------|-----------|
| `pipeline_utils` | `ruta_carpeta` | Resuelve una ruta relativa al directorio del proyecto |
| `pipeline_utils` | `log` | Imprime con indentación de árbol (niveles 1-4) |
| `adjuntos` | `descargar_adjuntos` | Descarga adjuntos vía Graph API |
| `adjuntos` | `filtrar_y_limpiar` | Filtra PDF/XML, elimina el resto |
| `documentos` | `copiar_a_red` | Copia PDF/XML a la ruta de red de Facturación Electrónica (`RUTA_RED_FACTURACION`) |
| `documentos` | `procesar_pdfs` | Extrae datos de PDFs, renombra, genera cache |
| `documentos` | `procesar_xmls` | Procesa XMLs, cruza con PDF, asigna guías, copia a red |
| `documentos` | `completar_guias` | Completa guías faltantes en líneas XML desde el PDF cache |
| `documentos` | `validar_guias` | Advierte (log) guías con datos incompletos |
| `persistencia` | `guardar_resultado` | Guarda JSON con datos extraídos (XML y PDF) |
| `persistencia` | `guardar_draft_json` | Guarda draft JSON para depuración |
| `draft_sap` | `calcular_fecha_vencimiento` | Calcula `DocDueDate` = fecha de contabilización + días de la condición de pago (`PaymentTermsTypes`) |
| `draft_sap` | `build_sap_draft` | Construye payload del draft SAP B1 |
| `draft_sap` | `validate_prices` | Valida precios contra DeliveryNotes / Orders (SAP) |
| `draft_sap` | `obtener_valor_referencial_sap` | Consulta `Sp_ObtenerValorReferencial` en HANA por guía |
| `notificaciones` | `build_validation_html` | Genera tabla HTML de validación de precios |
| `notificaciones` | `build_valor_referencial_html` | Genera tabla HTML comparando valor referencial XML vs SAP |
| `notificaciones` | `build_notification_body` | Arma cuerpo del email de notificación |