feat(mi-dia): botón Afluencia abre el formulario prellenado y actualiza la oportunidad
- Mis oportunidades: 'Afluencia →' navega a /client/?afluencia=<id> con nombre, contacto, desarrollo y modelo prellenados - Alta Afluencia: con oportunidadId el envío ACTUALIZA la oportunidad en Monday (perfil completo + etapa Afluencia) en vez de crear duplicado; sin oportunidadId el flujo de captura nueva no cambia - monday.service: actualizarOportunidadAfluencia (mismo builder de la creación + name); moverAGrupoSegunEstado tras actualizar - Tests: 457 API + 16 mi-dia + 116 alta-clientes, verde
This commit is contained in:
@@ -62,6 +62,9 @@ const crearAfluenciaSchema = z.object({
|
||||
origen: z.string().trim().min(1).optional(),
|
||||
desarrollo: z.string().trim().min(1).optional(),
|
||||
notas: z.string().trim().min(1).optional(),
|
||||
// Con oportunidadId (botón "Afluencia" de Mis oportunidades en Mi día): se
|
||||
// ACTUALIZA esa oportunidad con el perfil capturado en vez de crear una nueva
|
||||
oportunidadId: 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)
|
||||
modelo: z.string().trim().min(1).optional(),
|
||||
@@ -165,6 +168,7 @@ type MondayLeads = Pick<
|
||||
| 'cambiarValorColumna'
|
||||
| 'crearLead'
|
||||
| 'crearOportunidadAfluencia'
|
||||
| 'actualizarOportunidadAfluencia'
|
||||
| 'crearMotivoNoCompra'
|
||||
| 'buscarLeadPorTelefono'
|
||||
| 'buscarOportunidadPorTelefono'
|
||||
@@ -176,7 +180,7 @@ type MondayLeads = Pick<
|
||||
>
|
||||
|
||||
export type ResultadoCrearLead =
|
||||
| { id: string; oportunidadId: string | null }
|
||||
| { id: string; oportunidadId: string | null; actualizada?: boolean }
|
||||
| { duplicado: { id: string; nombre: string } }
|
||||
|
||||
/**
|
||||
@@ -237,6 +241,38 @@ export async function crearAfluencia(
|
||||
): Promise<ResultadoCrearLead> {
|
||||
const boardOportunidades = config.monday.boards.oportunidades
|
||||
|
||||
// Con oportunidadId: el formulario venía prellenado desde Mis oportunidades
|
||||
// (Mi día) → se ACTUALIZA esa oportunidad con el perfil completo y queda en
|
||||
// etapa 'Afluencia'; no se crea duplicado ni se valida teléfono.
|
||||
if (datos.oportunidadId !== undefined) {
|
||||
await monday.actualizarOportunidadAfluencia(datos.oportunidadId, {
|
||||
nombre: datos.nombre,
|
||||
telefono: datos.telefono,
|
||||
email: datos.email,
|
||||
desarrolloLabel: datos.desarrollo,
|
||||
origenLabel: datos.origen,
|
||||
modeloLabel: datos.modelo,
|
||||
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,
|
||||
notas: datos.notas,
|
||||
})
|
||||
try {
|
||||
await moverAGrupoSegunEstado(monday, boardOportunidades, datos.oportunidadId)
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`No se pudo mover al grupo correcto la oportunidad ${datos.oportunidadId}:`, err)
|
||||
}
|
||||
return { id: datos.oportunidadId, oportunidadId: datos.oportunidadId, actualizada: true }
|
||||
}
|
||||
|
||||
if (datos.telefono !== undefined) {
|
||||
const existente = await monday.buscarOportunidadPorTelefono(datos.telefono)
|
||||
if (existente) return { duplicado: { id: existente.id, nombre: existente.nombre } }
|
||||
@@ -429,6 +465,12 @@ export async function crearAfluenciaEndpoint(req: Request, res: Response): Promi
|
||||
})
|
||||
return
|
||||
}
|
||||
// Actualización de oportunidad existente (botón "Afluencia" de Mi día): no
|
||||
// hay captura nueva que registrar ni round-robin que correr
|
||||
if (resultado.actualizada === true) {
|
||||
res.json({ id: resultado.id, estado: 'Afluencia', oportunidadId: resultado.oportunidadId, actualizada: true })
|
||||
return
|
||||
}
|
||||
// Registro local del capturista para "Mis capturas" del panel Mi día.
|
||||
// leadId = el id de la oportunidad (la afluencia ES la oportunidad). Un
|
||||
// fallo aquí no rompe la respuesta: la afluencia ya quedó creada en Monday.
|
||||
|
||||
Reference in New Issue
Block a user