# Inventario del código ## Archivos | Archivo | Líneas | Rol | |---------|--------|-----| | `main.py` | 134 | Demonio orquestador (loop de horarios) | | `pipeline.py` | 957 | Pipeline core (procesar un correo completo) | | `sunat_schema.py` | 521 | Parseo de XML SUNAT (Invoice, DespatchAdvice) | | `pdf_utilities.py` | 450 | Parseo de PDFs (factura, guías) | | `sapb1_manager.py` | 322 | Comunicación con SAP B1 Service Layer | | `outlook_utilities.py` | 228 | Comunicación con Microsoft Graph | | `hana_manager.py` | 126 | Comunicación con SAP HANA directa | | `database_utilities.py` | 114 | SQLite local (cache de correos) | | `consulta_rapida.py` | 115 | Script auxiliar para reprocesar correos por ID | | `email_utilities.py` | 93 | Utilitarios de adjuntos (ZIP, filtrado) | | `logger_utilities.py` | 72 | Logging a archivo + consola | --- ## Dependencias entre archivos ``` main.py └── pipeline.py ├── sunat_schema.py ├── pdf_utilities.py ├── sapb1_manager.py │ └── hana_manager.py ├── outlook_utilities.py ├── email_utilities.py │ └── database_utilities.py └── database_utilities.py ``` --- ## Flujo de datos ``` main() └── run_pipeline() ├── step_authenticate() → token MS Graph ├── 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 │ └── pdf_utilities.extraer_datos_pdf() ├── _procesar_xmls(pdf_cache) → documentos[] │ └── sunat_schema.extraer_datos_xml() ├── _guardar_resultado(documentos) ├── _validate_prices(factura) → (ok, resultados) │ └── sapb1_manager.get_delivery_notes() │ ├── SL (Service Layer) GET /DeliveryNotes │ └── HANA fallback (get_delivery) ├── _build_sap_draft(factura, resultados) → draft ├── _guardar_draft_json(draft) ├── sapb1_manager.create_draft(draft) └── outlook_utilities.send_email(notificación) ``` --- ## Problemas conocidos hasta ahora | # | Problema | Archivo | Estado | |---|----------|---------|--------| | 1 | `_extraer_serie_numero_desde_texto` no limpiaba leading zeros | `sunat_schema.py` | ✅ Corregido | | 2 | Al asignar guías por línea, si hay +refs que líneas, las sobrantes se perdían | `pipeline.py` | ✅ Corregido | | 3 | SL sin fallback a HANA | `sapb1_manager.py` | ✅ Corregido | | 4 | Ctrl+C mostraba traceback | `main.py` | ✅ Corregido | | 5 | `.env.dev` vs `.env` inconsistente | `sapb1_manager.py` | ✅ Corregido | | 6 | `HANA_HOST` vs `HANA_SERVER` en `.env` | `hana_manager.py` | ✅ Corregido | | 7 | Columna `Cancelled` vs `CANCELED` en HANA | `hana_manager.py` | ✅ Corregido | --- ## Funciones internas en `_procesar_un_correo` (pipeline.py) | Función | Líneas | Propósito | |---------|--------|-----------| | `_descargar_adjuntos` | 107-134 | Descarga adjuntos vía Graph API | | `_descomprimir` | 136-149 | Descomprime ZIPs | | `_filtrar_y_limpiar` | 151-191 | Filtra PDF/XML, elimina el resto | | `_procesar_pdfs` | 193-246 | Extrae datos de PDFs, renombra, genera cache | | `_procesar_xmls` | 248-377 | Procesa XMLs, cruza con PDF, asigna guías | | `_guardar_resultado` | 379-408 | Guarda JSON con datos extraídos | | `_build_sap_draft` | 410-569 | Construye payload del draft SAP B1 | | `_validate_prices` | 571-745 | Valida precios contra DeliveryNotes SAP | | `_build_validation_html` | 747-775 | Genera tabla HTML para notificación | | `_build_notification_body` | 777-814 | Arma cuerpo del email de notificación | | `_guardar_draft_json` | 816-842 | Guarda draft JSON para depuración |