fix(cobranza): invariante engancheTotal=plan completo, pago 0 inicial y abonos al pago correcto
This commit is contained in:
@@ -174,10 +174,11 @@ function leer() {
|
||||
|
||||
planes.push({
|
||||
proyecto: nombreHoja,
|
||||
fechaVenta: col.fechaVenta != null ? aFecha(fila[col.fechaVenta]) : null,
|
||||
plan: {
|
||||
ventaRef, clienteNombre, clienteTelefono: null, unidadCodigo,
|
||||
proyecto: nombreHoja, fechaInicio,
|
||||
engancheTotal: apartado + enganche,
|
||||
engancheTotal: apartado + enganche, // se recalcula en escribir() con el plan completo
|
||||
numPagos: meses, mensualidad, tasaMoraMensual: 0, status: 'ACTIVO',
|
||||
},
|
||||
abonosGrid,
|
||||
@@ -199,11 +200,9 @@ async function escribir(planesLeidos) {
|
||||
const borrados = await prisma.planPago.deleteMany({}) // cascada: Pago, AplicacionPago, NotaPlan
|
||||
console.log(`Planes borrados: ${borrados.count}`)
|
||||
|
||||
let totalPagos = 0, totalAbonos = 0, totalStandalone = 0
|
||||
|
||||
for (const { plan, abonosGrid } of planesLeidos) {
|
||||
const creado = await prisma.planPago.create({ data: plan })
|
||||
let totalPagos = 0, totalAbonos = 0, totalStandalone = 0, totalInicial = 0
|
||||
|
||||
for (const { plan, fechaVenta, abonosGrid } of planesLeidos) {
|
||||
// 1) calendario programado: mensualidades desde MES INICIO
|
||||
const pagosProg = []
|
||||
if (plan.numPagos > 0 && plan.mensualidad > 0) {
|
||||
@@ -217,11 +216,26 @@ async function escribir(planesLeidos) {
|
||||
}
|
||||
}
|
||||
|
||||
// Invariante del módulo: Σ pagos.monto == engancheTotal. El apartado+enganche
|
||||
// (ya pagado según el maestro) entra como pago 0 y engancheTotal = plan completo.
|
||||
const inicialMonto = (plan.engancheTotal ?? 0)
|
||||
if (inicialMonto > 0) {
|
||||
pagosProg.unshift({
|
||||
numPago: 0,
|
||||
fechaVencimiento: fechaVenta ?? plan.fechaInicio,
|
||||
monto: inicialMonto,
|
||||
montoPagado: inicialMonto,
|
||||
})
|
||||
totalInicial++
|
||||
}
|
||||
plan.engancheTotal = pagosProg.reduce((a, p) => a + p.monto, 0)
|
||||
|
||||
// 2) abonos del grid sobre la mensualidad del mismo mes; sobrantes → standalone
|
||||
const aplicaciones = [] // { idxPago, fechaPago, monto }
|
||||
const standalone = []
|
||||
for (const ab of abonosGrid) {
|
||||
const idx = pagosProg.findIndex((p) => claveMes(p.fechaVencimiento) === claveMes(ab.fecha))
|
||||
// idx del arreglo == numPago (el inicial ocupa numPago 0 en el índice 0)
|
||||
const idx = pagosProg.findIndex((p) => p.numPago >= 1 && claveMes(p.fechaVencimiento) === claveMes(ab.fecha))
|
||||
if (idx !== -1) {
|
||||
aplicaciones.push({ idx, fechaPago: ab.fecha, monto: ab.monto })
|
||||
} else {
|
||||
@@ -235,8 +249,18 @@ async function escribir(planesLeidos) {
|
||||
p.montoPagado = Math.min(p.monto, p.montoPagado + ap.monto)
|
||||
}
|
||||
|
||||
// Si el maestro registra pagos por encima del plan declarado (filas con
|
||||
// MESES/MENSUALIDAD vacíos pero grid lleno), el total del plan es lo pagado.
|
||||
const totalPagadoAcumulado = pagosProg.reduce((a, p) => a + p.montoPagado, 0) +
|
||||
standalone.reduce((a, s) => a + s.monto, 0)
|
||||
if (totalPagadoAcumulado > plan.engancheTotal) {
|
||||
plan.engancheTotal = Math.round(totalPagadoAcumulado * 100) / 100
|
||||
}
|
||||
|
||||
const creado = await prisma.planPago.create({ data: plan })
|
||||
|
||||
// crear pagos programados
|
||||
let numSiguiente = pagosProg.length
|
||||
let numSiguiente = pagosProg.length - 1
|
||||
for (const p of pagosProg) {
|
||||
await prisma.pago.create({
|
||||
data: { planId: creado.id, numPago: p.numPago, fechaVencimiento: p.fechaVencimiento, monto: p.monto, montoPagado: p.montoPagado },
|
||||
@@ -257,7 +281,7 @@ async function escribir(planesLeidos) {
|
||||
|
||||
// 3) aplicaciones de pago (abonos con fecha real)
|
||||
for (const ap of aplicaciones) {
|
||||
const pagoId = porNum.get(ap.idx + 1)
|
||||
const pagoId = porNum.get(ap.idx)
|
||||
if (!pagoId) continue
|
||||
await prisma.aplicacionPago.create({
|
||||
data: { pagoId, fechaPago: ap.fechaPago, monto: ap.monto, referencia: 'Importación maestro cobranza 06/09/26', capturadoPorId: null },
|
||||
@@ -266,7 +290,7 @@ async function escribir(planesLeidos) {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\nPlanes: ${planesLeidos.length} | Pagos programados: ${totalPagos} | Standalone: ${totalStandalone} | Abonos (AplicacionPago): ${totalAbonos}`)
|
||||
console.log(`\nPlanes: ${planesLeidos.length} | Pagos programados: ${totalPagos} (incl. ${totalInicial} pagos iniciales apartado+enganche) | Standalone: ${totalStandalone} | Abonos (AplicacionPago): ${totalAbonos}`)
|
||||
}
|
||||
|
||||
async function verificar() {
|
||||
|
||||
Reference in New Issue
Block a user