feat(pendientes): cotizador (mensualidades, bloqueo de unidad, totales, numMensualidades), cobranza (recibos, atrasos, mora configurable, recordatorios), soporte (adjuntos, filtros, estados), clientes maestro (catalogos reales), contactos (ficha y duplicados) y permisos de captura por rol
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { PlanPago } from '../../types'
|
||||
import { generarCalendario, registrarAbono } from '../cobranza'
|
||||
import { crearDocumento, folioRecibo } from './reciboAbono'
|
||||
import { generarCalendario, registrarAbono, saldoPlan } from '../cobranza'
|
||||
import { crearDocumento, folioRecibo, saldosDelRecibo } from './reciboAbono'
|
||||
|
||||
function planConAbono(): PlanPago {
|
||||
const { mensualidad, pagos } = generarCalendario('2026-01-15', 100000, 3)
|
||||
@@ -47,4 +47,56 @@ describe('reciboAbono PDF', () => {
|
||||
// smoke: el contenido interno es un PDF válido
|
||||
expect(doc.output('datauristring')).toContain('application/pdf')
|
||||
})
|
||||
|
||||
it('saldosDelRecibo usa los totales del plan, no solo los abonos registrados', () => {
|
||||
const plan = planConAbono()
|
||||
const pago = plan.pagos[0]
|
||||
const { restantePago, saldoPlan: saldo } = saldosDelRecibo(plan, pago)
|
||||
expect(restantePago).toBe(28333.33)
|
||||
expect(saldo).toBe(saldoPlan(plan))
|
||||
expect(saldo).toBe(95000)
|
||||
})
|
||||
|
||||
it('el saldo incluye el apartado/enganche histórico sin fila de AplicacionPago', () => {
|
||||
// Caso real del maestro importado: el pago inicial (numPago 0) trae
|
||||
// montoPagado == monto pero sin aplicaciones. Antes el recibo restaba solo
|
||||
// aplicaciones y mostraba un saldo inflado (o negativo).
|
||||
const base = planConAbono()
|
||||
const pagoInicial = {
|
||||
id: 'pago-0',
|
||||
numPago: 0,
|
||||
fechaVencimiento: '2026-01-01',
|
||||
monto: 20000,
|
||||
montoPagado: 20000,
|
||||
aplicaciones: [],
|
||||
}
|
||||
const plan: PlanPago = {
|
||||
...base,
|
||||
pagos: [pagoInicial, ...base.pagos],
|
||||
engancheTotal: base.engancheTotal,
|
||||
}
|
||||
const pago = plan.pagos[1]
|
||||
const aplicacion = pago.aplicaciones[0]
|
||||
const { saldoPlan: saldo, restantePago } = saldosDelRecibo(plan, pago)
|
||||
// saldo real = Σ monto − Σ montoPagado = 120000 − 25000
|
||||
expect(saldo).toBe(95000)
|
||||
expect(restantePago).toBe(28333.33)
|
||||
expect(crearDocumento(plan, pago, aplicacion).doc.getNumberOfPages()).toBeGreaterThanOrEqual(1)
|
||||
})
|
||||
|
||||
it('un abono mayor al monto de su pago no produce saldo negativo (dato importado)', () => {
|
||||
// El importador viejo guardaba el valor crudo en AplicacionPago.monto
|
||||
// aunque montoPagado se topara con Math.min: el recibo restaba de más.
|
||||
const base = planConAbono()
|
||||
const pago = base.pagos[0]
|
||||
const inflado: PlanPago = {
|
||||
...base,
|
||||
pagos: base.pagos.map((p) =>
|
||||
p.id === pago.id
|
||||
? { ...p, aplicaciones: [{ ...p.aplicaciones[0], monto: 500000 }] }
|
||||
: p,
|
||||
),
|
||||
}
|
||||
expect(saldosDelRecibo(inflado, inflado.pagos[0]).saldoPlan).toBe(95000)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user