diff --git a/server.js b/server.js index 02811e1..7e4a619 100644 --- a/server.js +++ b/server.js @@ -685,6 +685,91 @@ async function triggerHomeServeRobot(ownerId, serviceId, eventType) { } } +// ========================================== +// 🤖 PUENTE AUTOMÁTICO HACIA MULTIASISTENCIA +// ========================================== +async function triggerMultiRobot(ownerId, serviceId, eventType) { + try { + const userQ = await pool.query("SELECT wa_settings FROM users WHERE id=$1", [ownerId]); + const settings = userQ.rows[0]?.wa_settings?.robot_multi || {}; + + const rule = settings[eventType]; + if (!rule || !rule.enabled) { + console.log(`🤖 [ROBOT MULTI] Regla '${eventType}' desactivada. Omitiendo.`); + return; + } + + const svcQ = await pool.query(` + SELECT s.service_ref, s.raw_data, u.full_name as worker_name + FROM scraped_services s + LEFT JOIN users u ON s.assigned_to = u.id + WHERE s.id = $1 + `, [serviceId]); + if (svcQ.rowCount === 0) return; + + const s = svcQ.rows[0]; + const raw = s.raw_data || {}; + + let targetDate = new Date(); + let formattedDate = ""; + let formattedTime = ""; + + if (eventType === 'date' && raw.scheduled_date) { + const [y, m, d] = raw.scheduled_date.split('-'); + formattedDate = `${d.padStart(2, '0')}/${m.padStart(2, '0')}/${y}`; + formattedTime = raw.scheduled_time || ""; + } else { + const daysToAdd = parseInt(rule.days_next) || 0; + targetDate.setDate(targetDate.getDate() + daysToAdd); + + if (targetDate.getDay() === 6) targetDate.setDate(targetDate.getDate() + 2); + else if (targetDate.getDay() === 0) targetDate.setDate(targetDate.getDate() + 1); + + const dd = String(targetDate.getDate()).padStart(2, '0'); + const mm = String(targetDate.getMonth() + 1).padStart(2, '0'); + const yyyy = targetDate.getFullYear(); + formattedDate = `${dd}/${mm}/${yyyy}`; + + const horaActual = `${String(new Date().getHours()).padStart(2, '0')}:${String(new Date().getMinutes()).padStart(2, '0')}`; + formattedTime = raw.scheduled_time || horaActual; + } + + let text = rule.obs || ""; + const clientName = raw["Nombre Cliente"] || raw["CLIENTE"] || "Cliente"; + let clientPhone = raw["Teléfono"] || raw["TELEFONO"] || raw["TELEFONOS"] || ""; + clientPhone = extractValidPhone(clientPhone); + + let textoFechaCita = "hoy"; + if (raw.scheduled_date) { + const [y, m, d] = raw.scheduled_date.split('-'); + textoFechaCita = `${d.padStart(2, '0')}/${m.padStart(2, '0')}/${y}`; + } else { + const hoy = new Date(); + textoFechaCita = `${String(hoy.getDate()).padStart(2, '0')}/${String(hoy.getMonth() + 1).padStart(2, '0')}/${hoy.getFullYear()}`; + } + + text = text.replace(/{{NOMBRE}}/g, clientName); + text = text.replace(/{{FECHA}}/g, textoFechaCita); + text = text.replace(/{{HORA}}/g, formattedTime); + text = text.replace(/{{TELEFONO}}/g, clientPhone); + text = text.replace(/{{REFERENCIA}}/g, s.service_ref); + text = text.replace(/{{NOMBRE_OPERARIO}}/g, s.worker_name || "el técnico"); + + // Añadimos columna si no existe por si acaso + await pool.query(`ALTER TABLE robot_queue ADD COLUMN IF NOT EXISTS appointment_time TEXT;`).catch(() => {}); + + await pool.query(` + INSERT INTO robot_queue (owner_id, provider, service_number, new_status, appointment_date, appointment_time, observation, inform_client) + VALUES ($1, 'multiasistencia', $2, $3, $4, $5, $6, false) + `, [ownerId, s.service_ref, rule.status, formattedDate, formattedTime, text]); + + console.log(`🤖 [ROBOT MULTI] Orden enviada a la cola para exp ${s.service_ref} (Regla: ${eventType}) | Fecha: ${formattedDate} | Hora: ${formattedTime}`); + + } catch(e) { + console.error("❌ Error en puente Multiasistencia:", e); + } +} + // ========================================== // 🕵️ ROBOT NOTARIO (TRAZABILIDAD TOTAL) @@ -1633,21 +1718,37 @@ app.put('/providers/scraped/:id', authMiddleware, async (req, res) => { else triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_update').catch(console.error); } - // 🚀 DISPARAR ROBOT HOMESERVE - const checkHs = await pool.query("SELECT provider FROM scraped_services WHERE id=$1", [id]); - if (checkHs.rows[0]?.provider === 'homeserve') { + // 🚀 DISPARAR ROBOTS SEGÚN PROVEEDOR + const checkProvider = await pool.query("SELECT provider FROM scraped_services WHERE id=$1", [id]); + const providerName = checkProvider.rows[0]?.provider; + + if (providerName === 'homeserve') { if (statusChanged && isAsignado && finalAssignedTo) { - console.log("✅ [ADMIN] Disparando robot: ASIGNACIÓN"); + console.log("✅ [ADMIN] Disparando robot HS: ASIGNACIÓN"); triggerHomeServeRobot(req.user.accountId, id, 'assign').catch(console.error); } if (isCitado && (statusChanged || dateChanged) && newDate !== "" && newDate !== "null") { - console.log(`✅ [ADMIN] Disparando robot: CITA (${newDate})`); + console.log(`✅ [ADMIN] Disparando robot HS: CITA (${newDate})`); triggerHomeServeRobot(req.user.accountId, id, 'date').catch(console.error); } if (isNoLocalizado && statusChanged) { - console.log(`✅ [ADMIN] Disparando robot: NO LOCALIZADO`); + console.log(`✅ [ADMIN] Disparando robot HS: NO LOCALIZADO`); triggerHomeServeRobot(req.user.accountId, id, 'notfound').catch(console.error); } + } + else if (providerName === 'multiasistencia') { + if (statusChanged && isAsignado && finalAssignedTo) { + console.log("✅ [ADMIN] Disparando robot MULTI: ASIGNACIÓN"); + triggerMultiRobot(req.user.accountId, id, 'assign').catch(console.error); + } + if (isCitado && (statusChanged || dateChanged) && newDate !== "" && newDate !== "null") { + console.log(`✅ [ADMIN] Disparando robot MULTI: CITA (${newDate})`); + triggerMultiRobot(req.user.accountId, id, 'date').catch(console.error); + } + if (isNoLocalizado && statusChanged) { + console.log(`✅ [ADMIN] Disparando robot MULTI: NO LOCALIZADO`); + triggerMultiRobot(req.user.accountId, id, 'notfound').catch(console.error); + } } res.json({ ok: true }); @@ -1772,32 +1873,45 @@ app.put("/services/set-appointment/:id", authMiddleware, async (req, res) => { console.log(`🤖 [DEBUG APP-OP] Exp: ${id} | Estado: '${stName}' | statusChanged: ${statusChanged} | dateChanged: ${dateChanged}`); - const checkHs = await pool.query("SELECT provider FROM scraped_services WHERE id=$1", [id]); - const isHomeServe = checkHs.rows[0]?.provider === 'homeserve'; + // 🚀 CAMBIO CLAVE: LEER PROVEEDOR REAL (HOME SERVE O MULTIASISTENCIA) + const checkProv = await pool.query("SELECT provider FROM scraped_services WHERE id=$1", [id]); + const providerName = checkProv.rows[0]?.provider; const isAsignado = stName.includes('asignado'); const isCitado = stName.includes('citado') || stName.includes('cita') || stName.includes('agendado'); // --- ASIGNADO --- if (statusChanged && isAsignado) { - if (isHomeServe) triggerHomeServeRobot(req.user.accountId, id, 'assign').catch(console.error); + + // Disparar Robot Inteligente + if (providerName === 'homeserve') triggerHomeServeRobot(req.user.accountId, id, 'assign').catch(console.error); + else if (providerName === 'multiasistencia') triggerMultiRobot(req.user.accountId, id, 'assign').catch(console.error); + + // Notificar por WhatsApp y cambiar a Esperando al Cliente si tiene éxito const waEnviadoExito = await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_assigned'); if (waEnviadoExito) { const estadoEsperando = await pool.query("SELECT id FROM service_statuses WHERE owner_id=$1 AND name='Esperando al Cliente' LIMIT 1", [req.user.accountId]); if (estadoEsperando.rowCount > 0) { updatedRawData.status_operativo = estadoEsperando.rows[0].id; - await pool.query('UPDATE scraped_services SET raw_data = $1 WHERE id = $2', [JSON.stringify(updatedRawData), id]); + await pool.query('UPDATE scraped_services SET raw_data = $1 WHERE id = $2 AND owner_id = $3', [JSON.stringify(updatedRawData), id, req.user.accountId]); } } } // --- CITADO (CONFIRMAR CITA) --- else if (isCitado && (statusChanged || dateChanged)) { - if (isHomeServe && newDate !== "") { - console.log(`✅ [APP-OP] Disparando robot: CITA (${newDate})`); - triggerHomeServeRobot(req.user.accountId, id, 'date').catch(console.error); + if (newDate !== "") { + // Disparar Robot Inteligente + if (providerName === 'homeserve') { + console.log(`✅ [APP-OP] Disparando robot HS: CITA (${newDate})`); + triggerHomeServeRobot(req.user.accountId, id, 'date').catch(console.error); + } else if (providerName === 'multiasistencia') { + console.log(`✅ [APP-OP] Disparando robot MULTI: CITA (${newDate})`); + triggerMultiRobot(req.user.accountId, id, 'date').catch(console.error); + } } + // Notificar por WhatsApp if (oldDate === "") await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_date'); else if (oldDate !== newDate) await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_update'); } @@ -1818,9 +1932,6 @@ app.put("/services/set-appointment/:id", authMiddleware, async (req, res) => { } }); -// ========================================== -// 📞 RUTA PARA CLIENTE NO LOCALIZADO -// ========================================== // ========================================== // 📞 RUTA PARA CLIENTE NO LOCALIZADO