# diag_tiempo_diana_ago10.py # Detalle del 10 de AGOSTO 2026 para DIANA CHAVEZ: asignados, hora de asignacion, # hora de respuesta y minutos laborales (misma logica del dashboard). Promedio al final. # Ejecutar en backend/: python diag_tiempo_diana_ago10.py from datetime import datetime, timedelta, date from data_manager_v2 import DataManager ANO, MES, DIA = 2026, 8, 10 NOMBRE = "DIANA" # user_name contiene esto dm = DataManager() asig = dm.traer_asignacion_respuesta() act_rows = dm.traer_actividad_asesores() uid2name = {} for r in asig: if r.get("user_id") is not None: uid2name[r["user_id"]] = r.get("user_name") or "" from collections import defaultdict act = defaultdict(lambda: defaultdict(int)) for a in act_rows: uid = a.get("user_id"); ts = a.get("created_at") if uid not in uid2name or not isinstance(ts, datetime): continue nom = uid2name[uid].upper(); d = ts.date(); h = ts.hour + ts.minute/60.0 key = (nom, d) if d.weekday() == 6: continue if d.weekday() == 5: if 9 <= h < 13: act[key]["sab_manana"] += 1 elif 14 <= h < 18: act[key]["sab_tarde"] += 1 else: if 13 <= h < 18: act[key]["tarde"] += 1 elif 18 <= h < 22: act[key]["noche"] += 1 def turno_dia(nom, d): if d.weekday() == 6: return None fr = act.get((nom, d)) if not fr: return None if d.weekday() == 5: m = fr.get("sab_manana",0); t = fr.get("sab_tarde",0) if m==0 and t==0: return None return [(9,13)] if m>=t else [(14,18)] t = fr.get("tarde",0); n = fr.get("noche",0) if t==0 and n==0: return None return [(9,13),(18,22)] if n>t else [(9,13),(14,18)] def _dt(d, hh): return datetime(d.year,d.month,d.day) + timedelta(hours=hh) def mins_laborales(nom, t1, t2): if not isinstance(t1,datetime) or not isinstance(t2,datetime) or t2<=t1: return 0 total=0.0; cur=t1; saltos=0 while cur < t2 and saltos < 60: d=cur.date(); bloques=turno_dia(nom,d) if not bloques: cur=_dt(d,24); saltos+=1; continue for (hi,hf) in bloques: ini=_dt(d,hi); fin=_dt(d,hf) if t2<=ini: break if cur>=fin: continue a=max(cur,ini); b=min(t2,fin) if b>a: total += (b-a).total_seconds()/60.0 cur=fin if cur>=t2: break if cur.date()==d: cur=_dt(d,24); saltos+=1 return round(total) # filtrar Diana + 10 agosto por fecha de asignacion filas=[] for r in asig: nom=(r.get("user_name") or "") if NOMBRE not in nom.upper(): continue t1=r.get("created_at") if not isinstance(t1,datetime): continue if not (t1.year==ANO and t1.month==MES and t1.day==DIA): continue filas.append(r) d1=date(ANO,MES,DIA) turno=None if filas: tt=turno_dia((filas[0].get("user_name") or "").upper(), d1) turno="Turno 1 (9-18)" if tt==[(9,13),(14,18)] else ("Turno 2 (9-13+18-22)" if tt==[(9,13),(18,22)] else str(tt)) print(f"\n=== DIANA CHAVEZ — {DIA:02d}/{MES:02d}/{ANO} ===") print(f"Turno detectado ese dia: {turno}") print(f"Total asignados ese dia: {len(filas)}\n") print(f"{'#':3} {'telefono':13} {'asignado':17} {'respondio':17} {'min':>5}") print("-"*62) resp=0; sinr=0; suma=0 for i,r in enumerate(sorted(filas, key=lambda x: x['created_at']),1): t1=r['created_at']; t2=r.get('respuesta_fecha') nom_up=(r.get('user_name') or '').upper() tel=r.get('telefono',''); a_str=t1.strftime('%H:%M:%S') if not isinstance(t2,datetime): sinr+=1 print(f"{i:3} {tel:13} {a_str:17} {'':17} {'':>5}") # sin respuesta -> vacio continue m=mins_laborales(nom_up,t1,t2); resp+=1; suma+=m print(f"{i:3} {tel:13} {a_str:17} {t2.strftime('%H:%M:%S'):17} {m:>5}") print("-"*62) print(f"Respondidos: {resp} | Sin responder: {sinr}") print(f"Promedio (solo respondidos): {round(suma/resp) if resp else 0} min")