""" core.py — Pipeline funcional del servicio de descarga CPE (Sovos). Reescribe las funciones de la plantilla: * describir_servicio() : banner del log. * obtener_datos() : consulta HANA multi-schema. * procesar_y_descargar(): descarga PDF/XML de Sovos y marca en HANA. """ import os import json from pathlib import Path from dotenv import load_dotenv from logger_manager import get_logger from hana_manager import obtener_pendientes, cerrar_conexion, obtener_config_hana from descargador_sovos import descargar_documentos_pendientes from smb_transfer import get_mount_base, transferir_a_smb # ============================================================================ load_dotenv() logger = get_logger("core") CONFIG_FILE = Path(os.getenv("CONFIG_PATH", Path(__file__).parent / "config.json")) # ============================================================================ def _cargar_config(path: str | None = None) -> dict: p = Path(path) if path else CONFIG_FILE with open(p, encoding="utf-8") as f: return json.load(f) CFG = _cargar_config() def empresas_activas(cfg: dict) -> list[dict]: return [e for e in cfg.get("empresas", []) if not e.get("locked", False)] # ============================================================================ # Específico del servicio # ============================================================================ def describir_servicio() -> str: return "DESCARGA COMPROBANTES ELECTRÓNICOS (SUNAT)" def obtener_datos(empresa: dict) -> list[dict]: schema = empresa["schema"] rucs = CFG.get("rucs", []) dias = CFG.get("consulta", {}).get("dias", 240) logger.info(f" 💾 Consultando HANA schema={schema}") return obtener_pendientes(schema, rucs, dias) def procesar_y_descargar(datos: list[dict], dir_empresa: Path) -> dict: return descargar_documentos_pendientes(datos, dir_empresa) # ============================================================================ # Pipeline (genérico) # ============================================================================ def ejecutar(cfg: dict | None = None): cfg = cfg if cfg is not None else CFG base = Path(cfg.get("files", {}).get("path", "downloads")).resolve() activas = empresas_activas(cfg) logger.info("=" * 60) logger.info(f"🚀 {describir_servicio()}") cfg_hana = obtener_config_hana() logger.info(f"💾 HANA: {cfg_hana['host']}:{cfg_hana['port']}") logger.info("=" * 60) logger.info(f"🏢 Empresas configuradas: {len(cfg.get('empresas', []))}") logger.info(f"📁 Descargas base: {base}") if not activas: logger.info("⏭️ No hay empresas activas (todas LOCKED). Fin.") return # LOOP 1: datos + procesamiento por empresa for emp in activas: nombre = emp["nombre"] dir_empresa = base / nombre logger.info("#" * 60) logger.info(f"# 🏢 Empresa: {nombre}") logger.info("#" * 60) datos = obtener_datos(emp) if not datos: logger.info(" ✅ No hay documentos pendientes") continue logger.info(f" 📄 Documentos pendientes obtenidos: {len(datos)}") procesar_y_descargar(datos, dir_empresa) # LOOP 2: transferencia a carpeta compartida (conserva si no está montada) logger.info("=" * 60) logger.info("🔁 Transferencia a carpeta compartida (SMB)") logger.info("=" * 60) mount_base = get_mount_base() auto_mount = os.getenv("SMB_AUTO_MOUNT", "false").lower() == "true" logger.info(f" Montaje base: {mount_base} | automontaje: {auto_mount}") resultados = transferir_a_smb(activas, mount_base, auto_mount) logger.info("📊 Resumen transferencias:") for r in resultados: logger.info(f" • {r['empresa']}: {r['estado']}") logger.info("\n👋 Proceso finalizado.") cerrar_conexion() # ============================================================================ if __name__ == "__main__": ejecutar() # ============================================================================