Files
descarga_factura_transporte/docs/despliegue_windows.md
T
GeorgeandClaude Sonnet 5.5 3b5400018c versión 1.2.1: la diferencia de importes con SAP se redondea a 2 decimales
La comparación abs(a - b) < 0.01 no era fiable por la coma flotante: el mismo
céntimo se aceptaba o rechazaba según el importe (431.41 contra 431.40 se
rechazaba y 624.39 contra 624.38 se aceptaba). pipeline_utils.importes_coinciden
redondea la diferencia a 2 decimales, lo que muestra un comprobante, y admite
hasta 1 céntimo. Se usa en la validación de precios y en la comparación del
valor referencial. Con datos reales de SAP (49 líneas) ningún resultado cambió.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 13:07:28 -05:00

5.7 KiB

Despliegue en Windows (servicio con NSSM)

El demonio (main.py) corre como servicio de Windows gestionado con NSSM: arranca con el servidor, se reinicia solo si se cae y se detiene de forma ordenada. La carpeta deploy/ trae los scripts.

Los scripts de deploy/ se revisaron con el analizador de PowerShell (sintaxis correcta) pero no se ejecutaron en un Windows real. Pruébelos primero en un servidor de pruebas.

Requisitos del servidor

Requisito Detalle
Windows Server 2016 o superior, o Windows 10/11
Python 3.11 o superior, 64 bits (el cliente de SAP HANA, hdbcli, lo requiere)
Git y NSSM git en el PATH y nssm.exe en el PATH (https://nssm.cc)
Red hacia fuera login.microsoftonline.com y graph.microsoft.com (443)
Red hacia SAP Service Layer (SAP_B1_URL, puerto 50000 por defecto) y HANA (HANA_SERVER, puerto 30015)
Ruta de red Acceso de lectura y escritura a RUTA_RED_FACTURACION (recurso UNC)
Cuenta de servicio Una cuenta de dominio, por ejemplo ABERIO\svc_facturas, con acceso a esa ruta de red
Zona horaria El código asume hora de Lima (UTC-5) para la fecha y hora de recepción que ve el proveedor

La cuenta de servicio es importante. Por defecto un servicio corre como LocalSystem, que no ve recursos de red: la copia a la ruta de facturación electrónica fallaría. Use una cuenta con permiso sobre ese recurso.

Instalación

En PowerShell como administrador:

cd C:\apps
git clone https://unasgeorge.vaquita-hadar.ts.net/george/descarga_factura_transporte.git
cd descarga_factura_transporte
git checkout v1.2.1                          # siempre una versión etiquetada, no main

py -3 -m venv venv
venv\Scripts\python -m pip install -r requirements.txt

copy .env.example .env                       # y completar los valores

Complete el .env (cómo obtener las credenciales de Microsoft: configurar_msal.md). Empiece con NOTIFICACION_MODO=prueba: las respuestas van al equipo y no a los proveedores. Defina NOTIFICACION_EQUIPO y LOGO_URL.

Verificar antes de instalar el servicio

venv\Scripts\python tools\verificar_conexiones.py

Revisa, sin modificar nada ni imprimir secretos: el .env, el token y la lectura del buzón de Microsoft Graph, SAP Service Layer, SAP HANA y la ruta de red de facturación (que debe ser accesible y escribible con la cuenta del servicio). Termina con código 1 si algo falla. Opcionalmente, las pruebas (no tocan SAP ni Outlook):

venv\Scripts\python -m pip install pytest==9.1.1
venv\Scripts\python -m pytest -q

Instalar y arrancar el servicio

.\deploy\instalar_servicio.ps1 -Cuenta "ABERIO\svc_facturas"      # pide la contraseña
nssm start descarga_factura_transporte

El script configura: arranque automático, directorio de trabajo del proyecto, reinicio automático a los 30 s si el proceso muere, parada con Ctrl+C (20 s de gracia), rotación de la salida del servicio a 10 MB y las variables PYTHONUTF8=1 y PYTHONIOENCODING=utf-8 (sin ellas los emojis del log dan error en la consola de Windows).

Comprobar que funciona

Get-Service descarga_factura_transporte
Get-Content logs\descarga_factura_transporte.log -Wait -Tail 30

En el log, al arrancar, debe verse 🚀 Demonio iniciado … (versión 1.2.1), y config_validator anuncia el modo de notificación (PRUEBA o REAL).

Operación

Tema Detalle
Logs de la aplicación logs\descarga_factura_transporte.log, rotación diaria, 30 días
Salida del servicio logs\servicio.out.log y servicio.err.log (10 MB, rotan). Mire servicio.err.log si el servicio arranca y se detiene
Cambiar el .env nssm restart descarga_factura_transporte
Horarios HORARIOS en main.py (24 h cubiertas, ver main.md)
Copia de seguridad emails.db guarda los correos procesados y los códigos de seguimiento. Cópielo con el servicio detenido, o con sqlite3 emails.db ".backup respaldo.db"
Espacio en disco adjuntos\ y resultado\ no se limpian solos: planifique una limpieza periódica
Pasar a modo real Cuando el equipo haya validado las respuestas: NOTIFICACION_MODO=real y reiniciar

Actualizar y volver atrás (rollback)

Siempre a una versión etiquetada (ver CHANGELOG):

.\deploy\actualizar.ps1 -Version v1.2.1
.\deploy\actualizar.ps1 -Version v1.2.0       # volver a la anterior

El script detiene el servicio, hace git checkout de la etiqueta, instala las dependencias y arranca de nuevo (aunque algo falle, vuelve a levantar lo que había). No toca el .env ni emails.db. Se niega a actuar si hay cambios locales sin guardar.

Desinstalar

.\deploy\desinstalar_servicio.ps1       # no borra el proyecto, el .env ni emails.db

Problemas frecuentes

Síntoma Causa probable
El servicio arranca y se detiene enseguida Falta el .env, o config_validator rechazó una variable: ver logs\servicio.err.log
Access is denied al copiar a la ruta de red El servicio corre como LocalSystem. Reinstale con -Cuenta o cambie la cuenta en services.msc
UnicodeEncodeError en la salida del servicio Falta PYTHONUTF8=1: reinstale con instalar_servicio.ps1
AADSTS7000222 / AADSTS700016 Secret vencido / CLIENT_ID y TENANT_ID de aplicaciones distintas: ver configurar_msal.md
ConnectTimeout hacia SAP o HANA VPN o firewall: abra el puerto 50000 (Service Layer) y 30015 (HANA) desde el servidor
Los correos llegan sin logo LOGO_URL vacío o no accesible públicamente