diff --git a/server.js b/server.js index 8515545..d54c546 100644 --- a/server.js +++ b/server.js @@ -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,