Actualizar backend/modules/ocupabilidad/processor.py

This commit is contained in:
2026-07-03 16:48:26 -05:00
parent 2f8fae01ca
commit c91026e4da

View File

@@ -154,6 +154,123 @@ class CursoProcessor:
print(f"❌ Error obteniendo datos procesados: {e}")
return []
# =========================================================================
# DETALLE DE ALUMNOS DE UN CURSO (para el popup "Ver")
# =========================================================================
def obtener_alumnos_curso(self, num_indice):
"""Alumnos matriculados de un curso (num_indice), TODOS menos ANU.
Devuelve nombre + cod_estado (ALU/PRE/RET) + curso anterior TEAC/TERC (si existe)."""
try:
idx = str(num_indice).strip()
conn = self.data_manager.get_connection()
cursor = conn.cursor()
# 1) Alumnos del curso actual (nombre, estado, dni, fecha de inicio del curso)
sql = """
SELECT
sgeca_matricula.num_matricula,
sgeca_matricula.cod_estado AS cod_estado,
sgema_alumno.dsc_documento AS dni,
sgema_alumno.dsc_apellido_paterno + ' ' + sgema_alumno.dsc_apellido_materno
+ ', ' + sgema_alumno.dsc_nombres AS dsc_alumno,
rp.fch_inicio AS fch_inicio_actual
FROM sgeca_matricula
INNER JOIN sgema_alumno ON sgeca_matricula.cod_alumno = sgema_alumno.cod_alumno
LEFT JOIN sgede_RP_programa rp
ON sgeca_matricula.cod_periodo = rp.cod_detalle
AND sgeca_matricula.cod_programa = rp.cod_programa
AND sgeca_matricula.num_indice = rp.num_indice
WHERE sgeca_matricula.num_indice = ?
AND sgeca_matricula.cod_localidad LIKE 'SCENT'
AND sgeca_matricula.cod_estado NOT IN ('ANU')
ORDER BY dsc_alumno
"""
cursor.execute(sql, idx)
filas = []
dnis = []
for row in cursor.fetchall():
mat = str(row[0]).strip()
if mat.endswith('.0'): mat = mat[:-2]
dni = str(row[2]).strip() if row[2] else ""
filas.append({
"matricula": mat,
"estado": str(row[1]).strip().upper(),
"dni": dni,
"alumno": str(row[3]).strip(),
"fch_inicio_actual": self.parse_fecha(row[4]),
"curso_anterior": "-",
"estado_anterior": "-",
})
if dni:
dnis.append(dni)
# 2) Historial de esos alumnos (cursos TEAC/TERC, no ANU, no SUS)
historial = {} # dni -> lista de {programa, fecha, estado}
if dnis:
dnis_unicos = list(set(dnis))
for i in range(0, len(dnis_unicos), 1000):
chunk = dnis_unicos[i:i+1000]
ph = ",".join(["?"] * len(chunk))
sql_hist = f"""
SELECT a.dsc_documento,
rp.dsc_det_programa AS programa_detallado,
p.dsc_programa AS programa_general,
rp.fch_inicio, m.cod_estado
FROM sgeca_matricula m
INNER JOIN sgema_alumno a ON m.cod_alumno = a.cod_alumno
INNER JOIN sgeca_programa p ON m.cod_programa = p.cod_programa
INNER JOIN sgede_RP_programa rp
ON m.cod_periodo = rp.cod_detalle
AND m.cod_programa = rp.cod_programa
AND m.num_indice = rp.num_indice
WHERE a.dsc_documento IN ({ph})
AND m.cod_localidad LIKE 'SCENT'
AND m.cod_estado IN ('ALU','PRE','RET')
AND rp.cod_estado <> 'SUS'
"""
cursor.execute(sql_hist, *chunk)
for r in cursor.fetchall():
d = str(r[0]).strip()
det = str(r[1]).strip() if r[1] else ""
gen = str(r[2]).strip() if r[2] else ""
historial.setdefault(d, []).append({
"programa": det if det and det != "None" else gen, # detallado (como Cobranza)
"programa_clasif": gen, # general, para clasificar TEAC/TERC
"fecha": self.parse_fecha(r[3]),
"estado": str(r[4]).strip().upper(),
})
conn.close()
# 3) Para cada alumno, buscar el ÚLTIMO curso anterior TEAC/TERC
for f in filas:
dni = f["dni"]
fch_act = f["fch_inicio_actual"]
if not dni or not fch_act or dni not in historial:
continue
candidatos = []
for h in historial[dni]:
if not h["fecha"]:
continue
if not (h["fecha"] < fch_act): # debe ser anterior
continue
cat = self.obtener_categoria_programa(h.get("programa_clasif") or h["programa"])
if cat not in ("TEAC", "TERC"): # solo TEAC/TERC
continue
candidatos.append(h)
if candidatos:
ultimo = max(candidatos, key=lambda x: x["fecha"])
f["curso_anterior"] = ultimo["programa"]
f["estado_anterior"] = ultimo["estado"]
# limpiar campos internos
for f in filas:
f.pop("dni", None)
f.pop("fch_inicio_actual", None)
return filas
except Exception as e:
print(f"❌ Error obtener_alumnos_curso: {e}")
return []
def normalizar_texto(self, texto):
if not texto: return ""
texto = str(texto).upper().strip()