feat: docs en apartados, enganche seleccionable y prefill de clientes
- Mis apartados (Mi día): botón Documentos con precarga del expediente — captura del cotizador y captura de pago apartado (obligatorios) más documentos generales; los archivos se guardan en el cliente ligado al apartado (se crea la ficha mínima si no existe). Endpoints GET/POST /apartados/:id/documentos (multipart, 10 MB, pdf/jpg/png) - Cotizador: se oculta el editor de descuento (usan los % del Excel); enganche seleccionable con mínimo 2.5% del valor de la propiedad, solo en esquemas con crédito (bancario/Infonavit); mensualidades se recalculan con el enganche elegido y nunca quedan en negativo - Cotizador: buscador de cliente en Monday (lead u oportunidad) que prellena nombre/contacto/desarrollo y vincula la cotización a la oportunidad al guardar - Alta Afluencia: buscador que jala nombre, contacto, origen, desarrollo y modelo desde leads y oportunidades existentes - buscarLeads devuelve desarrollo y modelo de interés - Landing: el módulo Clientes vuelve a llamarse Cobranza - Tests: 456 API + 94 cotizador + 14 mi-dia + 116 alta-clientes, verde
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useState, type FormEvent } from 'react'
|
||||
import { z } from 'zod'
|
||||
import { crearAfluencia, type LeadResumen } from '../services/api'
|
||||
import BusquedaLead from './BusquedaLead'
|
||||
import {
|
||||
DESARROLLOS_LEAD,
|
||||
ESTADOS_CIVILES,
|
||||
@@ -78,6 +79,36 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente }: Pro
|
||||
const modelosDelDesarrollo =
|
||||
MODELOS_POR_PROYECTO[form.desarrollo as keyof typeof MODELOS_POR_PROYECTO] ?? []
|
||||
|
||||
/**
|
||||
* Jala los datos de un lead u oportunidad ya capturados en Monday:
|
||||
* nombre/contacto siempre; origen, desarrollo y modelo solo si el valor del
|
||||
* lead existe entre las opciones del formulario.
|
||||
*/
|
||||
const prellenarDesdeLead = (lead: LeadResumen) => {
|
||||
setForm((prev) => {
|
||||
const desarrollo =
|
||||
lead.desarrollo !== undefined && (DESARROLLOS_LEAD as readonly string[]).includes(lead.desarrollo)
|
||||
? lead.desarrollo
|
||||
: prev.desarrollo
|
||||
const modelos = MODELOS_POR_PROYECTO[desarrollo as keyof typeof MODELOS_POR_PROYECTO] ?? []
|
||||
const modelo =
|
||||
lead.modeloInteres !== undefined && (modelos as readonly string[]).includes(lead.modeloInteres)
|
||||
? lead.modeloInteres
|
||||
: ''
|
||||
return {
|
||||
...prev,
|
||||
nombre: lead.nombre,
|
||||
telefono: lead.telefono,
|
||||
email: lead.email,
|
||||
origen: (ORIGENES_LEAD as readonly string[]).includes(lead.origen) ? lead.origen : prev.origen,
|
||||
desarrollo,
|
||||
modelo,
|
||||
}
|
||||
})
|
||||
setErrores({})
|
||||
setAviso('')
|
||||
}
|
||||
|
||||
const validar = (): boolean => {
|
||||
const nuevos: Errores = {}
|
||||
if (!form.nombre.trim()) nuevos.nombre = 'El nombre es obligatorio'
|
||||
@@ -180,6 +211,12 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente }: Pro
|
||||
|
||||
return (
|
||||
<form onSubmit={(e) => void enviar(e)} noValidate>
|
||||
<div className="mb-6 border-b border-[#E5E7EB] pb-6">
|
||||
<BusquedaLead onSeleccion={prellenarDesdeLead} />
|
||||
<p className="mt-2 text-xs text-[#64748B]">
|
||||
Si el interesado ya está en Monday (lead u oportunidad), sus datos se prellenan solos.
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid gap-6 sm:grid-cols-2">
|
||||
<label htmlFor="afluencia-nombre" className="block sm:col-span-2">
|
||||
<span className={labelClase}>
|
||||
|
||||
@@ -227,6 +227,10 @@ export interface LeadResumen {
|
||||
origen: string
|
||||
/** 'lead' = archivo histórico (tablero Leads); 'oportunidad' = modelo nuevo (tablero Oportunidades) */
|
||||
fuente: 'lead' | 'oportunidad'
|
||||
/** Desarrollo de interés ('' si no tiene); prellena la afluencia */
|
||||
desarrollo?: string
|
||||
/** Modelo de interés ('' si no tiene) */
|
||||
modeloInteres?: string
|
||||
}
|
||||
|
||||
/** GET /leads/buscar?q= — autocompletado para prellenar el alta (busca en AMBOS tableros) */
|
||||
|
||||
Reference in New Issue
Block a user