""" Fallback Logic — Aplica datos históricos cuando scrapers fallan. """ import logging from typing import Any, Optional logger = logging.getLogger(__name__) SITUACIONES_BCRA = { 1: "Normal", 2: "Con seguimiento especial / Riesgo bajo", 3: "Con problemas / Riesgo medio", 4: "Con alto riesgo de insolvencia / Riesgo alto", 5: "Irrecuperable", 6: "Irrecuperable por disposición técnica", } logger = logging.getLogger(__name__) async def apply_fallbacks( cuit: str, results: dict, cached_report: Optional[dict] = None, ) -> dict: """ Aplica fallbacks desde reporte cacheado anterior cuando scrapers fallan. Args: cuit: CUIT consultado results: Resultados de scrapers actuales (puede tener errores) cached_report: Reporte cacheado anterior (ya parseado a dict) Returns: dict con datos combinados (actuales + fallback) """ if not cached_report: logger.debug(f"No cached report for fallback: {cuit}") return {r.name: r.data for r in results.values() if r.data} merged = {} for name, result in results.items(): if result.data: merged[name] = result.data continue # Scraper falló - intentar fallback cached_key = name if name in cached_report: cached_data = cached_report[name] if cached_data: logger.info(f"[FALLBACK] Using cached data for {name} ({cuit})") merged[name] = cached_data else: merged[name] = {} else: merged[name] = {} # Fallback específico BCRA con lógica de negocio if "bcra" not in merged or not merged["bcra"]: merged["bcra"] = _bcra_fallback(cached_report) return merged def _bcra_fallback(cached_report: Optional[dict]) -> dict: """Aplica lógica de fallback específica para BCRA.""" if not cached_report or "bcra" not in cached_report: return { "denominacion": "", "bcra_situacion_actual": 1, "bcra_situacion_descripcion": SITUACIONES_BCRA[1], "bcra_historial": [], "bcra_total_deuda_miles": 0.0, "bcra_dias_atraso_max": 0, "cheques_rechazados": [], "tiene_deuda": False, } old = cached_report["bcra"] if not isinstance(old, dict): return {"bcra_situacion_actual": 1} # Si la situación histórica es peor (mayor número), usar esa # Si la actual falló, usar la histórica situacion_actual = old.get("bcra_situacion_actual", 1) return { "denominacion": old.get("denominacion", ""), "bcra_situacion_actual": situacion_actual, "bcra_situacion_descripcion": SITUACIONES_BCRA.get(situacion_actual, "Normal"), "bcra_historial": old.get("bcra_historial", []), "bcra_total_deuda_miles": old.get("bcra_total_deuda_miles", 0.0), "bcra_dias_atraso_max": old.get("bcra_dias_atraso_max", 0), "cheques_rechazados": old.get("cheques_rechazados", []), "tiene_deuda": old.get("tiene_deuda", False), } async def apply_fallbacks_to_person_report( cuit: str, raw_results: dict, cached_report: Optional[dict] = None, ) -> dict: """ Aplica fallbacks a resultados de reporte persona. Retorna datos listos para build_person_report. """ merged = await apply_fallbacks(cuit, raw_results, cached_report) return merged