feat: ecosistema FRASA — apps Cotizador, Alta Clientes, Cobranza y Landing
- Cotizador (/quote): 4 propuestas con formulas validadas del Excel, comparador, combobox de unidades, vigencia, PDF ANEXO A - Alta Clientes (/client): wizard 8 pasos, validacion CURP RENAPO, OCR de INE, checklist de expediente, firma digital, 5 PDFs legales - Cobranza (/pay): planes de enganche, mora, vista cobranza del dia, recibos PDF, bitacora, dashboard con filtros - Landing (/): entrada al ecosistema - Design system StudioBlank (monocromo, acento #1B4332) en las 4 apps - 123 tests vitest
This commit is contained in:
50
apps/cobranza/src/lib/pdf/reciboAbono.test.ts
Normal file
50
apps/cobranza/src/lib/pdf/reciboAbono.test.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { PlanPago } from '../../types'
|
||||
import { generarCalendario, registrarAbono } from '../cobranza'
|
||||
import { crearDocumento, folioRecibo } from './reciboAbono'
|
||||
|
||||
function planConAbono(): PlanPago {
|
||||
const { mensualidad, pagos } = generarCalendario('2026-01-15', 100000, 3)
|
||||
const plan: PlanPago = {
|
||||
id: 'plan-fixture',
|
||||
ventaRef: 'VTA-2026-001',
|
||||
clienteNombre: 'Cliente Fixture',
|
||||
clienteTelefono: '55 0000 0000',
|
||||
unidadCodigo: 'U-101',
|
||||
proyecto: 'SENDA',
|
||||
fechaInicio: '2026-01-15',
|
||||
engancheTotal: 100000,
|
||||
numPagos: 3,
|
||||
mensualidad,
|
||||
status: 'ACTIVO',
|
||||
pagos,
|
||||
notas: [],
|
||||
createdAt: '2026-01-01T00:00:00.000Z',
|
||||
}
|
||||
return registrarAbono(plan, {
|
||||
pagoId: plan.pagos[0].id,
|
||||
fechaPago: '2026-01-15',
|
||||
monto: 5000,
|
||||
referencia: 'SPEI-001',
|
||||
})
|
||||
}
|
||||
|
||||
describe('reciboAbono PDF', () => {
|
||||
it('el folio son los primeros 8 chars del id de la aplicación en mayúsculas', () => {
|
||||
const plan = planConAbono()
|
||||
const aplicacion = plan.pagos[0].aplicaciones[0]
|
||||
expect(folioRecibo(aplicacion)).toBe(aplicacion.id.slice(0, 8).toUpperCase())
|
||||
expect(folioRecibo({ ...aplicacion, id: 'abcdef12-3456-7890' })).toBe('ABCDEF12')
|
||||
})
|
||||
|
||||
it('genera el documento con nombre de archivo correcto', () => {
|
||||
const plan = planConAbono()
|
||||
const pago = plan.pagos[0]
|
||||
const aplicacion = pago.aplicaciones[0]
|
||||
const { doc, nombreArchivo } = crearDocumento(plan, pago, aplicacion, new Date('2026-02-20T12:00:00'))
|
||||
expect(nombreArchivo).toBe(`recibo_U-101_${folioRecibo(aplicacion)}.pdf`)
|
||||
expect(doc.getNumberOfPages()).toBeGreaterThanOrEqual(1)
|
||||
// smoke: el contenido interno es un PDF válido
|
||||
expect(doc.output('datauristring')).toContain('application/pdf')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user