Files
descarga_factura_transporte/docs/inventario.md
T
georgeandClaude Sonnet 5 15e3b5079c se agrega fallback OWTR y calculo de fecha de vencimiento por condicion de pago
- hana_manager.get_delivery ahora busca en ODLN y, si no encuentra, en OWTR
- sapb1_manager resuelve StockTransfers -> Orders (via U_IDC_NUMOV) para
  validar precios de flete cuando la guia es un traslado de inventario
- se corrige el orden de parametros tipo/serie/numero (sin cruces) en
  get_delivery, get_delivery_notes y _get_delivery_entries
- se agrega sapb1_manager.obtener_condicion_pago (BusinessPartners +
  PaymentTermsTypes) y pipeline._calcular_fecha_vencimiento para que
  DocDueDate del draft sea fecha de contabilizacion + dias de la condicion
  de pago del proveedor
- se agrega variante de regex para "VALOR REFER" truncado en sunat_schema.py
- se actualiza documentacion (docs/) reflejando estos cambios

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 13:21:04 -05:00

8.8 KiB

Inventario del código

Archivos

Archivo Líneas Rol
main.py 134 Demonio orquestador (loop de horarios)
pipeline.py 1284 Pipeline core (procesar un correo completo)
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
outlook_utilities.py 234 Comunicación con Microsoft Graph
hana_manager.py 123 Comunicación con SAP HANA directa (fallback de sapb1_manager y valor referencial)
database_utilities.py 116 SQLite local (cache de correos)
consulta_rapida.py 113 Script auxiliar para reprocesar correos por ID
email_utilities.py 52 Utilitarios de adjuntos (ZIP, filtrado)
logger_manager.py 149 Logging a archivo rotado (30 días) + consola + captura de print()

Dependencias entre archivos

main.py
  ├── logger_manager.py
  └── pipeline.py
        ├── sunat_schema.py
        ├── pdf_utilities.py
        ├── sapb1_manager.py
        │     └── hana_manager.py
        ├── hana_manager.py            (valor referencial, Sp_ObtenerValorReferencial)
        ├── outlook_utilities.py
        ├── email_utilities.py
        └── database_utilities.py

consulta_rapida.py
  ├── logger_manager.py
  ├── database_utilities.py
  └── pipeline.py (_procesar_un_correo, step_authenticate)

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()
              │     └── _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)
              │     └── 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
              │     └── hana_manager.obtener_valor_referencial() (Sp_ObtenerValorReferencial)
              ├── _build_sap_draft(factura, resultados) → draft (incluye U_VS_ANEXO_PDF/XML)
              │     └── sapb1_manager.obtener_condicion_pago(CardCode) → DocDueDate
              ├── _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
8 Bloque if __name__ == "__main__" borraba un correo real de la BD al ejecutar el módulo directo database_utilities.py ✅ Corregido
9 extraer_datos_xml solo procesaba guías tipo 31; tipo 09 (remitente) se descartaba pese a estar documentado sunat_schema.py ✅ Corregido
10 DatosComprobante.__str__ usaba ref.id (campo que ya no existe en DocumentoReferencia) sunat_schema.py ✅ Corregido
11 Log de error HTTP con print("%s", ...) no interpolaba el mensaje sapb1_manager.py ✅ Corregido
12 Fuga de conexión HANA si cursor() fallaba (quedaba fuera del try) hana_manager.py ✅ Corregido
13 razon_social_emisor se llenaba con el nombre del receptor en el JSON de depuración del PDF pipeline.py ✅ Corregido
14 Typo VERIFI_SSL en vez de VERIFY_SSL outlook_utilities.py / .env ✅ Corregido
15 Conexiones SQLite sin try/finally (fuga si fallaba una consulta a mitad de camino) database_utilities.py ✅ Corregido
16 Código muerto sin llamadores (quitar_correos_ya_registrados_en_base_de_datos, procesar_adjuntos_email) email_utilities.py ✅ Corregido (eliminado)
17 logger_utilities.py (redirección global de stdout, sin niveles ni rotación real) reemplazado por logger_manager.py (logging estándar, rotación diaria 30 días, captura de print()) logger_manager.py ✅ Corregido
18 task()/last_task() de logger_manager.py no devolvían el sub-logger (with ... as sub daba siempre None) logger_manager.py ✅ Corregido
19 DOWNLOAD_FOLDER duplicado en .env .env ✅ Corregido
20 Guías tipo 09 no se encontraban si el documento estaba en OWTR (Traslado de Inventario) en vez de ODLN hana_manager.py ✅ Corregido (fallback ODLN → OWTR)
21 Parámetros tipo/serie cruzados al llamar get_delivery/get_delivery_notes (mapeaban al revés a U_BPP_MDSD/U_BPP_MDTD) hana_manager.py, sapb1_manager.py, pipeline.py ✅ Corregido (orden natural tipo, serie, numero)
22 StockTransfers (OWTR) no tiene líneas FL*, por lo que la validación de precios fallaba siempre para esas guías sapb1_manager.py ✅ Corregido (resuelve la Orden de Venta vía U_IDC_NUMOV y valida contra Orders(DocEntry))
23 DocDueDate del draft usaba fecha_emision del XML, sin considerar la condición de pago del proveedor pipeline.py, sapb1_manager.py ✅ Corregido (DocDueDate = fecha de contabilización + días de PaymentTermsTypes)
24 Patrón regex de valor referencial no reconocía la variante truncada "VALOR REFER" (ej. "VALOR REFER:S/ 1431.16") sunat_schema.py ✅ Corregido

Funciones internas en _procesar_un_correo (pipeline.py)

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).

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