Actualizar server.js
This commit is contained in:
80
server.js
80
server.js
@@ -1811,6 +1811,50 @@ app.post("/providers/credentials", authMiddleware, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// ==========================================
|
||||
// 🚀 MOTOR DE AUTO-ASIGNACIÓN (BOLSA INTERNA)
|
||||
// ==========================================
|
||||
async function dispatchToBolsa(serviceId, guildId, cp, accountId, userId) {
|
||||
try {
|
||||
let workersQ = await pool.query(`
|
||||
SELECT u.id, u.full_name, u.phone FROM users u
|
||||
JOIN user_guilds ug ON u.id = ug.user_id
|
||||
WHERE u.owner_id = $1 AND u.role = 'operario' AND u.status = 'active'
|
||||
AND ug.guild_id = $2 AND u.zones::jsonb @> $3::jsonb
|
||||
`, [accountId, guildId, JSON.stringify([{ cps: (cp || "00000").toString() }])]);
|
||||
|
||||
if (workersQ.rowCount === 0) {
|
||||
workersQ = await pool.query(`
|
||||
SELECT u.id, u.full_name, u.phone FROM users u
|
||||
JOIN user_guilds ug ON u.id = ug.user_id
|
||||
WHERE u.owner_id = $1 AND u.role = 'operario' AND u.status = 'active' AND ug.guild_id = $2
|
||||
`, [accountId, guildId]);
|
||||
}
|
||||
|
||||
if (workersQ.rowCount === 0) {
|
||||
console.log(`⚠️ [AUTO-DISPATCH] No hay operarios activos para el gremio ${guildId}.`);
|
||||
return { ok: false, error: "No hay operarios disponibles para este gremio" };
|
||||
}
|
||||
|
||||
await pool.query("UPDATE scraped_services SET automation_status = 'in_progress' WHERE id = $1", [serviceId]);
|
||||
const worker = workersQ.rows[Math.floor(Math.random() * workersQ.rows.length)];
|
||||
const token = crypto.randomBytes(16).toString('hex');
|
||||
|
||||
await pool.query(`INSERT INTO assignment_pings (scraped_id, user_id, token, expires_at) VALUES ($1, $2, $3, CURRENT_TIMESTAMP + INTERVAL '5 minutes')`, [serviceId, worker.id, token]);
|
||||
|
||||
const msg = `🚨 *NUEVA URGENCIA DISPONIBLE*\n📍 Zona: ${(cp && cp !== "00000") ? cp : "Asignada"}\n🔗 https://web.integrarepara.es/aceptar.html?t=${token}`;
|
||||
sendWhatsAppAuto(worker.phone, msg, `cliente_${accountId}`, false).catch(console.error);
|
||||
|
||||
await registrarMovimiento(serviceId, userId, "Bolsa Automática", `Notificación enviada a: ${worker.full_name}`);
|
||||
console.log(`✅ [AUTO-DISPATCH] Urgencia enviada con éxito a ${worker.full_name}`);
|
||||
|
||||
return { ok: true };
|
||||
} catch (e) {
|
||||
console.error("❌ Error en dispatchToBolsa:", e);
|
||||
return { ok: false, error: "Error interno" };
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 📥 RECEPCIÓN DE SERVICIOS (EL DETECTOR DEFINITIVO Y MÁS LIMPIO)
|
||||
// ==========================================
|
||||
@@ -1830,7 +1874,6 @@ app.post("/providers/scraped", authMiddleware, async (req, res) => {
|
||||
);
|
||||
|
||||
// 🐛 ¡AQUÍ ESTABA EL BUG DEL INTERRUPTOR! 🐛
|
||||
// La BD devuelve un 1, pero JS esperaba un 'true'. Lo hacemos flexible:
|
||||
let autoDispatchEnabled = false;
|
||||
if (credsQ.rowCount > 0) {
|
||||
const val = credsQ.rows[0].auto_dispatch;
|
||||
@@ -1877,7 +1920,6 @@ app.post("/providers/scraped", authMiddleware, async (req, res) => {
|
||||
const newSvcId = insertRes.rows[0].id;
|
||||
const autoStatus = insertRes.rows[0].automation_status;
|
||||
|
||||
// 🕵️ CHIVATO EN CONSOLA PARA VER POR QUÉ NO SALTA
|
||||
console.log(`[DEBUG-BOLSA] Ref: ${ref} | Urgente: ${esUrgente} | Gremio: ${guildId} | Auto_ON: ${autoDispatchEnabled} | Estado: ${autoStatus}`);
|
||||
|
||||
// 🔥 DISPARO AUTOMÁTICO REPARADO 🔥
|
||||
@@ -1886,7 +1928,7 @@ app.post("/providers/scraped", authMiddleware, async (req, res) => {
|
||||
const cpMatch = todoElTexto.match(/\b\d{5}\b/);
|
||||
const cpFinal = cpMatch ? cpMatch[0] : "00000";
|
||||
|
||||
// Llamamos directamente a la función
|
||||
// Llamamos directamente a la función, pasando el ownerId y userId (para los logs)
|
||||
dispatchToBolsa(newSvcId, guildId, cpFinal, req.user.accountId, req.user.sub);
|
||||
}
|
||||
|
||||
@@ -1940,40 +1982,18 @@ app.get("/providers/scraped", authMiddleware, async (req, res) => {
|
||||
app.post("/providers/automate/:id", authMiddleware, async (req, res) => {
|
||||
const { id } = req.params;
|
||||
try {
|
||||
const { guild_id, cp, useDelay } = req.body;
|
||||
const { guild_id, cp } = req.body;
|
||||
if (!guild_id) return res.status(400).json({ ok: false, error: "Falta Gremio" });
|
||||
|
||||
const serviceQ = await pool.query("SELECT raw_data, provider, owner_id FROM scraped_services WHERE id = $1", [id]);
|
||||
if (serviceQ.rowCount === 0) return res.status(404).json({ ok: false, error: "Expediente no encontrado" });
|
||||
|
||||
let workersQ = await pool.query(`
|
||||
SELECT u.id, u.full_name, u.phone FROM users u
|
||||
JOIN user_guilds ug ON u.id = ug.user_id
|
||||
WHERE u.owner_id = $1 AND u.role = 'operario' AND u.status = 'active'
|
||||
AND ug.guild_id = $2 AND u.zones::jsonb @> $3::jsonb
|
||||
`, [req.user.accountId, guild_id, JSON.stringify([{ cps: (cp || "00000").toString() }])]);
|
||||
// Llamamos a nuestra nueva función reutilizable
|
||||
const result = await dispatchToBolsa(id, guild_id, cp, req.user.accountId, req.user.sub);
|
||||
|
||||
if (workersQ.rowCount === 0) {
|
||||
workersQ = await pool.query(`
|
||||
SELECT u.id, u.full_name, u.phone FROM users u
|
||||
JOIN user_guilds ug ON u.id = ug.user_id
|
||||
WHERE u.owner_id = $1 AND u.role = 'operario' AND u.status = 'active' AND ug.guild_id = $2
|
||||
`, [req.user.accountId, guild_id]);
|
||||
}
|
||||
if (result.ok) res.json({ ok: true });
|
||||
else res.status(404).json(result);
|
||||
|
||||
if (workersQ.rowCount === 0) return res.status(404).json({ ok: false, error: "No hay operarios disponibles" });
|
||||
|
||||
await pool.query("UPDATE scraped_services SET automation_status = 'in_progress' WHERE id = $1", [id]);
|
||||
const worker = workersQ.rows[Math.floor(Math.random() * workersQ.rows.length)];
|
||||
const token = crypto.randomBytes(16).toString('hex');
|
||||
|
||||
await pool.query(`INSERT INTO assignment_pings (scraped_id, user_id, token, expires_at) VALUES ($1, $2, $3, CURRENT_TIMESTAMP + INTERVAL '5 minutes')`, [id, worker.id, token]);
|
||||
|
||||
const msg = `🛠️ *NUEVO SERVICIO DISPONIBLE*\n📍 Zona: ${(cp && cp !== "00000") ? cp : "Asignada"}\n🔗 https://web.integrarepara.es/aceptar.html?t=${token}`;
|
||||
sendWhatsAppAuto(worker.phone, msg, `cliente_${req.user.accountId}`, useDelay).catch(console.error);
|
||||
|
||||
await registrarMovimiento(id, req.user.sub, "Bolsa Automática", `Notificación enviada a: ${worker.full_name}`);
|
||||
res.json({ ok: true });
|
||||
} catch (e) { res.status(500).json({ ok: false }); }
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user