- Nueva página docs/sapb1_manager.md: sesión, funciones, clasificación de errores (SapNoDisponible frente a rechazo de SAP), búsqueda de facturas existentes y cómo se ubica una guía. - procesar_pdfs.md y procesar_xmls.md usaban los nombres anteriores a la división de pipeline.py (_procesar_pdfs, _ruta_carpeta...) y números de línea que envejecen; ahora apuntan a documentos.py. - inventario.md: árbol de dependencias con los módulos nuevos. - pipeline.md: _procesar_factura, importes_coinciden, hana_disponible y buscar_factura_existente; validar_precios.md, hana_manager.md, main.md y procesar_xmls.md con las notas que faltaban; README sin la cifra de pruebas vieja. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2.9 KiB
hana_manager.py — SAP HANA directo
Acceso de solo lectura a SAP HANA con hdbcli. Se usa para dos cosas:
- Fallback de
sapb1_manager.get_delivery_notes: ubicar una guía de remisión cuando el Service Layer no la encuentra. - Valor referencial por guía: ejecutar
Sp_ObtenerValorReferencial(lo consumedraft_sap.obtener_valor_referencial_sap).
Estructura
hana_manager.py
├── CONFIG (.env): HANA_SERVER, HANA_PORT (30015), HANA_USER, HANA_PASSWORD, HANA_SCHEMA
├── get_connection() → conexión | None
├── get_delivery(tipo, serie, numero) → list[dict]
│ ├── _query_delivery_table(conn, "ODLN", ...) (Entregas)
│ └── _query_delivery_table(conn, "OWTR", ...) (Traslados; solo si ODLN no devolvió nada)
└── obtener_valor_referencial(serie, numero) → float
get_delivery(tipo, serie, numero)
flowchart TD
A[get_delivery] --> B{get_connection OK?}
B -- No --> Z["return []"]
B -- Sí --> C["Consultar ODLN"]
C --> D{¿Hay resultados?}
D -- Sí --> R["return resultados (Tabla = 'ODLN')"]
D -- No --> E["Consultar OWTR"]
E --> R2["return resultados (Tabla = 'OWTR') o []"]
Filtro aplicado en ambas tablas:
| Campo SAP | Valor |
|---|---|
CANCELED |
'N' |
U_BPP_MDTD |
tipo (código SUNAT: 09, 31) |
U_BPP_MDSD |
serie |
U_BPP_MDCD |
LIKE '%numero%' |
Cada registro devuelto trae DocEntry, DocNum, CardCode, CardName y Tabla. El campo Tabla le dice a sapb1_manager qué endpoint del Service Layer usar después: DeliveryNotes (ODLN) o StockTransfers (OWTR, que además requiere resolver la orden de venta por U_IDC_NUMOV).
obtener_valor_referencial(serie, numero)
Ejecuta CALL "<schema>"."Sp_ObtenerValorReferencial"(serie, numero) y devuelve la columna ValorReferencial del primer registro. Retorna 0.0 si no hay filas, si el valor es nulo o si ocurre un error.
Comportamiento ante errores
Ninguna función lanza excepciones: todas registran un ERROR en el log y devuelven un valor neutro (None en get_connection, [] en get_delivery, 0.0 en obtener_valor_referencial). Por eso las credenciales de HANA son obligatorias en config_validator: sin ellas el pipeline seguiría ejecutándose con valores referenciales en 0 sin detenerse.
Notas
-
draft_sap.hana_disponible()usaget_connection()como comprobación de salud: abre y cierra una conexión. Se invoca antes de rechazar por "guía no encontrada", porqueget_deliverydevuelve lista vacía tanto si la guía no existe como si HANA está caído. -
Cada llamada abre y cierra su propia conexión (no hay pool).
-
El número se busca con
LIKE '%numero%': es una coincidencia parcial, así que un número corto podría coincidir con más de un documento de la misma serie. -
El esquema se interpola en el SQL desde
HANA_SCHEMA(.env); los valores de búsqueda sí van como parámetros (?).