feat(afluencia): captura completa de perfil en alta de afluencia
Agrega al formulario ligero y a POST /api/leads: tipo de propiedad, medio de contacto, edad, estado civil, tipo de empleo, ocupacion, rango salarial, credito, tipo de economia, califica y lo quiere para. Selects obligatorios (estado civil, tipo de empleo, tipo de economia, califica) con las etiquetas sembradas como labels status en el tablero Leads de Monday.
This commit is contained in:
@@ -101,6 +101,38 @@ describe('crearLead (POST /api/leads)', () => {
|
||||
expect(monday.leadsCreados[0]).toMatchObject({ email: 'lead@correo.com', desarrolloLabel: 'SENDA' })
|
||||
})
|
||||
|
||||
it('pasa los campos de calificación al item de Monday (labels listos para el board)', async () => {
|
||||
const monday = mondayMock()
|
||||
const r = await crearLead(monday, {
|
||||
...datosBase,
|
||||
tipoPropiedad: 'Casa',
|
||||
medioContacto: 'WhatsApp',
|
||||
edad: 35,
|
||||
estadoCivil: 'Casado(a)',
|
||||
tipoEmpleo: 'Asalariado',
|
||||
ocupacion: 'Ingeniero',
|
||||
rangoSalarial: '$20,000 - $30,000',
|
||||
credito: 'Infonavit',
|
||||
tipoEconomia: 'Economía mexicana',
|
||||
califica: 'Sí',
|
||||
loQuierePara: 'Vivir ahí',
|
||||
})
|
||||
expect(r).toEqual({ id: 'lead-nuevo-1', oportunidadId: null })
|
||||
expect(monday.leadsCreados[0]).toMatchObject({
|
||||
tipoPropiedadLabel: 'Casa',
|
||||
medioContacto: 'WhatsApp',
|
||||
edad: 35,
|
||||
estadoCivilLabel: 'Casado(a)',
|
||||
tipoEmpleoLabel: 'Asalariado',
|
||||
ocupacion: 'Ingeniero',
|
||||
rangoSalarial: '$20,000 - $30,000',
|
||||
creditoLabel: 'Infonavit',
|
||||
tipoEconomiaLabel: 'Economía mexicana',
|
||||
calificaLabel: 'Sí',
|
||||
loQuierePara: 'Vivir ahí',
|
||||
})
|
||||
})
|
||||
|
||||
it('con funnel: asegura la oportunidad de Afluencia con los datos del lead', async () => {
|
||||
const monday = mondayMock()
|
||||
const funnel = funnelMock()
|
||||
|
||||
@@ -22,6 +22,19 @@ const crearLeadSchema = z.object({
|
||||
origen: z.string().trim().min(1).optional(),
|
||||
desarrollo: z.string().trim().min(1).optional(),
|
||||
notas: z.string().trim().min(1).optional(),
|
||||
// Campos de calificación de la afluencia (opcionales; los labels fijos del
|
||||
// front coinciden con los sembrados en Monday, no se validan contra el board)
|
||||
tipoPropiedad: z.string().trim().min(1).optional(),
|
||||
medioContacto: z.string().trim().min(1).optional(),
|
||||
edad: z.coerce.number().int().min(15).max(120).optional(),
|
||||
estadoCivil: z.string().trim().min(1).optional(),
|
||||
tipoEmpleo: z.string().trim().min(1).optional(),
|
||||
ocupacion: z.string().trim().min(1).optional(),
|
||||
rangoSalarial: z.string().trim().min(1).optional(),
|
||||
credito: z.string().trim().min(1).optional(),
|
||||
tipoEconomia: z.string().trim().min(1).optional(),
|
||||
califica: z.string().trim().min(1).optional(),
|
||||
loQuierePara: z.string().trim().min(1).optional(),
|
||||
})
|
||||
|
||||
const cambiarEstadoSchema = z.object({
|
||||
@@ -112,6 +125,17 @@ export async function crearLead(
|
||||
origenLabel: datos.origen,
|
||||
desarrolloLabel: datos.desarrollo,
|
||||
notas: datos.notas,
|
||||
tipoPropiedadLabel: datos.tipoPropiedad,
|
||||
medioContacto: datos.medioContacto,
|
||||
edad: datos.edad,
|
||||
estadoCivilLabel: datos.estadoCivil,
|
||||
tipoEmpleoLabel: datos.tipoEmpleo,
|
||||
ocupacion: datos.ocupacion,
|
||||
rangoSalarial: datos.rangoSalarial,
|
||||
creditoLabel: datos.credito,
|
||||
tipoEconomiaLabel: datos.tipoEconomia,
|
||||
calificaLabel: datos.califica,
|
||||
loQuierePara: datos.loQuierePara,
|
||||
})
|
||||
|
||||
let oportunidadId: string | null = null
|
||||
|
||||
@@ -882,6 +882,17 @@ export class MondayService {
|
||||
Origen: datos.origenLabel,
|
||||
Desarrollo: datos.desarrolloLabel,
|
||||
Notas: datos.notas,
|
||||
'Tipo de Propiedad': datos.tipoPropiedadLabel,
|
||||
'Medio de Contacto': datos.medioContacto,
|
||||
Edad: datos.edad,
|
||||
'Estado Civil': datos.estadoCivilLabel,
|
||||
'Tipo de Empleo': datos.tipoEmpleoLabel,
|
||||
Ocupación: datos.ocupacion,
|
||||
'Rango Salarial': datos.rangoSalarial,
|
||||
Crédito: datos.creditoLabel,
|
||||
'Tipo de Economía': datos.tipoEconomiaLabel,
|
||||
Califica: datos.calificaLabel,
|
||||
'Lo Quiere Para': datos.loQuierePara,
|
||||
})
|
||||
return this.crearItem(boardId, datos.nombre, columnValues)
|
||||
}
|
||||
@@ -1083,6 +1094,18 @@ export interface DatosLead {
|
||||
origenLabel?: string | undefined // label real de la columna status 'Origen' del board Leads
|
||||
desarrolloLabel?: string | undefined // label real de la columna status 'Desarrollo' del board Leads
|
||||
notas?: string | undefined
|
||||
// Campos de calificación del interesado (labels reales de las columnas status del board Leads)
|
||||
tipoPropiedadLabel?: string | undefined
|
||||
medioContacto?: string | undefined
|
||||
edad?: number | undefined
|
||||
estadoCivilLabel?: string | undefined
|
||||
tipoEmpleoLabel?: string | undefined
|
||||
ocupacion?: string | undefined
|
||||
rangoSalarial?: string | undefined
|
||||
creditoLabel?: string | undefined
|
||||
tipoEconomiaLabel?: string | undefined
|
||||
calificaLabel?: string | undefined
|
||||
loQuierePara?: string | undefined
|
||||
}
|
||||
|
||||
/** Singleton usado por los controllers (los tests instancian el suyo) */
|
||||
|
||||
Reference in New Issue
Block a user