From 435a56383fadeceaa114b70c56b91a2889557c20 Mon Sep 17 00:00:00 2001 From: Administrator Date: Wed, 23 Sep 2026 10:44:38 -0500 Subject: [PATCH] Actualizar backend/modules/rentabilidad/logic.py --- backend/modules/rentabilidad/logic.py | 36 +++++++++++++++++++++------ 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/backend/modules/rentabilidad/logic.py b/backend/modules/rentabilidad/logic.py index 0202717..87b1fa4 100644 --- a/backend/modules/rentabilidad/logic.py +++ b/backend/modules/rentabilidad/logic.py @@ -147,30 +147,34 @@ class RentabilidadLogic: datos = self.processor.obtener_datos_procesados(ano, mes) programas_disponibles = set() + # Sede/Programa pueden venir con varios separados por coma (multi). Vacío/TODOS = todo. + _sede_set = {s.strip().upper() for s in str(sede or "TODOS").split(",") if s.strip()} + _sede_all = (not _sede_set) or ("TODOS" in _sede_set) + _prog_set = {p.strip().upper() for p in str(filtro_prog or "TODOS").split(",") if p.strip()} + _prog_all = (not _prog_set) or ("TODOS" in _prog_set) + if datos: for d in datos: prog = str(d.get('programa_frecuencia', d.get('dsc_programa', ''))) d['Categoria_Programa'] = self.clasificar_programa(prog) d['Sede'] = self.identificar_sede(prog) d['Filtro_Programa'] = self.identificar_filtro_programa(prog) - + # Recolectar qué programas existen REALMENTE en la Sede seleccionada - if sede == "TODOS" or d['Sede'] == sede: + if _sede_all or str(d['Sede']).upper() in _sede_set: programas_disponibles.add(d['Filtro_Programa']) # Ordenar para el Dropdown en la UI orden_deseado = ["SEMINARIOS", "OTROS", "TEAC", "TERC"] self.programas_disponibles_filtro = [p for p in orden_deseado if p in programas_disponibles] - # NO auto-corregir: se respeta el filtro y la tabla queda vacia si no hay. self.filtro_corregido = None - if datos and (sede != "TODOS" or filtro_prog != "TODOS"): + if datos and (not _sede_all or not _prog_all): datos_filtrados = [] for d in datos: - cumple_sede = (sede == "TODOS" or d.get('Sede') == sede) - cumple_prog = (filtro_prog == "TODOS" or d.get('Filtro_Programa') == filtro_prog) - + cumple_sede = _sede_all or str(d.get('Sede')).upper() in _sede_set + cumple_prog = _prog_all or str(d.get('Filtro_Programa')).upper() in _prog_set if cumple_sede and cumple_prog: datos_filtrados.append(d) datos = datos_filtrados @@ -525,7 +529,23 @@ class RentabilidadLogic: f"S/ {venta_actual:,.0f}", f"S/ {costo_actual:,.0f}", str_margen_actual, - " ≡ ▼ " + " ≡ ▼ ", + # ── Extras para EXPORTAR (no se muestran en la tabla) ── + round(costo_epp + costo_cert, 2), # [14] EPP + Certificado (inicial) + round(costo_doc, 2), # [15] Docentes (inicial) + round(costo_cons, 2), # [16] Consumibles (inicial) + round(costo_mkt, 2), # [17] Marketing (inicial) + round(margen_bruto * 100, 2), # [18] MB% inicial (número) + str(d.get('Sede', '')), # [19] Sede + round(venta, 2), # [20] Venta inicial (número) + round(valor_costo_inicial, 2), # [21] Costo inicial (número) + round(venta_actual, 2), # [22] Venta actual (número) + round(costo_actual, 2), # [23] Costo actual (número) + round((1 - (costo_actual/venta_actual)) * 100, 2) if venta_actual else 0, # [24] MB% actual + round(costo_cert, 2), # [25] Certificado solo (inicial) + total_inscritos, # [26] Total inscritos (número) + retirados, # [27] Retirados (número) + en_curso, # [28] En curso (número) ] sheet_data.append(fila)