se responde al remitente con las plantillas de aceptado/rechazado
El sistema contesta a quien envió el correo con la plantilla que corresponda. Por defecto (NOTIFICACION_MODO=prueba) la respuesta va solo al equipo con el asunto "[PRUEBA → remitente]"; en modo real va al remitente con copia oculta al equipo. El correo técnico (tablas de SAP, JSON) pasa a ir solo al equipo. - respuesta_proveedor.py: contextos de las plantillas, envío y protecciones (remitente desconocido o sin dominio, propio buzón, no-reply, mensajes automáticos, respuestas a notificaciones, límite de 3 por remitente/24 h). - observaciones.py: motivos de rechazo con título, filas y cómo corregir (borrador de textos); también para correos sin comprobante válido. - Un error de SAP/HANA o un fallo inesperado no se le comunica al proveedor y ya no tumba el ciclo; "guía no encontrada" exige que HANA responda. - outlook_utilities: es_mensaje_automatico y copia oculta en send_email. - seguimiento: notificacion_destinatario (con migración) y contar_respuestas_correo. - config_validator anuncia el modo activo; documentación y pruebas. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
af9e3961e5
commit
4deb9d4e4d
22 files changed
+1660
-146
No files matched your search
+30
-1
@@ -11,6 +11,35 @@ from pipeline_utils import log
|
||||
|
||||
|
||||
# ============================================================================
|
||||
def hay_error_de_consulta(resultados_val: list[dict]) -> str | None:
|
||||
"""
|
||||
Devuelve el detalle del primer error de consulta a SAP que dejó ``validate_prices``
|
||||
(una guía cuya consulta lanzó excepción), o None si no hubo ninguno. Un error de
|
||||
consulta es una falla nuestra: no debe confundirse con una guía inexistente.
|
||||
"""
|
||||
for resultado in resultados_val:
|
||||
for item in resultado.get("guias_lt", []):
|
||||
if item.get("error"):
|
||||
return item["error"]
|
||||
return None
|
||||
|
||||
|
||||
def hana_disponible() -> bool:
|
||||
"""
|
||||
True si se puede abrir una conexión a SAP HANA. ``get_delivery_notes`` devuelve ``[]``
|
||||
tanto si una guía no existe como si HANA está caído; antes de decirle a un proveedor
|
||||
que una guía "no se encontró" conviene descartar que haya sido una caída.
|
||||
"""
|
||||
conexion = hana_manager.get_connection()
|
||||
if conexion is None:
|
||||
return False
|
||||
try:
|
||||
conexion.close()
|
||||
except Exception:
|
||||
pass
|
||||
return True
|
||||
|
||||
|
||||
def calcular_fecha_vencimiento(fecha_base: str, condicion_pago: dict | None) -> str:
|
||||
"""
|
||||
Calcula la fecha de vencimiento sumando a ``fecha_base`` los días de
|
||||
@@ -341,7 +370,7 @@ def validate_prices(factura: dict) -> tuple[bool, list[dict]]:
|
||||
all_wh.update(wh_set)
|
||||
except Exception as ex:
|
||||
log(f"⚠️ Guía {codigo_guia}: error al consultar SAP - {ex}", 2, severity=logging.WARNING)
|
||||
guias_lt.append({"guia": guia, "line_total": 0.0, "warehouse_code": "A-CENTRA", "weight1": 0.0, "quantity": 0.0, "price_after_vat_sum": 0.0, "zona": "", "draft_quantity": 0, "draft_price": 0.0})
|
||||
guias_lt.append({"guia": guia, "line_total": 0.0, "warehouse_code": "A-CENTRA", "weight1": 0.0, "quantity": 0.0, "price_after_vat_sum": 0.0, "zona": "", "draft_quantity": 0, "draft_price": 0.0, "error": str(ex)})
|
||||
all_ok = False
|
||||
|
||||
sap_total = sum(item["line_total"] for item in guias_lt)
|
||||
|
||||
Reference in new issue
Block a user