Actualizar frontend/src/pages/Cobranza.jsx
This commit is contained in:
@@ -95,6 +95,14 @@ export default function Cobranza() {
|
||||
return () => { activo = false; };
|
||||
}, [ano, mes, sectorista]);
|
||||
|
||||
// Cargar matrículas POR RETIRAR (para el "Saldo por Retirar" de las tarjetas)
|
||||
const [porRetirar, setPorRetirar] = useState(new Set());
|
||||
useEffect(() => {
|
||||
api.alumnosPorRetirar()
|
||||
.then((r) => setPorRetirar(new Set((r.matriculas || []).map(String))))
|
||||
.catch(() => {});
|
||||
}, [ano, mes]);
|
||||
|
||||
// Cargar clasificación de sede (sede.json) para los programas visibles
|
||||
useEffect(() => {
|
||||
if (!esPrograma) return;
|
||||
@@ -165,6 +173,17 @@ export default function Cobranza() {
|
||||
return a.programa;
|
||||
}
|
||||
|
||||
// Saldo por retirar (ANT/MES/TOTAL) de los alumnos marcados POR RETIRAR (según filtros)
|
||||
const retiroKpi = useMemo(() => {
|
||||
let sAnt=0, sMes=0;
|
||||
alumnosFiltrados.forEach((a) => {
|
||||
if (!porRetirar.has(String(a.matricula))) return;
|
||||
sAnt += ((Number(a.cta_ant)||0) - (Number(a.cob_ant)||0));
|
||||
sMes += ((Number(a.cta_cur)||0) - (Number(a.cob_cur)||0));
|
||||
});
|
||||
return { sAnt, sMes, sTot: sAnt + sMes };
|
||||
}, [alumnosFiltrados, porRetirar]);
|
||||
|
||||
// Exportar el DETALLE DE ALUMNOS (rápido: usa el dataset ya cargado, sin N consultas)
|
||||
async function exportarDetalle() {
|
||||
setExportando(true);
|
||||
@@ -262,7 +281,7 @@ export default function Cobranza() {
|
||||
{loading ? <Loader text="Calculando cobranza..." /> :
|
||||
error ? <ErrorBox msg={error} /> :
|
||||
<>
|
||||
<Tarjetas kpis={kpis} />
|
||||
<Tarjetas kpis={kpis} retiro={retiroKpi} />
|
||||
|
||||
<div className="table-wrap" style={{marginTop:16, overflowX:"auto"}}>
|
||||
<table className="cob-table" {...cols.tableProps}>
|
||||
@@ -358,7 +377,8 @@ export default function Cobranza() {
|
||||
);
|
||||
}
|
||||
|
||||
function Tarjetas({ kpis }) {
|
||||
function Tarjetas({ kpis, retiro }) {
|
||||
const rt = retiro || { sAnt:0, sMes:0, sTot:0 };
|
||||
const alDia = kpis.saldo <= 0.01;
|
||||
if (alDia) {
|
||||
return (
|
||||
@@ -371,13 +391,13 @@ function Tarjetas({ kpis }) {
|
||||
);
|
||||
}
|
||||
const cards = [
|
||||
["⚠ MES ANTERIOR","#d97706",kpis.cAnt,kpis.obAnt],
|
||||
["📅 MES EN CURSO","#059669",kpis.cMes,kpis.obMes],
|
||||
["💰 CARTERA TOTAL","#7c3aed",kpis.cTot,kpis.obTot],
|
||||
["⚠ MES ANTERIOR","#d97706",kpis.cAnt,kpis.obAnt, rt.sAnt],
|
||||
["📅 MES EN CURSO","#059669",kpis.cMes,kpis.obMes, rt.sMes],
|
||||
["💰 CARTERA TOTAL","#7c3aed",kpis.cTot,kpis.obTot, rt.sTot],
|
||||
];
|
||||
return (
|
||||
<div style={{display:"grid",gridTemplateColumns:"repeat(3,1fr)",gap:14}}>
|
||||
{cards.map(([titulo,color,cta,cob]) => {
|
||||
{cards.map(([titulo,color,cta,cob,saldoRetiro]) => {
|
||||
const ratio = cta>0 ? (cob/cta*100) : 0;
|
||||
const c = colorSemaforo(ratio);
|
||||
const saldo = cta - cob;
|
||||
@@ -388,6 +408,7 @@ function Tarjetas({ kpis }) {
|
||||
<Row k="Cta x Cobrar" v={`S/ ${cta.toLocaleString("es-PE",{maximumFractionDigits:0})}`} />
|
||||
<Row k="Cobrado" v={`S/ ${cob.toLocaleString("es-PE",{maximumFractionDigits:0})}`} />
|
||||
<Row k="Saldo" v={`S/ ${saldo.toLocaleString("es-PE",{maximumFractionDigits:0})}`} bold color={saldo>0?"#dc2626":"#10b981"} />
|
||||
<Row k="Saldo por Retirar" v={`S/ ${(saldoRetiro||0).toLocaleString("es-PE",{maximumFractionDigits:0})}`} color="#dc2626" />
|
||||
{cta>0 && (
|
||||
<div style={{marginTop:10}}>
|
||||
<div style={{display:"flex",justifyContent:"space-between",marginBottom:4}}>
|
||||
|
||||
Reference in New Issue
Block a user