# backend/export_base_junta.py """ Une los leads de Postgre (Fact_Leads_Procesados, mapa de campañas) + Supabase, deduplica por teléfono quedándose con el MÁS ANTIGUO (desempate: Pauta_wsp_face), y exporta un Excel con: Telefono, Canal, Fecha Creada. Uso: py -3.12 export_base_junta.py """ import os from datetime import datetime from dotenv import load_dotenv from data_manager_v2 import DataManager load_dotenv() # Canal preferido en caso de empate de fecha CANAL_PREFERIDO = "Pauta_wsp_face" def _norm_tel(v): s = str(v or "") for x in ("+51", "+", " ", "-", "(", ")"): s = s.replace(x, "") return s.strip() def _txt(v): """Texto en MAYÚSCULAS; '-' o vacío → ''.""" s = str(v or "").strip() if s == "-": s = "" return s.upper() def _to_dt(v): if v is None: return None if isinstance(v, datetime): return v s = str(v)[:19] for fmt in ("%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d", "%d/%m/%Y", "%d-%m-%Y"): try: return datetime.strptime(s[:len(fmt) + 2] if "%H" in fmt else s[:10], fmt) except Exception: pass return None def traer_postgre(dm): """Mismos leads que Fact_Leads_Procesados (mapa de campañas): tel, fecha, canal(origen).""" filas = dm.traer_leads_chatwoot() # ya aplica el mapa de campañas y trae 'origen' out = [] for f in filas: tel = _norm_tel(f.get("telefono")) if not tel: continue out.append({ "telefono": tel, "fecha": _to_dt(f.get("fecha_creada")), "canal": _txt(f.get("origen")), "sede": _txt(f.get("sede")), "programa": _txt(f.get("programa")), "codigo": _txt(f.get("codigo")), }) return out def traer_supabase(dm): """Lee la tabla de Supabase con columnas: telefono, fechacreada, canal.""" try: from supabase import create_client url = os.getenv("SUPABASE_URL", "") key = os.getenv("SUPABASE_KEY", "") if not url or not key: print("⚠️ Falta SUPABASE_URL / SUPABASE_KEY en .env — se omite Supabase") return [] sb = create_client(url, key) tabla = os.getenv("SUPABASE_TABLA_LEADS", "leads") # ajustar nombre real si difiere res = sb.table(tabla).select("Telefono,Fechacreada,Canal,Sede,Programa,Codigo").execute() out = [] for r in (res.data or []): tel = _norm_tel(r.get("Telefono")) if not tel: continue out.append({ "telefono": tel, "fecha": _to_dt(r.get("Fechacreada")), "canal": _txt(r.get("Canal")), "sede": _txt(r.get("Sede")), "programa": _txt(r.get("Programa")), "codigo": _txt(r.get("Codigo")), }) return out except Exception as e: print(f"⚠️ Error leyendo Supabase: {e}") return [] def main(): dm = DataManager() print("Trayendo Postgre (Fact_Leads_Procesados)...") pg = traer_postgre(dm) print(f" Postgre: {len(pg)} filas") print("Trayendo Supabase...") sup = traer_supabase(dm) print(f" Supabase: {len(sup)} filas") todos = pg + sup print(f"Total combinado (con repetidos): {len(todos)}") # Dedup por teléfono: quedarse con el MÁS ANTIGUO. # Desempate (misma fecha): preferir CANAL_PREFERIDO. FUTURO = datetime(9999, 1, 1) mejor = {} for r in todos: tel = r["telefono"] f = r["fecha"] or FUTURO actual = mejor.get(tel) if actual is None: mejor[tel] = r continue fa = actual["fecha"] or FUTURO if f < fa: mejor[tel] = r elif f == fa: # empate de fecha → preferir el canal preferido if r["canal"] == CANAL_PREFERIDO and actual["canal"] != CANAL_PREFERIDO: mejor[tel] = r final = list(mejor.values()) print(f"Teléfonos únicos (sin repetir): {len(final)}") # Exportar a Excel import openpyxl wb = openpyxl.Workbook() ws = wb.active ws.title = "Base_Junta" ws.append(["Telefono", "Canal", "Fecha Creada", "Sede", "Programa", "Codigo"]) for r in sorted(final, key=lambda x: (x["fecha"] or FUTURO)): fecha = r["fecha"].strftime("%d/%m/%Y") if r["fecha"] and r["fecha"] != FUTURO else "" ws.append([r["telefono"], r["canal"], fecha, r.get("sede", ""), r.get("programa", ""), r.get("codigo", "")]) salida = os.path.join(os.path.dirname(__file__), "base_junta.xlsx") wb.save(salida) print(f"\n✅ Exportado: {salida}") print(f" Filas: {len(final)}") if __name__ == "__main__": main()