Actualizar backend/modules/ocupabilidad/processor.py
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user