Actualizar server.js

This commit is contained in:
2026-03-08 22:45:51 +00:00
parent bc55e94ddd
commit 5c287ba38d

View File

@@ -1591,59 +1591,7 @@ app.post("/providers/automate/:id", authMiddleware, async (req, res) => {
} }
}); });
// ========================================== // 3. ACTUALIZACIÓN MANUAL NORMAL DE LA FICHA
// 📝 ACTUALIZACIÓN DE EXPEDIENTES (Y ESCUDO ANTI-ARCHIVO)
// ==========================================
app.put('/providers/scraped/:id', authMiddleware, async (req, res) => {
const { id } = req.params;
let { automation_status, status, name, phone, address, cp, description, guild_id, assigned_to, assigned_to_name, internal_notes, client_notes, is_urgent, ...extra } = req.body;
try {
// 1. Cambio de estado de automatización
if (automation_status) {
await pool.query(`UPDATE scraped_services SET automation_status = $1 WHERE id = $2 AND owner_id = $3`, [automation_status, id, req.user.accountId]);
return res.json({ ok: true });
}
// 2. ESCUDO ANTI-ARCHIVO
if (status === 'archived') {
const checkQ = await pool.query(`
SELECT raw_data, assigned_to, service_ref,
(SELECT is_final FROM service_statuses WHERE id::text = raw_data->>'status_operativo') as is_final
FROM scraped_services WHERE id = $1 AND owner_id = $2
`, [id, req.user.accountId]);
if (checkQ.rowCount > 0) {
const row = checkQ.rows[0];
const isFinal = row.is_final === true;
const hasWorker = row.assigned_to !== null;
let raw = row.raw_data || {};
const serviceRef = row.service_ref || raw["Referencia"] || id;
if (hasWorker && !isFinal) {
if (!raw.cerrado_proveedor) {
raw.cerrado_proveedor = true;
await pool.query(`UPDATE scraped_services SET raw_data = $1 WHERE id = $2 AND owner_id = $3`, [JSON.stringify(raw), id, req.user.accountId]);
await pool.query("INSERT INTO scraped_service_logs (scraped_id, user_name, action, details) VALUES ($1, $2, $3, $4)", [id, 'Sistema (Robot)', 'Intento de Cierre', 'La compañía ha cerrado el aviso, pero se mantiene vivo en IntegraRepara.']);
const workerQ = await pool.query("SELECT full_name, phone FROM users WHERE id=$1", [row.assigned_to]);
if (workerQ.rowCount > 0) {
const w = workerQ.rows[0];
const msg = `🚨 *¡ALERTA URGENTE!* 🚨\n\nHola ${w.full_name}, la compañía aseguradora acaba de *CERRAR/ANULAR* el expediente *#${serviceRef}* en su sistema.\n\n⚠️ *NO ACUDAS NI REALICES EL TRABAJO* si no lo has hecho ya, porque no se va a cobrar.\n\nPor favor, contacta con la oficina.`;
sendWhatsAppAuto(w.phone, msg, `cliente_${req.user.accountId}`, false).catch(console.error);
await pool.query("INSERT INTO scraped_service_logs (scraped_id, user_name, action, details) VALUES ($1, $2, $3, $4)", [id, 'Sistema (Robot)', 'Alerta de Cancelación', `WhatsApp de emergencia enviado a ${w.full_name}.`]);
}
}
return res.json({ ok: true, note: "Protegido de archivo automático y operario alertado" });
}
}
await pool.query(`UPDATE scraped_services SET status = 'archived', automation_status = 'manual' WHERE id = $1 AND owner_id = $2`, [id, req.user.accountId]);
await pool.query("INSERT INTO scraped_service_logs (scraped_id, user_name, action, details) VALUES ($1, $2, $3, $4)", [id, 'Sistema', 'Archivado', 'El expediente se ha cerrado definitivamente y movido al histórico.']);
return res.json({ ok: true });
}
// 3. ACTUALIZACIÓN MANUAL NORMAL
const current = await pool.query('SELECT raw_data, assigned_to, status, is_urgent FROM scraped_services WHERE id = $1 AND owner_id = $2', [id, req.user.accountId]); const current = await pool.query('SELECT raw_data, assigned_to, status, is_urgent FROM scraped_services WHERE id = $1 AND owner_id = $2', [id, req.user.accountId]);
if (current.rows.length === 0) return res.status(404).json({ error: 'No encontrado' }); if (current.rows.length === 0) return res.status(404).json({ error: 'No encontrado' });
@@ -1655,7 +1603,13 @@ app.put('/providers/scraped/:id', authMiddleware, async (req, res) => {
const oldWorkerId = current.rows[0].assigned_to || rawActual.assigned_to; const oldWorkerId = current.rows[0].assigned_to || rawActual.assigned_to;
let finalAssignedTo = assigned_to !== undefined ? (assigned_to === "" ? null : assigned_to) : oldWorkerId; let finalAssignedTo = assigned_to !== undefined ? (assigned_to === "" ? null : assigned_to) : oldWorkerId;
// --- AVISO AL OPERARIO --- // 👇 MAGIA: Detectamos si la fecha ha cambiado independientemente del estado
const oldDate = rawActual.scheduled_date || "";
const newDate = extra.scheduled_date !== undefined ? extra.scheduled_date : oldDate;
const dateChanged = newDate !== "" && newDate !== oldDate;
const statusChanged = newStatus !== oldStatus;
// --- AVISO AL OPERARIO (ASIGNACIÓN NUEVA / DESASIGNACIÓN) ---
if (finalAssignedTo !== oldWorkerId) { if (finalAssignedTo !== oldWorkerId) {
if (finalAssignedTo) { if (finalAssignedTo) {
const workerQ = await pool.query("SELECT full_name, phone FROM users WHERE id=$1", [finalAssignedTo]); const workerQ = await pool.query("SELECT full_name, phone FROM users WHERE id=$1", [finalAssignedTo]);
@@ -1679,10 +1633,12 @@ app.put('/providers/scraped/:id', authMiddleware, async (req, res) => {
// --- LÓGICA DE ESTADOS Y WHATSAPP AL CLIENTE --- // --- LÓGICA DE ESTADOS Y WHATSAPP AL CLIENTE ---
let stName = ""; let stName = "";
if (newStatus && newStatus !== oldStatus) { if (newStatus) {
const statusQ = await pool.query("SELECT name FROM service_statuses WHERE id=$1", [newStatus]); const statusQ = await pool.query("SELECT name FROM service_statuses WHERE id=$1", [newStatus]);
stName = (statusQ.rows[0]?.name || "").toLowerCase(); stName = (statusQ.rows[0]?.name || "").toLowerCase();
}
if (statusChanged) {
if ((stName.includes('pendiente') && !stName.includes('cita')) || stName.includes('desasignado') || stName.includes('asignado') || stName.includes('anulado') || stName.includes('esperando')) { if ((stName.includes('pendiente') && !stName.includes('cita')) || stName.includes('desasignado') || stName.includes('asignado') || stName.includes('anulado') || stName.includes('esperando')) {
if (!extra.scheduled_date) { if (!extra.scheduled_date) {
extra.scheduled_date = ""; extra.scheduled_date = "";
@@ -1703,11 +1659,12 @@ app.put('/providers/scraped/:id', authMiddleware, async (req, res) => {
await registrarMovimiento(id, req.user.sub, "Robot WA", "WhatsApp de asignación falló o está desactivado."); await registrarMovimiento(id, req.user.sub, "Robot WA", "WhatsApp de asignación falló o está desactivado.");
} }
} }
else if (stName.includes('citado') && extra.scheduled_date) {
const oldDate = rawActual.scheduled_date || "";
if (oldDate === "") await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_date');
else if (oldDate !== extra.scheduled_date) await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_update');
} }
// 🟢 NUEVO DISPARADOR WHATSAPP CITA (Se lanza si cambia el estado O la fecha)
if ((statusChanged && stName.includes('citado') && newDate !== "") || (dateChanged && stName.includes('citado'))) {
if (oldDate === "") await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_date');
else if (oldDate !== newDate) await triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_update');
} }
// 4. UNIFICAR DATOS FINALES // 4. UNIFICAR DATOS FINALES
@@ -1730,7 +1687,6 @@ app.put('/providers/scraped/:id', authMiddleware, async (req, res) => {
let currentDbStatus = current.rows[0].status; let currentDbStatus = current.rows[0].status;
const finalIsUrgent = is_urgent !== undefined ? is_urgent : current.rows[0].is_urgent; const finalIsUrgent = is_urgent !== undefined ? is_urgent : current.rows[0].is_urgent;
// GUARDAMOS EN BASE DE DATOS
await pool.query( await pool.query(
`UPDATE scraped_services SET raw_data = $1, status = $2, is_urgent = $3, assigned_to = $4 WHERE id = $5 AND owner_id = $6`, `UPDATE scraped_services SET raw_data = $1, status = $2, is_urgent = $3, assigned_to = $4 WHERE id = $5 AND owner_id = $6`,
[JSON.stringify(updatedRawData), currentDbStatus, finalIsUrgent, finalAssignedTo, id, req.user.accountId] [JSON.stringify(updatedRawData), currentDbStatus, finalIsUrgent, finalAssignedTo, id, req.user.accountId]
@@ -1738,22 +1694,15 @@ app.put('/providers/scraped/:id', authMiddleware, async (req, res) => {
await registrarMovimiento(id, req.user.sub, "Edición / Asignación", "Expediente actualizado o asignado."); await registrarMovimiento(id, req.user.sub, "Edición / Asignación", "Expediente actualizado o asignado.");
// 5. 🤖 DISPARAR ROBOT HOMESERVE (AHORA SÍ, CON LA BBDD YA ACTUALIZADA) // 5. 🤖 DISPARAR ROBOT HOMESERVE (AHORA SÍ, LEE SI CAMBIA FECHA O ESTADO)
if (newStatus && newStatus !== oldStatus) { if (statusChanged && stName.includes('asignado') && finalAssignedTo) {
if (stName.includes('asignado') && finalAssignedTo) {
triggerHomeServeRobot(req.user.accountId, id, 'assign').catch(console.error); triggerHomeServeRobot(req.user.accountId, id, 'assign').catch(console.error);
} }
else if (stName.includes('citado') && updatedRawData.scheduled_date) { if ((statusChanged && stName.includes('citado') && updatedRawData.scheduled_date) || (dateChanged && stName.includes('citado'))) {
triggerHomeServeRobot(req.user.accountId, id, 'date').catch(console.error); triggerHomeServeRobot(req.user.accountId, id, 'date').catch(console.error);
} }
}
res.json({ ok: true }); res.json({ ok: true });
} catch (error) {
console.error("Error actualización manual:", error);
res.status(500).json({ error: 'Error' });
}
});
// Validar si una referencia ya existe para este dueño // Validar si una referencia ya existe para este dueño
app.get("/services/check-ref", authMiddleware, async (req, res) => { app.get("/services/check-ref", authMiddleware, async (req, res) => {