feat: Interesado en leads, lada MX/USA, orígenes FRASA y subcategoría de descarte
- Mis leads: botón Interesado (label sembrado en Monday, mueve a Leads Progreso); el botón Agenda cita ahora solo vive en Mis oportunidades - Descarte: además de la categoría, subcategoría del catálogo de Monday (workspace de referencia CRM FRASA); se guarda en la columna Subcategoria del tablero Motivos No Compra y el item queda en el grupo de su categoría - Teléfonos con selector de lada 🇲🇽 +52 / 🇺🇸 +1 en captura rápida (Mi día), Alta Afluencia y Alta de Cliente (tel. casa y celular); Monday escribe countryShortName MX/US y el número compacto (rechaza espacios); el dedup sigue comparando por los últimos 10 dígitos - Origen nuevo en captura rápida y afluencia: PASE, PROSPECCION ASESOR, ACTIVACION, FACEBOOK FRASA, REFERIDO, OTRO (sembrados en Leads.Origen y Oportunidades.Origen del Lead) - Tests: 461 API + 16 mi-dia + 116 alta-clientes, verde
This commit is contained in:
@@ -14,8 +14,8 @@ import {
|
||||
} from './mi-dia'
|
||||
|
||||
describe('catálogos', () => {
|
||||
it('orígenes = labels reales de la columna Origen del board Leads', () => {
|
||||
expect([...ORIGENES_LEAD]).toEqual(['WhatsApp', 'Web', 'Recomendado', 'Facebook', 'Otro'])
|
||||
it('orígenes = vocabulario FRASA sembrado en Monday (Leads y Oportunidades)', () => {
|
||||
expect([...ORIGENES_LEAD]).toEqual(['PASE', 'PROSPECCION ASESOR', 'ACTIVACION', 'FACEBOOK FRASA', 'REFERIDO', 'OTRO'])
|
||||
})
|
||||
|
||||
it('desarrollos = labels reales de la columna Desarrollo del board Leads', () => {
|
||||
|
||||
@@ -100,8 +100,9 @@ export interface ResumenMiDia {
|
||||
}
|
||||
}
|
||||
|
||||
// Labels reales de la columna status 'Origen' del board Leads (verificados en Monday)
|
||||
export const ORIGENES_LEAD = ['WhatsApp', 'Web', 'Recomendado', 'Facebook', 'Otro'] as const
|
||||
// Labels de la columna 'Origen' (board Leads) / 'Origen del Lead' (Oportunidades),
|
||||
// vocabulario FRASA verificado y sembrado en Monday el 2026-09-04
|
||||
export const ORIGENES_LEAD = ['PASE', 'PROSPECCION ASESOR', 'ACTIVACION', 'FACEBOOK FRASA', 'REFERIDO', 'OTRO'] as const
|
||||
|
||||
// Labels reales de la columna status 'Desarrollo' del board Leads (verificados en Monday)
|
||||
export const DESARROLLOS_LEAD = ['ATELIER', 'DIAGONAL', 'ESTANZA', 'SENDA', 'SOLANA'] as const
|
||||
@@ -119,6 +120,39 @@ export const MOTIVOS_NO_COMPRA = [
|
||||
|
||||
export type MotivoNoCompra = (typeof MOTIVOS_NO_COMPRA)[number]
|
||||
|
||||
// Subcategorías por categoría del tablero Motivos No Compra (catálogo del
|
||||
// workspace de referencia CRM FRASA, sembrado en Frasa-CAS el 2026-09-04).
|
||||
// Espejo de SUBCATEGORIAS_NO_COMPRA del API (mantener sincronizados).
|
||||
export const SUBCATEGORIAS_NO_COMPRA: Record<MotivoNoCompra, string[]> = {
|
||||
Precio: ['Precio Total', 'Enganche', 'Mesualidad'],
|
||||
Producto: ['Distribucion', 'Tamaño', 'Recamaras', 'Baños', 'Amenidades', 'Acabados', 'Estacionamiento', 'Seguridad', 'Inventario'],
|
||||
Ubicacion: ['Zona', 'Accesos', 'Distancia', 'Servicios', 'Seguridad', 'Escuela', 'Trabajo'],
|
||||
Financiamiento: ['No Califica', 'Credito Insuficiente', 'Tasa de interes', 'Mensualidad Alta', 'Enganche Alto', 'Forma de Pago', 'Infonavit Insuficiente', 'No tiene liquidez'],
|
||||
Competencia: ['Precio', 'Producto', 'Ubicacion', 'Promocion', 'Financiamiento'],
|
||||
Cliente: ['Cambo de Planes', 'Decision Familiar', 'No estaba Listo', 'Emergencia Personal'],
|
||||
Timing: ['Compra Posterior', 'Esperando Credito', 'Esperando Venta de Propiedad', 'Esperando Proyecto'],
|
||||
}
|
||||
|
||||
// LADAs soportadas en la captura de teléfonos (México default, USA opcional)
|
||||
export const LADAS = [
|
||||
{ clave: 'MX', etiqueta: '🇲🇽 +52', prefijo: '+52' },
|
||||
{ clave: 'US', etiqueta: '🇺🇸 +1', prefijo: '+1' },
|
||||
] as const
|
||||
|
||||
export type ClaveLada = (typeof LADAS)[number]['clave']
|
||||
|
||||
/**
|
||||
* Compone el teléfono a guardar: "<prefijo> <numero>" (p. ej. "+52 4771234567").
|
||||
* Si el número ya trae prefijo internacional, se respeta tal cual.
|
||||
*/
|
||||
export function componerTelefono(lada: ClaveLada, numero: string): string {
|
||||
const limpio = numero.trim()
|
||||
if (limpio === '') return ''
|
||||
if (limpio.startsWith('+')) return limpio
|
||||
const prefijo = LADAS.find((l) => l.clave === lada)?.prefijo ?? '+52'
|
||||
return `${prefijo} ${limpio}`
|
||||
}
|
||||
|
||||
// Fases del funnel de Oportunidades (labels REALES del board; el API las valida tal cual)
|
||||
export const FASES_OPORTUNIDAD = ['Agendo Cita', 'Afluencia', 'Cotizador', 'Aparto', 'No Asistio', 'Abandono'] as const
|
||||
export type FaseOportunidad = (typeof FASES_OPORTUNIDAD)[number]
|
||||
|
||||
Reference in New Issue
Block a user