From f00b8549595d85b77d405b51214d3de235e9fc94 Mon Sep 17 00:00:00 2001 From: marsalva Date: Wed, 4 Mar 2026 22:46:41 +0000 Subject: [PATCH] Actualizar server.js --- server.js | 101 +++++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/server.js b/server.js index ba7f9a1..693d5ae 100644 --- a/server.js +++ b/server.js @@ -1368,6 +1368,7 @@ app.get("/services/active", authMiddleware, async (req, res) => { // AÑADIDO: Ruta para fijar la cita o el estado operativo (CORREGIDA PARA NO PERDER LA FECHA) // AÑADIDO: Ruta para fijar la cita o el estado operativo (CORREGIDA PARA NO PERDER LA FECHA Y ENVIAR BIEN EL WHATSAPP) +// AÑADIDO: Ruta para fijar la cita o el estado operativo (CON ENVÍO WA EN SEGUNDO PLANO) app.put("/services/set-appointment/:id", authMiddleware, async (req, res) => { try { const { id } = req.params; @@ -1398,7 +1399,7 @@ app.put("/services/set-appointment/:id", authMiddleware, async (req, res) => { newTime = ""; } - // 1. PRIMERO GUARDAMOS EN BASE DE DATOS (Para que los motores puedan leer la info real) + // 1. GUARDAMOS EN BBDD RÁPIDAMENTE const updatedRawData = { ...rawActual, ...extra, @@ -1411,59 +1412,65 @@ app.put("/services/set-appointment/:id", authMiddleware, async (req, res) => { [JSON.stringify(updatedRawData), finalAssignedTo, id, req.user.accountId] ); - // 2. DESPUÉS LANZAMOS LOS EVENTOS (Con la BBDD ya actualizada) - if (stName.includes('asignado')) { - 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 AND owner_id = $3', [JSON.stringify(updatedRawData), id, req.user.accountId]); - } - } - } - else if (stName.includes('esperando') || stName.includes('pendiente de cita')) { - await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_assigned'); - } - else if (stName.includes('pendiente de asignar') || stName.includes('desasignado')) { - const oldWorkerId = finalAssignedTo || rawActual.assigned_to; - if (oldWorkerId) { - const workerQ = await pool.query("SELECT full_name, phone FROM users WHERE id=$1", [oldWorkerId]); - if (workerQ.rowCount > 0) { - const w = workerQ.rows[0]; - const ref = rawActual.service_ref || rawActual["Referencia"] || id; - const msg = `⚠️ *AVISO DE DESASIGNACIÓN*\n\nHola ${w.full_name}, se te ha retirado el expediente *#${ref}*.\n\nYa no tienes que atender este servicio.`; - sendWhatsAppAuto(w.phone, msg, `cliente_${req.user.accountId}`, false).catch(console.error); - } - } - // Limpieza de datos si se desasigna - updatedRawData.assigned_to = null; - updatedRawData.assigned_to_name = null; - finalAssignedTo = null; - await pool.query('UPDATE scraped_services SET raw_data = $1, assigned_to = null WHERE id = $2 AND owner_id = $3', [JSON.stringify(updatedRawData), id, req.user.accountId]); - } - else if (stName.includes('citado') && newDate !== "" && date !== undefined) { - const oldDate = rawActual.scheduled_date || ""; - if (oldDate === "") await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_date'); - else if (oldDate !== newDate) await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_update'); - } else if (stName.includes('camino')) { - await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_onway'); - } else if (stName.includes('finalizado') || stName.includes('terminado')) { - if (!skip_survey) { // Solo lo mandamos si el operario no dijo que NO - await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_survey'); - } - } - // --- INICIO TRAZABILIDAD --- let logDetalle = `Estado modificado a: ${stName.toUpperCase() || 'MODIFICADO'}.`; if (newDate) logDetalle += ` Cita para el ${newDate} a las ${newTime}.`; await registrarMovimiento(id, req.user.sub, "Actualización desde App", logDetalle); - // --- FIN TRAZABILIDAD --- - + + // 🚀 RESPONDEMOS AL NAVEGADOR INMEDIATAMENTE (La ventana se cierra al instante) res.json({ ok: true }); + + // 2. MAGIA: TAREAS EN SEGUNDO PLANO (El WhatsApp tarda lo que tenga que tardar, sin bloquear) + (async () => { + try { + if (stName.includes('asignado')) { + 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 AND owner_id = $3', [JSON.stringify(updatedRawData), id, req.user.accountId]); + } + } + } + else if (stName.includes('esperando') || stName.includes('pendiente de cita')) { + await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_assigned'); + } + else if (stName.includes('pendiente de asignar') || stName.includes('desasignado')) { + const oldWorkerId = finalAssignedTo || rawActual.assigned_to; + if (oldWorkerId) { + const workerQ = await pool.query("SELECT full_name, phone FROM users WHERE id=$1", [oldWorkerId]); + if (workerQ.rowCount > 0) { + const w = workerQ.rows[0]; + const ref = rawActual.service_ref || rawActual["Referencia"] || id; + const msg = `⚠️ *AVISO DE DESASIGNACIÓN*\n\nHola ${w.full_name}, se te ha retirado el expediente *#${ref}*.\n\nYa no tienes que atender este servicio.`; + sendWhatsAppAuto(w.phone, msg, `cliente_${req.user.accountId}`, false).catch(console.error); + } + } + updatedRawData.assigned_to = null; + updatedRawData.assigned_to_name = null; + await pool.query('UPDATE scraped_services SET raw_data = $1, assigned_to = null WHERE id = $2 AND owner_id = $3', [JSON.stringify(updatedRawData), id, req.user.accountId]); + } + else if (stName.includes('citado') && newDate !== "" && date !== undefined) { + const oldDate = rawActual.scheduled_date || ""; + if (oldDate === "") await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_date'); + else if (oldDate !== newDate) await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_update'); + } else if (stName.includes('camino')) { + await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_onway'); + } else if (stName.includes('finalizado') || stName.includes('terminado')) { + if (!skip_survey) { + await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_survey'); + } + } + } catch (errBckg) { + console.error("Error en tareas de fondo:", errBckg); + } + })(); // El paréntesis final ejecuta esto en las sombras + } catch (e) { console.error("Error agendando cita:", e); - res.status(500).json({ ok: false }); + // Solo enviamos error si no hemos respondido ya + if (!res.headersSent) res.status(500).json({ ok: false }); } });