feat: conversión lead→oportunidad (Agendo) y alta ligada a apartado
- Mis leads: botón 'Agendo →' convierte el lead en oportunidad (etapa Agendo Cita, con sus datos, asesor = vendedor del lead o quien convierte), marca el lead Calificado y guarda el mapping LeadOportunidad; 409 si ya fue convertido - Mis oportunidades: se quitan No Asistio y Abandono (redundantes con Descartar); quedan Cotizar, Afluencia, Agendo Cita y Aparto - Mis apartados: 'Firma cliente (venta) →' abre el alta de cliente con TODO lo recolectado prellenado (ficha del apartado + contacto + oportunidad + cotización vinculada vía GET /altas/prefill-apartado/:id) - El alta con apartadoMondayId se LIGA al apartado existente y lo enriquece (curp, teléfono, email, precio final, enganche, forma de pago, unidad) en vez de crear un duplicado - monday.service: actualizarApartado + ApartadoMonday con curp, forma de pago, enganche y monto apartado - Tests: 470 API + 120 alta-clientes + 16 mi-dia, verde
This commit is contained in:
@@ -21,11 +21,13 @@ import {
|
||||
listarBorradores,
|
||||
obtenerBorrador,
|
||||
obtenerCotizacion,
|
||||
obtenerPrefillApartado,
|
||||
subirDocumentos,
|
||||
type BorradorResumen,
|
||||
type LeadResumen,
|
||||
} from '../services/api'
|
||||
import { cotizacionAPrellenado } from '../lib/cotizacionAlta'
|
||||
import { apartadoAPrellenado } from '../lib/apartadoAlta'
|
||||
import { leadAPrellenado } from '../lib/leadAlta'
|
||||
import BusquedaLead from '../components/BusquedaLead'
|
||||
import AltaAfluenciaForm from '../components/AltaAfluenciaForm'
|
||||
@@ -54,6 +56,11 @@ function paramsAfluencia(): { oportunidadId: string; valores: Record<string, str
|
||||
return { oportunidadId: id, valores }
|
||||
}
|
||||
|
||||
/** Lee ?apartado=<itemId> — botón "Firma Cliente (Venta)" de Mis apartados en Mi día */
|
||||
function paramApartado(): string | null {
|
||||
return new URLSearchParams(window.location.search).get('apartado')
|
||||
}
|
||||
|
||||
const formatoFechaHora = (iso: string): string =>
|
||||
new Date(iso).toLocaleString('es-MX', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' })
|
||||
|
||||
@@ -127,10 +134,25 @@ export default function AltaClientePage() {
|
||||
valores: Record<string, string>
|
||||
} | null>(null)
|
||||
|
||||
// Al entrar: ?cotizacion=<id> prellena el alta y salta directo al wizard;
|
||||
// ?afluencia=<id> abre el formulario de afluencia prellenado; si no, la
|
||||
// entrada ofrece Alta Afluencia (captura ligera) y Alta de Cliente
|
||||
// Al entrar: ?apartado=<id> prellena el alta con todo lo recolectado del
|
||||
// apartado y salta al wizard ligado a ese item; ?afluencia=<id> abre el
|
||||
// formulario de afluencia prellenado; ?cotizacion=<id> prellena el alta;
|
||||
// si no, la entrada ofrece Alta Afluencia (captura ligera) y Alta de Cliente
|
||||
useEffect(() => {
|
||||
const apartadoId = paramApartado()
|
||||
if (apartadoId) {
|
||||
obtenerPrefillApartado(apartadoId)
|
||||
.then((pre) => {
|
||||
const p = apartadoAPrellenado(pre)
|
||||
actualizar('datosGenerales', { ...datos.datosGenerales, ...p.datosGenerales })
|
||||
actualizar('viviendaCredito', { ...datos.viviendaCredito, ...p.viviendaCredito })
|
||||
actualizar('apartadoMondayId', apartadoId)
|
||||
if (p.leadMondayId) actualizar('leadMondayId', p.leadMondayId)
|
||||
})
|
||||
.catch(() => setErrorCarga('No se pudo cargar el apartado para prellenar el alta.'))
|
||||
.finally(() => setPantalla('wizard'))
|
||||
return
|
||||
}
|
||||
const afl = paramsAfluencia()
|
||||
if (afl) {
|
||||
setAfluenciaPrevia(afl)
|
||||
@@ -487,6 +509,11 @@ export default function AltaClientePage() {
|
||||
{errorCarga}
|
||||
</p>
|
||||
)}
|
||||
{datos.apartadoMondayId && (
|
||||
<p role="note" className="mb-6 rounded-lg border border-blue-200 bg-blue-50 px-4 py-3 text-xs font-medium text-blue-800">
|
||||
Alta ligada al apartado del cliente en Monday — al completarla se actualiza ese item (no se duplica).
|
||||
</p>
|
||||
)}
|
||||
|
||||
{paso === 0 && (
|
||||
<TarjetaPaso>
|
||||
|
||||
Reference in New Issue
Block a user