Actualizar backend/services.py
This commit is contained in:
@@ -1033,12 +1033,66 @@ def usuarios_actualizar_rol(user_id, rol):
|
|||||||
sb.table("perfiles").update({"rol": rol}).eq("id", user_id).execute()
|
sb.table("perfiles").update({"rol": rol}).eq("id", user_id).execute()
|
||||||
return {"status": "ok"}
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
def usuarios_actualizar_email(user_id, email):
|
||||||
|
"""Cambia el correo de un usuario existente (Supabase Auth)."""
|
||||||
|
sb = _sb()
|
||||||
|
sb.auth.admin.update_user_by_id(user_id, {"email": email, "email_confirm": True})
|
||||||
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
def usuarios_actualizar_password(user_id, password):
|
||||||
|
"""Cambia la contraseña de un usuario existente (Supabase Auth)."""
|
||||||
|
sb = _sb()
|
||||||
|
sb.auth.admin.update_user_by_id(user_id, {"password": password})
|
||||||
|
return {"status": "ok"}
|
||||||
|
|
||||||
def usuarios_eliminar(user_id):
|
def usuarios_eliminar(user_id):
|
||||||
sb = _sb()
|
sb = _sb()
|
||||||
sb.auth.admin.delete_user(user_id)
|
sb.auth.admin.delete_user(user_id)
|
||||||
return {"status": "ok"}
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
|
||||||
|
# ── ROLES Y PERMISOS (tabla 'permisos': rol, modulo, puede_ver) ────────────
|
||||||
|
def roles_modulos_disponibles():
|
||||||
|
"""Lista de módulos existentes (todos los que aparecen en la tabla permisos)."""
|
||||||
|
sb = _sb()
|
||||||
|
res = sb.table("permisos").select("modulo").execute()
|
||||||
|
mods = sorted({str(r.get("modulo", "")).strip() for r in (res.data or []) if r.get("modulo")})
|
||||||
|
return {"modulos": mods}
|
||||||
|
|
||||||
|
def roles_listar():
|
||||||
|
"""Devuelve todos los roles con la lista de módulos que puede ver cada uno."""
|
||||||
|
sb = _sb()
|
||||||
|
res = sb.table("permisos").select("rol,modulo,puede_ver").execute()
|
||||||
|
por_rol = {}
|
||||||
|
for r in (res.data or []):
|
||||||
|
rol = str(r.get("rol", "")).strip()
|
||||||
|
if not rol:
|
||||||
|
continue
|
||||||
|
por_rol.setdefault(rol, [])
|
||||||
|
if r.get("puede_ver"):
|
||||||
|
por_rol[rol].append(str(r.get("modulo", "")).strip())
|
||||||
|
return {"roles": [{"rol": k, "modulos": sorted(v)} for k, v in sorted(por_rol.items())]}
|
||||||
|
|
||||||
|
def rol_guardar(rol, modulos):
|
||||||
|
"""Crea o actualiza un rol: borra sus filas y reinserta una por módulo marcado."""
|
||||||
|
sb = _sb()
|
||||||
|
rol = str(rol or "").strip().upper()
|
||||||
|
if not rol:
|
||||||
|
return {"status": "error", "msg": "Nombre de rol vacío"}
|
||||||
|
sb.table("permisos").delete().eq("rol", rol).execute()
|
||||||
|
registros = [{"rol": rol, "modulo": str(m).strip(), "puede_ver": True}
|
||||||
|
for m in (modulos or []) if str(m).strip()]
|
||||||
|
if registros:
|
||||||
|
sb.table("permisos").insert(registros).execute()
|
||||||
|
return {"status": "ok", "rol": rol, "modulos": len(registros)}
|
||||||
|
|
||||||
|
def rol_eliminar(rol):
|
||||||
|
"""Borra un rol y todos sus permisos."""
|
||||||
|
sb = _sb()
|
||||||
|
sb.table("permisos").delete().eq("rol", str(rol or "").strip().upper()).execute()
|
||||||
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
|
||||||
# ── VENDEDORES MANUALES (Comisiones, en Supabase) ──────────────────────────
|
# ── VENDEDORES MANUALES (Comisiones, en Supabase) ──────────────────────────
|
||||||
# ── CONFIG MENSUAL COMISIONES (IMP_TC, META, COMISIÓN por tipo de programa) ──
|
# ── CONFIG MENSUAL COMISIONES (IMP_TC, META, COMISIÓN por tipo de programa) ──
|
||||||
def comisiones_config_listar(ano, mes):
|
def comisiones_config_listar(ano, mes):
|
||||||
@@ -1158,3 +1212,73 @@ def comisiones_override_restaurar(num_matricula):
|
|||||||
cache_invalidate("ventas")
|
cache_invalidate("ventas")
|
||||||
cache_invalidate("comisiones_det_todos")
|
cache_invalidate("comisiones_det_todos")
|
||||||
return {"status": "ok"}
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
|
||||||
|
# ── HISTORIAL DE ESTADO DE ASESORES (Chatwoot -> historial_estado_asesor) ──
|
||||||
|
def registrar_estado_asesores():
|
||||||
|
"""Lee el estado actual de cada agente en Chatwoot (account_users) y, si cambió
|
||||||
|
respecto a lo último guardado, inserta una fila en historial_estado_asesor.
|
||||||
|
availability: 0 = ON (conectado), 1 = OFF (desconectado)."""
|
||||||
|
dm = get_dm()
|
||||||
|
conn = dm.get_pg_connection()
|
||||||
|
if conn is None:
|
||||||
|
return {"status": "error", "msg": "sin conexion postgre"}
|
||||||
|
try:
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute("""
|
||||||
|
SELECT u.name, u.uid, au.availability, au.updated_at
|
||||||
|
FROM account_users au
|
||||||
|
JOIN users u ON au.user_id = u.id
|
||||||
|
WHERE u.uid LIKE '%@escueladerefrigeracion.edu.pe'
|
||||||
|
""")
|
||||||
|
actuales = cur.fetchall()
|
||||||
|
|
||||||
|
cur.execute("""
|
||||||
|
SELECT DISTINCT ON (email) email, accion
|
||||||
|
FROM historial_estado_asesor
|
||||||
|
ORDER BY email, fecha_hora DESC
|
||||||
|
""")
|
||||||
|
ultimo = {r[0]: r[1] for r in cur.fetchall()}
|
||||||
|
|
||||||
|
nuevos = 0
|
||||||
|
for (name, email, avail, updated_at) in actuales:
|
||||||
|
accion = "ON" if int(avail) == 0 else "OFF"
|
||||||
|
if ultimo.get(email) == accion:
|
||||||
|
continue
|
||||||
|
cur.execute("""
|
||||||
|
INSERT INTO historial_estado_asesor (asesor, email, accion, origen, quien, fecha_hora)
|
||||||
|
VALUES (%s, %s, %s, %s, %s, %s)
|
||||||
|
""", (name, email, accion, "CHATWOOT", name, updated_at))
|
||||||
|
nuevos += 1
|
||||||
|
conn.commit()
|
||||||
|
return {"status": "ok", "nuevos": nuevos}
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[historial asesores] {e}")
|
||||||
|
return {"status": "error", "msg": str(e)}
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
def historial_asesor(email, limite=100):
|
||||||
|
"""Devuelve el historial de estados de un asesor (por email), más reciente primero."""
|
||||||
|
dm = get_dm()
|
||||||
|
conn = dm.get_pg_connection()
|
||||||
|
if conn is None:
|
||||||
|
return {"historial": []}
|
||||||
|
try:
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute("""
|
||||||
|
SELECT accion, origen, quien, fecha_hora
|
||||||
|
FROM historial_estado_asesor
|
||||||
|
WHERE email = %s
|
||||||
|
ORDER BY fecha_hora DESC
|
||||||
|
LIMIT %s
|
||||||
|
""", (email, int(limite)))
|
||||||
|
filas = [{"accion": r[0], "origen": r[1], "quien": r[2],
|
||||||
|
"fecha_hora": r[3].isoformat() if r[3] else None} for r in cur.fetchall()]
|
||||||
|
return {"historial": filas}
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[historial_asesor] {e}")
|
||||||
|
return {"historial": []}
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|||||||
Reference in New Issue
Block a user