modificado para obtener todas las facturas que tiene el casillero de validación vacío, no más de 30 días

This commit is contained in:
George committed 2026-08-07 13:40:04 -05:00
1 parent 22aec163d2
commit 9f2d96e64c
9 files changed
+213 -198

No files matched your search

+42 -52
View File
@@ -3,13 +3,15 @@ import time
from datetime import datetime, timedelta
from dotenv import load_dotenv
import logger_utilities
from logger_manager import get_logger
import sunat_manager
import hana_manager
import sapb1_manager
from constants import ESTADOS_COMPROBANTE
from hana_manager import actualizar_documento_sap
logger = get_logger()
# ============================================================================
config = {}
@@ -147,41 +149,39 @@ def enviar_mensaje_sl(usercode, doc, resultado, schema):
print(f" ┌─ 📩 Enviando Messages a {usercode} ───────────")
# for line in json.dumps(payload, indent=2).splitlines():
# print(f" │ {line}")
logger.info(f" ┌─ 📩 Enviando Messages a {usercode} ───────────")
sapb1_manager.send_message(payload)
print(f" │ ✅ Mensaje enviado a {usercode}")
print(f" └───────────────────────────────────────────────")
logger.info(f" │ ✅ Mensaje enviado a {usercode}")
logger.info(f" └───────────────────────────────────────────────")
# ============================================================================
def procesar_empresa(schema, datos_empresa, modo):
print(f"\n{'='*60}")
print(f"🏢 Procesando empresa: {schema} [{modo}]")
print(f"{'='*60}")
logger.info(f"\n{'='*60}")
logger.info(f"🏢 Procesando empresa: {schema} [{modo}]")
logger.info(f"{'='*60}")
if modo == "rapido":
documentos = hana_manager.obtener_documentos_creados_actualizados_hace_60_minutos(schema, 60)
documentos = hana_manager.obtener_documentos_aun_no_validados_ultimos_30_dias(schema)
else:
documentos = hana_manager.obtener_documentos_fecha_emision_ultimos_8_dias(schema)
if not documentos:
print(f"⚠️ No se encontraron documentos para {schema}")
logger.warning(f"⚠️ No se encontraron documentos para {schema}")
return 0, 0
## documentos = hana_manager.obtener_documentos_creados_hace_x_dias(schema, 8)
print(f"📄 Documentos encontrados: {len(documentos)}")
logger.info(f"📄 Documentos encontrados: {len(documentos)}")
print(f"🔑 Solicitando token SUNAT...")
logger.info(f"🔑 Solicitando token SUNAT...")
token = sunat_manager.token(datos_empresa)
if not token:
print(f"❌ No se obtuvo token para {schema}")
logger.error(f"❌ No se obtuvo token para {schema}")
return 0, len(documentos)
print(f"✅ Token obtenido correctamente")
logger.info(f"✅ Token obtenido correctamente")
sapb1_manager.login()
print(f"✅ Sesión SL establecida para {schema}")
logger.info(f"✅ Sesión SL establecida para {schema}")
ruc_empresa = datos_empresa["Ruc"]
procesados = 0
@@ -189,7 +189,7 @@ def procesar_empresa(schema, datos_empresa, modo):
try:
for idx, doc in enumerate(documentos, start=1):
print(f"\n--- [{idx}/{len(documentos)}] {doc['FolioPref']}-{doc['FolioNum']} ---")
logger.info(f"\n--- [{idx}/{len(documentos)}] {doc['FolioPref']}-{doc['FolioNum']} ---")
try:
payload = {
@@ -203,15 +203,15 @@ def procesar_empresa(schema, datos_empresa, modo):
if doc["FolioPref"] and doc["FolioPref"][0].isalpha():
payload["monto"] = str(doc["DocTotal"])
print(f" ┌─ 📤 Enviando a SUNAT {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}─────────────────────")
logger.info(f" ┌─ 📤 Enviando a SUNAT {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}─────────────────────")
for line in json.dumps(payload, indent=2).splitlines():
print(f" │ {line}")
print(f" └────────────────────────────────────────────")
logger.info(f" │ {line}")
logger.info(f" └────────────────────────────────────────────")
resultado = sunat_manager.validar_comprobante(token, ruc_empresa, payload)
print(f" ┌─ 📥 Respuesta de SUNAT {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}───────────────────")
logger.info(f" ┌─ 📥 Respuesta de SUNAT {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}───────────────────")
for line in json.dumps(resultado, indent=2).splitlines():
print(f" │ {line}")
print(f" └────────────────────────────────────────────")
logger.info(f" │ {line}")
logger.info(f" └────────────────────────────────────────────")
registro = {
"objtype": str(doc["ObjType"]),
@@ -223,13 +223,13 @@ def procesar_empresa(schema, datos_empresa, modo):
if resultado.get("success"):
estado_cp = resultado.get("data", {}).get("estadoCp", "")
print(f"✅ OK - Estado CP: {estado_cp}")
logger.info(f"✅ OK - Estado CP: {estado_cp}")
if estado_cp not in ["1","3"] and doc.get("UserCode"):
enviar_mensaje_sl(doc["UserCode"], doc, resultado, schema)
else:
print(f"⚠️ Falló - {resultado.get('message', 'Error desconocido')}")
logger.warning(f"⚠️ Falló - {resultado.get('message', 'Error desconocido')}")
procesados += 1
@@ -237,11 +237,11 @@ def procesar_empresa(schema, datos_empresa, modo):
time.sleep(2)
except Exception as e:
print(f"❌ Error procesando documento: {e}")
logger.error(f"❌ Error procesando documento: {e}")
errores += 1
finally:
sapb1_manager.logout()
print(f"🔒 Sesión SL cerrada para {schema}")
logger.info(f"🔒 Sesión SL cerrada para {schema}")
return procesados, errores
@@ -249,7 +249,7 @@ def procesar_empresa(schema, datos_empresa, modo):
def procesar_todas_empresas(inicio_ciclo, modo):
empresas = cargar_empresas()
print(f"📋 Empresas cargadas: {len(empresas)}")
logger.info(f"📋 Empresas cargadas: {len(empresas)}")
total_procesados = 0
total_errores = 0
@@ -258,7 +258,7 @@ def procesar_todas_empresas(inicio_ciclo, modo):
schema = empresa["CompanyDB"]
if empresa.get("Locked") == "Y":
print(f"\n⏭️ Empresa {schema} está bloqueada (LOCKED=Y), saltando...")
logger.warning(f"\n⏭️ Empresa {schema} está bloqueada (LOCKED=Y), saltando...")
continue
sapb1_manager._sap_credentials = {
@@ -272,29 +272,25 @@ def procesar_todas_empresas(inicio_ciclo, modo):
total_procesados += p
total_errores += e
except Exception as ex:
print(f"❌ Error procesando empresa {schema}: {ex}")
logger.error(f"❌ Error procesando empresa {schema}: {ex}")
total_errores += 1
duracion_ciclo = datetime.now() - inicio_ciclo
print(f"\n📊 CICLO COMPLETADO en {str(duracion_ciclo).split('.')[0]}")
print(f" ✅ {total_procesados} procesados | ❌ {total_errores} errores")
logger.info(f"\n📊 CICLO COMPLETADO en {str(duracion_ciclo).split('.')[0]}")
logger.info(f" ✅ {total_procesados} procesados | ❌ {total_errores} errores")
return total_procesados, total_errores
# ============================================================================
def main():
log_path = logger_utilities.setup_logger()
_ultima_limpieza = None
load_dotenv(dotenv_path=".env")
cargar_programacion()
print("=" * 60)
print("🚀 Demonio iniciado")
print(f"📄 Log guardado en: {log_path}")
print("Servicio iniciado")
print("=" * 60)
logger.info("=" * 60)
logger.info("🚀 Demonio iniciado")
logger.info("Servicio iniciado")
logger.info("=" * 60)
while True:
@@ -302,15 +298,9 @@ def main():
cargar_programacion()
logger_utilities.rotar_log()
if _ultima_limpieza != inicio_ciclo.date():
logger_utilities.limpiar_logs_antiguos(dias=7)
_ultima_limpieza = inicio_ciclo.date()
if inicio_ciclo.weekday() not in obtener_dias_activos():
dormir = segundos_hasta_proximo_dia_activo(inicio_ciclo)
print(
logger.info(
f"\n[{inicio_ciclo:%Y-%m-%d %H:%M:%S}] "
f"Día no activo (weekday={inicio_ciclo.weekday()}).\n"
f"Próxima ejecución: "
@@ -325,7 +315,7 @@ def main():
intervalo, modo = resultado
print(
logger.info(
f"\n[{inicio_ciclo:%Y-%m-%d %H:%M:%S}] "
f"Iniciando ciclo [{modo}] (cada {intervalo}s)"
)
@@ -335,14 +325,14 @@ def main():
duracion = (datetime.now() - inicio_ciclo).total_seconds()
if duracion > intervalo:
print(
logger.warning(
f"⚠️ El ciclo demoró {duracion:.1f}s "
f"(intervalo configurado {intervalo}s)"
)
dormir = max(0, intervalo - duracion)
print(f"💤 Próximo ciclo [{modo}] en {dormir:.0f}s...")
logger.info(f"💤 Próximo ciclo [{modo}] en {dormir:.0f}s...")
else:
@@ -350,7 +340,7 @@ def main():
despertar = inicio_ciclo + timedelta(seconds=dormir)
print(
logger.info(
f"\n[{inicio_ciclo:%Y-%m-%d %H:%M:%S}] "
f"Fuera del horario.\n"
f"Próxima ejecución: {despertar:%Y-%m-%d %H:%M:%S}"
@@ -363,4 +353,4 @@ if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\n🛑 Demonio detenido por el usuario.")
logger.info("\n\n🛑 Demonio detenido por el usuario.")