IA WhatsApp: condiciones de cobertura combinables por gremio ademas de compañía

This commit is contained in:
2026-08-28 21:19:57 +00:00
parent a94f34884f
commit 6a18d229be

View File

@@ -1610,15 +1610,28 @@ async function procesarConIA(ownerId, mensajeCliente, datosExpediente) {
const instruccionesExtra = settings.ai_custom_prompt || "";
const empresaNombre = userData?.full_name || "nuestra empresa";
// 🧾 Condiciones de cobertura por compañía: cada regla tiene una "keyword" corta
// (ej. "santander") que buscamos DENTRO del campo Compañía del expediente, sin
// mayúsculas ni tildes. Así da igual si el texto viene envuelto en cosas de
// Multiasistencia/HomeServe (ej. "MULTI - Siniestros - Santander Generales
// proyecto Gesca") — con que contenga la palabra clave, coincide.
// 🧾 Condiciones de cobertura por compañía y/o gremio: cada regla puede llevar una
// "keyword" corta (ej. "santander") que buscamos DENTRO del campo Compañía del
// expediente, sin mayúsculas ni tildes (así da igual si el texto viene envuelto en
// cosas de Multiasistencia/HomeServe, ej. "MULTI - Siniestros - Santander Generales
// proyecto Gesca" — con que contenga la palabra clave, coincide), y/o un "gremio_id"
// (el id del gremio tal cual está en la tabla guilds) para que las condiciones
// cambien según sea manitas, electricista, fontanería, etc. Una regla necesita al
// menos uno de los dos criterios; si solo lleva uno, ese criterio se ignora (aplica
// a "todas las compañías" o "todos los gremios" según cuál falte). Si varias reglas
// coinciden a la vez, gana la más específica (la que combina compañía + gremio).
const normalizarTexto = (str) => String(str || "").toLowerCase().normalize("NFD").replace(/[̀-ͯ]/g, "");
const coverageRules = Array.isArray(settings.coverage_rules) ? settings.coverage_rules : [];
const companiaNormalizada = normalizarTexto(datosExpediente.compania);
const reglaCobertura = coverageRules.find(r => r.keyword && companiaNormalizada.includes(normalizarTexto(r.keyword)));
const gremioIdActual = String(datosExpediente.guild_id || "");
const reglasCoincidentes = coverageRules.filter(r => {
if (!r.keyword && !r.gremio_id) return false;
const matchCompania = r.keyword ? companiaNormalizada.includes(normalizarTexto(r.keyword)) : true;
const matchGremio = r.gremio_id ? String(r.gremio_id) === gremioIdActual : true;
return matchCompania && matchGremio;
});
const especificidad = (r) => (r.keyword ? 1 : 0) + (r.gremio_id ? 1 : 0);
const reglaCobertura = reglasCoincidentes.sort((a, b) => especificidad(b) - especificidad(a))[0];
if (!settings.wa_ai_enabled) return null;
@@ -2009,7 +2022,7 @@ Eres el coordinador humano de "${empresaNombre}". Hablas de tú, de forma natura
- Fines de semana solo si es una urgencia.
- Localidad del cliente actual: ${datosExpediente.poblacion || 'Localidad no especificada'}.
${reglaCobertura ? `
--- 🧾 CONDICIONES DE COBERTURA PARA ESTA COMPAÑÍA (${datosExpediente.compania}) ---
--- 🧾 CONDICIONES DE COBERTURA PARA ESTE SERVICIO (Compañía: ${datosExpediente.compania || 'no especificada'} · Gremio: ${datosExpediente.gremio || 'no especificado'}) ---
${reglaCobertura.text}
Menciona esto SOLO si el cliente pregunta por costes, materiales, o qué cubre el seguro. No lo repitas si no viene a cuento.` : ''}
@@ -5425,6 +5438,7 @@ async function procesarTurnoIA({ ownerId, service, mensajeTexto, telefonoCliente
poblacion: service.poblacion || "",
cp: service.cp || "",
guild_id: service.guild_id || "",
gremio: service.gremio_nombre || "",
is_urgent: service.is_urgent,
appointment_status: service.appointment_status,
cita_pendiente_fecha: service.cita_pendiente_fecha,
@@ -5540,6 +5554,7 @@ app.post("/webhook/evolution", async (req, res) => {
COALESCE(s.raw_data->>'Población', s.raw_data->>'POBLACION-PROVINCIA', '') as poblacion,
COALESCE(s.raw_data->>'Código Postal', s.raw_data->>'C.P.', '') as cp,
COALESCE(s.raw_data->>'guild_id', '') as guild_id,
COALESCE((SELECT name FROM guilds WHERE id::text = s.raw_data->>'guild_id' LIMIT 1), '') as gremio_nombre,
COALESCE(s.raw_data->>'appointment_status', '') as appointment_status,
COALESCE(s.raw_data->>'requested_date', '') as cita_pendiente_fecha,
COALESCE(s.raw_data->>'requested_time', '') as cita_pendiente_hora,