feat: mis clientes en Mi dia + perfilamiento de la afluencia en dashboards
- Cliente.capturadoPorId: el alta (directa y progresiva) registra al usuario que la inicio; el panel Mi dia muestra 'Mis clientes' con su estado (En captura / Cliente) sin depender de Monday. - LeadMonday ahora lee las 11 columnas de perfil del tablero Leads (estado civil, edad, rango salarial, tipo de empleo/economia, califica, credito, modelo, etc.). - GET /api/reportes/resumen agrega leads.perfil con conteos por dimension (valores vacios se omiten; edad en buckets). - /dash/ gana la seccion 'Perfilamiento de la afluencia' con mini-graficas de barras por dimension.
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
datosPipeline,
|
||||
formatoMoneda,
|
||||
formatoPorcentaje,
|
||||
rebanadasDe,
|
||||
unidadesApiladas,
|
||||
unidadesEnEtapa,
|
||||
type ResumenReportes,
|
||||
@@ -13,7 +14,26 @@ import {
|
||||
function resumen(overrides: Partial<ResumenReportes> = {}): ResumenReportes {
|
||||
return {
|
||||
generadoEn: '2026-08-22T12:00:00.000Z',
|
||||
leads: { total: 40, nuevosHoy: 3, nuevosSemana: 12, porEstado: {}, porOrigen: {} },
|
||||
leads: {
|
||||
total: 40,
|
||||
nuevosHoy: 3,
|
||||
nuevosSemana: 12,
|
||||
porEstado: {},
|
||||
porOrigen: {},
|
||||
perfil: {
|
||||
porDesarrollo: { ATELIER: 10, DIAGONAL: 8 },
|
||||
porModelo: {},
|
||||
porEstadoCivil: { Soltero: 15, Casado: 9 },
|
||||
porTipoEmpleo: {},
|
||||
porTipoEconomia: {},
|
||||
porCalifica: { Si: 20 },
|
||||
porCredito: {},
|
||||
porRangoSalarial: {},
|
||||
porMedioContacto: {},
|
||||
porLoQuierePara: {},
|
||||
porEdad: { '25–34': 12, '15–24': 5 },
|
||||
},
|
||||
},
|
||||
oportunidades: {
|
||||
total: 20,
|
||||
activas: 15,
|
||||
@@ -121,6 +141,20 @@ describe('datosCobranza', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('rebanadasDe (perfilamiento)', () => {
|
||||
it('ordena desc y filtra los valores en 0', () => {
|
||||
expect(rebanadasDe({ Soltero: 15, Casado: 9, Viudo: 0, 'Union Libre': 22 })).toEqual([
|
||||
{ nombre: 'Union Libre', valor: 22 },
|
||||
{ nombre: 'Soltero', valor: 15 },
|
||||
{ nombre: 'Casado', valor: 9 },
|
||||
])
|
||||
})
|
||||
|
||||
it('registro vacío devuelve lista vacía (la tarjeta muestra "Sin datos")', () => {
|
||||
expect(rebanadasDe({})).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatos', () => {
|
||||
it('moneda MXN sin centavos', () => {
|
||||
expect(formatoMoneda(125000)).toBe('$125,000')
|
||||
|
||||
Reference in New Issue
Block a user