feat(leads): la captura desde una app se asigna al capturista
POST /api/leads con sesion y Monday vinculado asigna el lead a quien lo registro (mas su actividad de contacto) en vez del round-robin; sin vinculo o sin token sigue el reparto. Bandera rr:skip para que el webhook create_item no pise la asignacion durante la propagacion de Monday (la carrera se observo en el smoke). Mensajes de exito en /hoy y /client reflejan a quien quedo asignado.
This commit is contained in:
@@ -65,6 +65,19 @@ describe('AltaAfluenciaForm', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('con asignacion "capturista" el mensaje dice que quedó asignado a ti', async () => {
|
||||
fetchMock.mockResolvedValueOnce(
|
||||
respuesta({ id: 'l-1', estado: 'NUEVO', oportunidadId: 'op-1', asignacion: 'capturista' }),
|
||||
)
|
||||
render(<AltaAfluenciaForm onVolver={() => undefined} onPasarAAltaCliente={() => undefined} />)
|
||||
llenarRequeridos()
|
||||
fireEvent.click(screen.getByRole('button', { name: /Registrar en afluencia/ }))
|
||||
|
||||
expect((await screen.findByRole('status')).textContent).toContain(
|
||||
'Registrado en afluencia — asignado a ti',
|
||||
)
|
||||
})
|
||||
|
||||
it('renderiza los selects de calificación con las opciones de los catálogos', () => {
|
||||
render(<AltaAfluenciaForm onVolver={() => undefined} onPasarAAltaCliente={() => undefined} />)
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente }: Pro
|
||||
const [errores, setErrores] = useState<Errores>({})
|
||||
const [enviando, setEnviando] = useState(false)
|
||||
const [leadCreado, setLeadCreado] = useState<LeadResumen | null>(null)
|
||||
const [asignacion, setAsignacion] = useState<'capturista' | 'round-robin' | null>(null)
|
||||
const [aviso, setAviso] = useState('')
|
||||
|
||||
const cambiar = (campo: keyof typeof FORM_INICIAL) => (e: { target: { value: string } }) => {
|
||||
@@ -122,6 +123,7 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente }: Pro
|
||||
estado: res.lead.estado,
|
||||
origen: form.origen,
|
||||
})
|
||||
setAsignacion(res.lead.asignacion ?? 'round-robin')
|
||||
} else if (res.motivo === 'duplicado') {
|
||||
setAviso(`Ya existe un lead con ese teléfono: ${res.nombre}.`)
|
||||
} else {
|
||||
@@ -134,6 +136,7 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente }: Pro
|
||||
setErrores({})
|
||||
setAviso('')
|
||||
setLeadCreado(null)
|
||||
setAsignacion(null)
|
||||
}
|
||||
|
||||
if (leadCreado !== null) {
|
||||
@@ -143,7 +146,9 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente }: Pro
|
||||
role="status"
|
||||
className="rounded-lg border border-green-200 bg-green-50 px-4 py-3 text-sm font-medium text-green-700"
|
||||
>
|
||||
Registrado en afluencia — se asignará por round-robin
|
||||
{asignacion === 'capturista'
|
||||
? 'Registrado en afluencia — asignado a ti'
|
||||
: 'Registrado en afluencia — se asignará por round-robin'}
|
||||
</p>
|
||||
<div className="mt-6 flex flex-wrap gap-3">
|
||||
<button
|
||||
|
||||
@@ -239,6 +239,8 @@ export interface LeadCreado {
|
||||
id: string
|
||||
estado: string
|
||||
oportunidadId: string | null
|
||||
/** 'capturista' = asignado a quien lo registró; 'round-robin' = entra al reparto */
|
||||
asignacion?: 'capturista' | 'round-robin'
|
||||
}
|
||||
|
||||
/** Resultado del alta de afluencia: distingue duplicado (409) de fallo de red */
|
||||
|
||||
@@ -235,7 +235,7 @@ export default function MiDiaPage({ accionesSesion }: { accionesSesion: Acciones
|
||||
setCapEnviando(true)
|
||||
setCapMensaje(null)
|
||||
try {
|
||||
await crearLead({
|
||||
const creado = await crearLead({
|
||||
nombre: capNombre.trim(),
|
||||
...(capTelefono.trim() !== '' ? { telefono: capTelefono.trim() } : {}),
|
||||
...(capEmail.trim() !== '' ? { email: capEmail.trim() } : {}),
|
||||
@@ -243,7 +243,13 @@ export default function MiDiaPage({ accionesSesion }: { accionesSesion: Acciones
|
||||
...(capDesarrollo !== '' ? { desarrollo: capDesarrollo } : {}),
|
||||
...(capNotas.trim() !== '' ? { notas: capNotas.trim() } : {}),
|
||||
})
|
||||
setCapMensaje({ tipo: 'ok', texto: 'Lead registrado, se asignará por round-robin' })
|
||||
setCapMensaje({
|
||||
tipo: 'ok',
|
||||
texto:
|
||||
creado.asignacion === 'capturista'
|
||||
? 'Lead registrado y asignado a ti'
|
||||
: 'Lead registrado, se asignará por round-robin',
|
||||
})
|
||||
setCapNombre('')
|
||||
setCapTelefono('')
|
||||
setCapEmail('')
|
||||
|
||||
@@ -21,6 +21,8 @@ export function fetchResumenMiDia(): Promise<ResumenMiDia> {
|
||||
export interface LeadCreado {
|
||||
id: string
|
||||
estado: string
|
||||
/** 'capturista' = asignado a quien lo registró; 'round-robin' = entra al reparto */
|
||||
asignacion?: 'capturista' | 'round-robin'
|
||||
}
|
||||
|
||||
/** Crea un lead; en duplicado (409) lanza Error con el mensaje del API */
|
||||
|
||||
Reference in New Issue
Block a user