Initial commit - dashboard leads
This commit is contained in:
131
backend/diag_tiempo_diana_jul1.py
Normal file
131
backend/diag_tiempo_diana_jul1.py
Normal file
@@ -0,0 +1,131 @@
|
||||
# diag_tiempo_diana_jul1.py
|
||||
# Detalle del 1 de JULIO 2026 para DIANA CHAVEZ: los asignados, hora de asignacion,
|
||||
# si respondieron, hora de respuesta y minutos laborales (misma logica del dashboard).
|
||||
# Ejecutar en backend/: python diag_tiempo_diana_jul1.py
|
||||
from datetime import datetime, timedelta
|
||||
from data_manager_v2 import DataManager
|
||||
|
||||
ANO, MES, DIA = 2026, 7, 1
|
||||
NOMBRE = "DIANA" # busca por apellido/nombre que contenga esto en user_name
|
||||
|
||||
dm = DataManager()
|
||||
|
||||
# --- 1) asignacion + respuesta (mismo query del dashboard) ---
|
||||
asig = dm.traer_asignacion_respuesta()
|
||||
# --- 2) actividad de asesores (para detectar turno) ---
|
||||
act_rows = dm.traer_actividad_asesores()
|
||||
|
||||
# mapa user_id -> user_name
|
||||
uid2name = {}
|
||||
for r in asig:
|
||||
if r.get("user_id") is not None:
|
||||
uid2name[r["user_id"]] = r.get("user_name") or ""
|
||||
|
||||
# actividad por (user_name_upper, fecha) -> franja -> conteo
|
||||
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)
|
||||
|
||||
def es_refri_t1(nom, ts):
|
||||
d=ts.date()
|
||||
if d.weekday()>=5: return False
|
||||
fr=act.get((nom,d))
|
||||
if not fr: return False
|
||||
t=fr.get("tarde",0); n=fr.get("noche",0)
|
||||
es_t1 = not (n>t) and (t>0 or n>0)
|
||||
h=ts.hour+ts.minute/60.0
|
||||
return es_t1 and (13<=h<14)
|
||||
|
||||
# --- filtrar Diana + 1 julio (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)
|
||||
|
||||
# turno detectado ese dia
|
||||
from datetime import date
|
||||
d1 = date(ANO,MES,DIA)
|
||||
turno = None
|
||||
if filas:
|
||||
nom_up = (filas[0].get("user_name") or "").upper()
|
||||
tt = turno_dia(nom_up, 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} nota")
|
||||
print("-"*75)
|
||||
resp=0; sinr=0; refri=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 es_refri_t1(nom_up, t1):
|
||||
refri+=1
|
||||
r_str = t2.strftime('%H:%M:%S') if isinstance(t2, datetime) else '(sin resp)'
|
||||
print(f"{i:3} {tel:13} {a_str:17} {r_str:17} {'-':>5} EXCLUIDO (refrigerio 13-14)")
|
||||
continue
|
||||
if not isinstance(t2,datetime):
|
||||
sinr+=1
|
||||
print(f"{i:3} {tel:13} {a_str:17} {'(sin resp)':17} {'-':>5} no respondio")
|
||||
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("-"*75)
|
||||
print(f"Respondidos: {resp} | Sin responder: {sinr} | Excluidos refrigerio: {refri}")
|
||||
print(f"Suma minutos: {suma} | Promedio: {round(suma/resp) if resp else 0} min")
|
||||
Reference in New Issue
Block a user