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:
2026-09-21 08:34:53 +00:00
parent b5a20aed4e
commit 2fc80e7f9e
66 changed files with 3792 additions and 436 deletions

View File

@@ -7,11 +7,15 @@ const prismaMock = vi.hoisted(() => ({
findMany: vi.fn(),
findUnique: vi.fn(),
},
capturaDepartamento: {
findMany: vi.fn(),
},
}))
vi.mock('../services/prisma.js', () => ({ prisma: prismaMock }))
import {
CAMPOS_FECHA_ENTREGA,
getUnidadesLocal,
getUnidadLocal,
unidadLocalADto,
@@ -37,10 +41,11 @@ beforeEach(() => {
vi.clearAllMocks()
prismaMock.unidad.findMany.mockResolvedValue([])
prismaMock.unidad.findUnique.mockResolvedValue(null)
prismaMock.capturaDepartamento.findMany.mockResolvedValue([])
})
describe('unidadLocalADto', () => {
it('mapea la fila local al DTO Unidad', () => {
it('mapea la fila local al DTO Unidad (sin fecha de entrega por defecto)', () => {
const dto = unidadLocalADto(fila({ codigo: 'SENDA-101' }))
expect(dto).toEqual({
codigo: 'SENDA-101',
@@ -58,6 +63,10 @@ describe('unidadLocalADto', () => {
})
})
it('con fecha de entrega (captura de departamentos) la deja en el DTO', () => {
expect(unidadLocalADto(fila({ codigo: 'U-101' }), '2027-10-08').fechaEntrega).toBe('2027-10-08')
})
it('etapa vacía → null', () => {
expect(unidadLocalADto(fila({ codigo: 'U-1', etapa: '' })).etapa).toBeNull()
})
@@ -80,11 +89,41 @@ describe('getUnidadesLocal / getUnidadLocal', () => {
expect(senda.map((u) => u.codigo)).toEqual(['U-2', 'U-3'])
})
it('getUnidadLocal: null si no existe', async () => {
it('completa fechaEntrega desde la captura: entrega programada > habitabilidad > inicio de obra', async () => {
prismaMock.unidad.findMany.mockResolvedValue([
fila({ codigo: 'U-1', desarrollo: 'DIAGONAL' }),
fila({ codigo: 'U-2', desarrollo: 'DIAGONAL' }),
fila({ codigo: 'S-1', desarrollo: 'SENDA' }),
fila({ codigo: 'S-2', desarrollo: 'SENDA' }),
])
prismaMock.capturaDepartamento.findMany.mockResolvedValue([
{ unidadCodigo: 'U-1', campo: 'inicio_obra_fecha', valor: '2026-01-01' },
{ unidadCodigo: 'U-1', campo: 'habitabilidad', valor: '2027-10-08' },
{ unidadCodigo: 'U-1', campo: 'entrega_programada_fecha', valor: '2027-11-20' },
{ unidadCodigo: 'S-1', campo: 'habitabilidad', valor: '2027-05-05' },
// Valor vacío / no-fecha: no cuenta como dato
{ unidadCodigo: 'S-1', campo: 'entrega_programada_fecha', valor: '' },
{ unidadCodigo: 'S-2', campo: 'entrega_programada_fecha', valor: 'pendiente' },
])
const todas = await getUnidadesLocal()
expect(todas.map((u) => u.fechaEntrega)).toEqual(['2027-11-20', null, '2027-05-05', null])
expect(prismaMock.capturaDepartamento.findMany).toHaveBeenCalledWith(
expect.objectContaining({ where: { campo: { in: [...CAMPOS_FECHA_ENTREGA] } } }),
)
})
it('getUnidadLocal: null si no existe; trae la fecha de su captura', async () => {
prismaMock.unidad.findUnique.mockImplementation(async ({ where }) =>
where.codigo === 'U-9' ? fila({ codigo: 'U-9' }) : null,
)
expect((await getUnidadLocal('U-9'))?.codigo).toBe('U-9')
prismaMock.capturaDepartamento.findMany.mockResolvedValue([
{ unidadCodigo: 'U-9', campo: 'habitabilidad', valor: '2027-10-08' },
])
const dto = await getUnidadLocal('U-9')
expect(dto?.codigo).toBe('U-9')
expect(dto?.fechaEntrega).toBe('2027-10-08')
expect(await getUnidadLocal('U-X')).toBeNull()
})
})