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:
1 parent
c5210c8a57
commit
6cc5e03209
9 files changed
+1309
-1228
No files matched your search
+53
-36
@@ -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 |
|
||||
+61
-55
@@ -4,12 +4,18 @@
|
||||
|
||||
```
|
||||
pipeline.py
|
||||
├── CONFIG: RUTA_RED_FACTURACION, RUC_EMPRESA (desde .env)
|
||||
├── HELPERS: _ruta_carpeta(), _copiar_a_red(data, _log)
|
||||
├── PASO 1: step_authenticate() → token | None
|
||||
├── PASO 2: step_fetch_emails() → list[dict]
|
||||
├── _procesar_un_correo() → None (core, funciones anidadas)
|
||||
├── _procesar_un_correo() → None (orquesta los módulos de abajo)
|
||||
└── run_pipeline() → None
|
||||
|
||||
Módulos que orquesta _procesar_un_correo():
|
||||
├── adjuntos.py descargar_adjuntos, filtrar_y_limpiar
|
||||
├── documentos.py procesar_pdfs, procesar_xmls, completar_guias, validar_guias, copiar_a_red
|
||||
├── persistencia.py guardar_resultado, guardar_draft_json
|
||||
├── draft_sap.py validate_prices, obtener_valor_referencial_sap, build_sap_draft
|
||||
├── notificaciones.py build_validation_html, build_valor_referencial_html, build_notification_body
|
||||
└── pipeline_utils.py log, ruta_carpeta
|
||||
```
|
||||
|
||||
---
|
||||
@@ -42,29 +48,29 @@ flowchart TD
|
||||
A[_procesar_un_correo] --> B[1-2. BD: ¿ya procesado?]
|
||||
B -- Sí --> C[⏭️ Saltar]
|
||||
B -- No --> D[Guardar en BD]
|
||||
D --> E[3. _descargar_adjuntos]
|
||||
D --> E[3. descargar_adjuntos]
|
||||
E --> F{Hay adjuntos?}
|
||||
F -- No --> C
|
||||
F -- Sí --> G[4. _descomprimir ZIPs]
|
||||
G --> H[5. _filtrar_y_limpiar]
|
||||
G --> H[5. filtrar_y_limpiar]
|
||||
H --> I{Hay PDF/XML?}
|
||||
I -- No --> C
|
||||
I -- Sí --> J[6. _procesar_pdfs]:::highlight
|
||||
J --> K[7. _procesar_xmls]:::highlight
|
||||
K --> K2[8. _completar_guias]
|
||||
K2 --> K3[9. _validar_guias]
|
||||
I -- Sí --> J[6. procesar_pdfs]:::highlight
|
||||
J --> K[7. procesar_xmls]:::highlight
|
||||
K --> K2[8. completar_guias]
|
||||
K2 --> K3[9. validar_guias]
|
||||
K3 --> L{Hay documentos?}
|
||||
L -- No --> C
|
||||
L -- Sí --> M[10. _guardar_resultado]
|
||||
L -- Sí --> M[10. guardar_resultado]
|
||||
M --> N[11. Filtrar facturas tipo 01]
|
||||
N --> O{Hay facturas?}
|
||||
O -- No --> C
|
||||
O -- Sí --> P[Bucle: por cada factura]
|
||||
|
||||
P --> Q[12. _validate_prices]:::highlight
|
||||
Q --> Q2[12.5 _obtener_valor_referencial_sap]
|
||||
Q2 --> R[13. _build_sap_draft]:::highlight
|
||||
R --> S[14. _guardar_draft_json]
|
||||
P --> Q[12. validate_prices]:::highlight
|
||||
Q --> Q2[12.5 obtener_valor_referencial_sap]
|
||||
Q2 --> R[13. build_sap_draft]:::highlight
|
||||
R --> S[14. guardar_draft_json]
|
||||
S --> T{Todas coinciden?}
|
||||
T -- Sí --> U[15. sapb1_manager.create_draft]
|
||||
T -- No --> V[⏭️ Draft NO creado]
|
||||
@@ -75,38 +81,38 @@ flowchart TD
|
||||
classDef highlight fill:#fff3e0,stroke:#e65100,stroke-width:3px;
|
||||
```
|
||||
|
||||
`_procesar_xmls` (paso 7) incluye internamente la copia de PDF/XML a la ruta de red (`_copiar_a_red`, ver más abajo) por cada comprobante procesado.
|
||||
`procesar_xmls` (paso 7) incluye internamente la copia de PDF/XML a la ruta de red (`copiar_a_red`, ver más abajo) por cada comprobante procesado.
|
||||
|
||||
---
|
||||
|
||||
## Funciones internas de `_procesar_un_correo`
|
||||
## Funciones por módulo
|
||||
|
||||
> `_ruta_carpeta` y `_copiar_a_red` están definidas a nivel de módulo (no anidadas); el resto son funciones anidadas dentro de `_procesar_un_correo`.
|
||||
> Son funciones de módulo (antes anidadas en `_procesar_un_correo`) y reciben explícitamente `email`, `download_folder`, `output_folder`, etc. `_procesar_un_correo` solo las orquesta.
|
||||
|
||||
| Función | Línea | Propósito |
|
||||
|---------|-------|-----------|
|
||||
| `_ruta_carpeta()` (módulo) | 33 | Resuelve una ruta relativa al directorio del script |
|
||||
| `_copiar_a_red(data, _log)` (módulo) | 37 | Copia PDF/XML de un comprobante a la ruta de red configurable |
|
||||
| `_descargar_adjuntos()` | 169 | Descarga adjuntos vía Microsoft Graph |
|
||||
| `_descomprimir()` | 198 | Descomprime archivos ZIP |
|
||||
| `_filtrar_y_limpiar()` | 213 | Filtra solo PDF/XML, elimina el resto |
|
||||
| **`_procesar_pdfs()`** | **255** | **Extrae datos de PDFs, renombra, genera cache** |
|
||||
| **`_procesar_xmls(pdf_cache)`** | **310** | **Procesa XMLs, cruza con PDF, asigna guías, copia a red** |
|
||||
| `_completar_guias(documentos, pdf_cache)` | 465 | Completa guías faltantes en líneas XML desde el PDF cache |
|
||||
| `_validar_guias(documentos)` | 524 | Advierte (log) guías con datos incompletos (falta tipo/serie/numero) |
|
||||
| `_guardar_resultado(documentos, datos_pdf)` | 534 | Guarda JSON con datos extraídos (XML y PDF) |
|
||||
| `_calcular_fecha_vencimiento(fecha_base, condicion_pago)` | 665 | Calcula `DocDueDate` = fecha de contabilización + días de `PaymentTermsTypes` |
|
||||
| **`_build_sap_draft(factura, resultados_val)`** | **694** | **Construye payload del draft SAP B1 (incluye `U_VS_ANEXO_PDF`/`U_VS_ANEXO_XML`, `DocDueDate` por condición de pago)** |
|
||||
| **`_validate_prices(factura)`** | **856** | **Valida precios contra DeliveryNotes/Orders SAP** |
|
||||
| `_build_validation_html(resultados)` | 1032 | Genera tabla HTML de validación de precios |
|
||||
| `_obtener_valor_referencial_sap(factura)` | 1062 | Consulta `Sp_ObtenerValorReferencial` en HANA por cada guía única |
|
||||
| `_build_valor_referencial_html(factura, guias_valor_ref)` | 1091 | Genera tabla HTML comparando valor referencial XML vs SAP |
|
||||
| `_build_notification_body(status, factura, validation_table, valor_referencial_table, **kwargs)` | 1127 | Arma cuerpo del email de notificación |
|
||||
| `_guardar_draft_json(draft, serie, numero)` | 1169 | Guarda draft JSON para depuración |
|
||||
| Función | Módulo | Propósito |
|
||||
|---------|--------|-----------|
|
||||
| `ruta_carpeta()` | `pipeline_utils` | Resuelve una ruta relativa al directorio del proyecto |
|
||||
| `log(msg, level, last)` | `pipeline_utils` | Imprime con indentación de árbol |
|
||||
| `copiar_a_red(data)` | `documentos` | Copia PDF/XML de un comprobante a la ruta de red configurable |
|
||||
| `descargar_adjuntos(email, email_addr, token, download_folder)` | `adjuntos` | Descarga adjuntos vía Microsoft Graph |
|
||||
| `filtrar_y_limpiar(email, download_folder)` | `adjuntos` | Filtra solo PDF/XML, elimina el resto |
|
||||
| **`procesar_pdfs(email, download_folder)`** | `documentos` | **Extrae datos de PDFs, renombra, genera cache** |
|
||||
| **`procesar_xmls(email, download_folder, pdf_cache)`** | `documentos` | **Procesa XMLs, cruza con PDF, asigna guías, copia a red** |
|
||||
| `completar_guias(documentos, pdf_cache)` | `documentos` | Completa guías faltantes en líneas XML desde el PDF cache |
|
||||
| `validar_guias(documentos)` | `documentos` | Advierte (log) guías con datos incompletos (falta tipo/serie/numero) |
|
||||
| `guardar_resultado(documentos, datos_pdf, output_folder)` | `persistencia` | Guarda JSON con datos extraídos (XML y PDF) |
|
||||
| `guardar_draft_json(draft, serie, numero, output_folder)` | `persistencia` | Guarda draft JSON para depuración |
|
||||
| `calcular_fecha_vencimiento(fecha_base, condicion_pago)` | `draft_sap` | Calcula `DocDueDate` = fecha de contabilización + días de `PaymentTermsTypes` |
|
||||
| **`build_sap_draft(factura, resultados_val)`** | `draft_sap` | **Construye payload del draft SAP B1 (incluye `U_VS_ANEXO_PDF`/`U_VS_ANEXO_XML`, `DocDueDate` por condición de pago)** |
|
||||
| **`validate_prices(factura)`** | `draft_sap` | **Valida precios contra DeliveryNotes/Orders SAP** |
|
||||
| `obtener_valor_referencial_sap(factura)` | `draft_sap` | Consulta `Sp_ObtenerValorReferencial` en HANA por cada guía única |
|
||||
| `build_validation_html(resultados)` | `notificaciones` | Genera tabla HTML de validación de precios |
|
||||
| `build_valor_referencial_html(factura, guias_valor_ref)` | `notificaciones` | Genera tabla HTML comparando valor referencial XML vs SAP |
|
||||
| `build_notification_body(status, factura, validation_table, valor_referencial_table, **kwargs)` | `notificaciones` | Arma cuerpo del email de notificación |
|
||||
|
||||
---
|
||||
|
||||
## `_copiar_a_red(data, _log)` — Copia a ruta de red
|
||||
## `copiar_a_red(data)` — Copia a ruta de red
|
||||
|
||||
Copia el PDF y el XML de cada comprobante procesado a una ruta de red UNC configurable, en paralelo al guardado local existente (no lo reemplaza). No falla el pipeline si la ruta no está configurada o no está disponible: solo registra una advertencia.
|
||||
|
||||
@@ -118,8 +124,8 @@ Copia el PDF y el XML de cada comprobante procesado a una ruta de red UNC config
|
||||
{RUC_EMPRESA}-{tipo}-{serie}-{numero}.xml
|
||||
```
|
||||
`RUC_EMPRESA` es el RUC de Aberio (fijo); `ruc_emisor` es el RUC del proveedor que emitió la factura (varía por comprobante). Año/mes/día salen de `fecha_emision`, sin ceros a la izquierda en mes/día.
|
||||
- Guarda las rutas resultantes en `data["ruta_red_pdf"]` / `data["ruta_red_xml"]`, que luego usa `_build_sap_draft` para llenar `U_VS_ANEXO_PDF` / `U_VS_ANEXO_XML` en el draft SAP B1.
|
||||
- Se invoca desde `_procesar_xmls`, justo después de resolver `data["ruta_pdf"]`.
|
||||
- Guarda las rutas resultantes en `data["ruta_red_pdf"]` / `data["ruta_red_xml"]`, que luego usa `build_sap_draft` para llenar `U_VS_ANEXO_PDF` / `U_VS_ANEXO_XML` en el draft SAP B1.
|
||||
- Se invoca desde `procesar_xmls`, justo después de resolver `data["ruta_pdf"]`.
|
||||
|
||||
---
|
||||
|
||||
@@ -134,23 +140,23 @@ run_pipeline
|
||||
│ └── outlook_utilities.get_emails
|
||||
└── _procesar_un_correo (por cada email)
|
||||
├── database_utilities.get_existing_ids / save_emails
|
||||
├── _descargar_adjuntos
|
||||
├── descargar_adjuntos
|
||||
│ └── outlook_utilities.download_attachments
|
||||
├── _descomprimir
|
||||
│ └── email_utilities.descomprimir_adjuntos
|
||||
├── _filtrar_y_limpiar
|
||||
├── _procesar_pdfs
|
||||
├── filtrar_y_limpiar
|
||||
├── procesar_pdfs
|
||||
│ └── pdf_utilities.extraer_datos_pdf / renombrar_pdf
|
||||
├── _procesar_xmls
|
||||
├── procesar_xmls
|
||||
│ ├── sunat_schema.extraer_datos_xml
|
||||
│ ├── pdf_utilities.extraer_referencias
|
||||
│ └── _copiar_a_red
|
||||
├── _completar_guias
|
||||
├── _validar_guias
|
||||
├── _guardar_resultado
|
||||
│ └── copiar_a_red
|
||||
├── completar_guias
|
||||
├── validar_guias
|
||||
├── guardar_resultado
|
||||
│ └── sunat_schema.split_serie_numero, pdf_utilities.TIPO_MAP
|
||||
├── (por cada factura tipo 01)
|
||||
│ ├── _validate_prices
|
||||
│ ├── validate_prices
|
||||
│ │ ├── sapb1_manager.get_zonas
|
||||
│ │ └── sapb1_manager.get_delivery_notes
|
||||
│ │ ├── hana_manager.get_delivery (fallback si SL no responde;
|
||||
@@ -158,15 +164,15 @@ run_pipeline
|
||||
│ │ └── si el DocEntry vino de OWTR (StockTransfers), resuelve
|
||||
│ │ además la Orden de Venta asociada (Orders vía
|
||||
│ │ U_IDC_NUMOV) para poder validar las líneas FL*
|
||||
│ ├── _build_validation_html
|
||||
│ ├── _obtener_valor_referencial_sap
|
||||
│ ├── build_validation_html
|
||||
│ ├── obtener_valor_referencial_sap
|
||||
│ │ └── hana_manager.obtener_valor_referencial
|
||||
│ ├── _build_valor_referencial_html
|
||||
│ ├── _build_sap_draft
|
||||
│ ├── build_valor_referencial_html
|
||||
│ ├── build_sap_draft
|
||||
│ │ └── sapb1_manager.obtener_condicion_pago (BusinessPartners +
|
||||
│ │ PaymentTermsTypes, para calcular DocDueDate)
|
||||
│ ├── _guardar_draft_json
|
||||
│ ├── guardar_draft_json
|
||||
│ ├── sapb1_manager.create_draft (si todas las líneas coinciden)
|
||||
│ ├── _build_notification_body
|
||||
│ ├── build_notification_body
|
||||
│ └── outlook_utilities.send_email
|
||||
```
|
||||
Reference in new issue
Block a user