feat(apartado): ficha completa en Monday + estado visible en la app

- El alta (directa y progresiva) llena el Apartado con telefono, correo,
  curp, Precio Final, Enganche, Fecha Compra, Vendedor (el capturista
  con Monday vinculado) y Forma de Pago; el path webhook/cron hereda
  contacto, precio y asesor de la oportunidad.
- Bidireccional: Mis clientes en /hoy muestra el estado actual del
  Apartado leyendolo de Monday (si lo mueven en Monday, la app lo
  refleja en el siguiente refresh).
- getApartados con la correccion value-null al leer Estado.
- Test del mapa de Tipo propuesta del cotizador (los 502 del log eran
  de un proceso previo al fix 4f31d1c; queda cubierto).
This commit is contained in:
2026-09-04 07:34:57 +00:00
parent d81797c610
commit 42cfe937cf
13 changed files with 428 additions and 12 deletions

View File

@@ -10,6 +10,9 @@ const prismaMock = vi.hoisted(() => ({
findUnique: vi.fn(),
update: vi.fn(),
},
usuario: {
findUnique: vi.fn(),
},
}))
const mondayMock = vi.hoisted(() => ({
@@ -66,6 +69,7 @@ beforeEach(() => {
vi.clearAllMocks()
prismaMock.cliente.create.mockImplementation(async ({ data }) => ({ id: 'cli-1', ...data }))
prismaMock.cliente.update.mockImplementation(async ({ data }) => ({ id: 'cli-1', ...data }))
prismaMock.usuario.findUnique.mockResolvedValue(null) // default: capturista sin Monday vinculado
mondayMock.crearContacto.mockResolvedValue('cont-1')
mondayMock.actualizarContacto.mockResolvedValue(undefined)
mondayMock.crearApartado.mockResolvedValue('ap-1')
@@ -282,6 +286,38 @@ describe('completarProgreso (POST /api/clientes/progreso/:id/completar)', () =>
})
})
it('el Apartado lleva la ficha completa: contacto, precio, Forma de Pago y Vendedor del capturista original', async () => {
const { completarProgreso } = await import('./clientes.controller.js')
prismaMock.cliente.findUnique.mockResolvedValue({
id: 'cli-1',
mondayContactoId: 'cont-1',
mondayApartadoId: null,
capturadoPorId: 'usr-9', // quien inició el alta progresiva
})
prismaMock.usuario.findUnique.mockResolvedValue({ mondayUserId: 12345 })
const altaConCredito = {
...altaCompleta,
viviendaCredito: { ...altaCompleta.viviendaCredito, tiposCredito: ['COFI_FOVISSSTE'] },
}
const { res, status } = resFake()
await completarProgreso(reqFake(altaConCredito, { id: 'cli-1' }), res)
expect(status).toHaveBeenCalledWith(201)
expect(mondayMock.crearApartado).toHaveBeenCalledWith(
expect.objectContaining({
clienteNombre: 'Ana Demo Progreso',
unidadCodigo: 'U-999-DEMO2',
telefono: '6649990003',
email: 'ana@correo.com',
curp: 'AEDA900101MBCXXX00',
precioFinal: 1500000,
enganche: 20000,
vendedorId: 12345,
formaPagoLabel: 'Cofi-Fovissste',
fechaCompra: expect.stringMatching(/^\d{4}-\d{2}-\d{2}$/),
}),
)
})
it('sin Contacto previo lo crea directo como CLIENTE (alta sin Monday al iniciar)', async () => {
const { completarProgreso } = await import('./clientes.controller.js')
prismaMock.cliente.findUnique.mockResolvedValue({