From ee44f166b112360c90310b39a9e949b652f1c904 Mon Sep 17 00:00:00 2001 From: Administrator Date: Tue, 1 Sep 2026 12:13:07 -0500 Subject: [PATCH] Actualizar backend/services.py --- backend/services.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/backend/services.py b/backend/services.py index c0d1199..5bbacdb 100644 --- a/backend/services.py +++ b/backend/services.py @@ -281,9 +281,9 @@ def cobranza(ano, mes, sectorista="TODOS", agrupacion="SEDE", sede_filtro="TODOS def _load(): dm = get_dm() logic = CobranzaLogic(dm) - # Matrículas POR RETIRAR (Supabase) para calcular la columna SALDO POR RETIRAR + # Matrículas POR RETIRAR (Supabase) de ESTE mes/año, para la columna SALDO POR RETIRAR try: - mats_retirar = set(alumnos_por_retirar().get("matriculas", [])) + mats_retirar = set(alumnos_por_retirar(ano, mes).get("matriculas", [])) except Exception: mats_retirar = set() filas = logic.obtener_datos_tabla(str(ano), str(mes), sectorista, agrupacion, sede_filtro, prog_filtro, venc_hasta, mats_retirar) @@ -719,37 +719,43 @@ def _sb(): return dm.supabase_client # ── Estado/observaciones por alumno (tabla cobranza_estado_alumno) ── -def alumno_estado_obtener(matricula): - """Devuelve {estado, observaciones} de un alumno. Si no existe, valores por defecto.""" +def alumno_estado_obtener(matricula, ano, mes): + """Devuelve {estado, observaciones} de un alumno en (ano, mes). Default si no existe.""" sb = _sb() - res = sb.table("cobranza_estado_alumno").select("*").eq("matricula", str(matricula)).execute() + res = (sb.table("cobranza_estado_alumno").select("*") + .eq("matricula", str(matricula)).eq("ano", int(ano)).eq("mes", int(mes)) + .execute()) fila = (res.data or [None])[0] if not fila: return {"estado": "EN CURSO", "observaciones": []} return {"estado": fila.get("estado") or "EN CURSO", "observaciones": fila.get("observaciones") or []} -def alumno_estado_guardar(matricula, estado, observaciones, usuario=None): - """Guarda (upsert) el estado y la lista de observaciones del alumno.""" +def alumno_estado_guardar(matricula, ano, mes, estado, observaciones, usuario=None): + """Guarda (upsert) el estado y observaciones del alumno en (ano, mes).""" sb = _sb() from datetime import datetime, timezone payload = { "matricula": str(matricula), + "ano": int(ano), + "mes": int(mes), "estado": estado or "EN CURSO", "observaciones": observaciones or [], "actualizado_en": datetime.now(timezone.utc).isoformat(), "actualizado_por": usuario or None, } - sb.table("cobranza_estado_alumno").upsert(payload).execute() + sb.table("cobranza_estado_alumno").upsert(payload, on_conflict="matricula,ano,mes").execute() # Invalidar la tabla de cobranza para recalcular la columna SALDO POR RETIRAR from cache_manager import cache_invalidate cache_invalidate("cobranza") return {"status": "ok"} -def alumnos_por_retirar(): - """Lista de matrículas marcadas como POR RETIRAR (para tachar la fila en la tabla).""" +def alumnos_por_retirar(ano, mes): + """Matrículas marcadas POR RETIRAR en (ano, mes).""" sb = _sb() - res = sb.table("cobranza_estado_alumno").select("matricula").eq("estado", "POR RETIRAR").execute() + res = (sb.table("cobranza_estado_alumno").select("matricula") + .eq("estado", "POR RETIRAR").eq("ano", int(ano)).eq("mes", int(mes)) + .execute()) return {"matriculas": [str(r["matricula"]) for r in (res.data or [])]} def usuarios_listar():