Actualizar worker-homeserve.js

This commit is contained in:
2026-03-06 08:28:51 +00:00
parent bad1f6004c
commit fe8d487f39

View File

@@ -1,4 +1,4 @@
// worker-homeserve.js (Versión PostgreSQL - MULTI-EMPRESA SAAS - ES Modules) // worker-homeserve.js (Versión Definitiva PostgreSQL - MULTI-EMPRESA SAAS)
import { chromium } from 'playwright'; import { chromium } from 'playwright';
import pg from 'pg'; import pg from 'pg';
@@ -10,7 +10,7 @@ const CONFIG = {
LOGIN_URL: 'https://www.clientes.homeserve.es/cgi-bin/fccgi.exe?w3exec=PROF_PASS', LOGIN_URL: 'https://www.clientes.homeserve.es/cgi-bin/fccgi.exe?w3exec=PROF_PASS',
BASE_CGI: 'https://www.clientes.homeserve.es/cgi-bin/fccgi.exe', BASE_CGI: 'https://www.clientes.homeserve.es/cgi-bin/fccgi.exe',
NAV_TIMEOUT: 60000, NAV_TIMEOUT: 60000,
POLL_INTERVAL_MS: 5000 // Cada 5 segundos mira si hay trabajo POLL_INTERVAL_MS: 5000 // Cada 5 segundos mira si hay trabajo en la pizarra
}; };
if (!CONFIG.DATABASE_URL) { if (!CONFIG.DATABASE_URL) {
@@ -18,7 +18,7 @@ if (!CONFIG.DATABASE_URL) {
process.exit(1); process.exit(1);
} }
// Conexión a tu Base de Datos local/servidor // Conexión a la Base de Datos
const pool = new Pool({ connectionString: CONFIG.DATABASE_URL, ssl: false }); const pool = new Pool({ connectionString: CONFIG.DATABASE_URL, ssl: false });
// --- UTILS --- // --- UTILS ---
@@ -40,7 +40,6 @@ function checkWeekend(dateStr) {
// --- DESENCRIPTAR CREDENCIALES (MULTI-EMPRESA) --- // --- DESENCRIPTAR CREDENCIALES (MULTI-EMPRESA) ---
async function getHomeServeCreds(ownerId) { async function getHomeServeCreds(ownerId) {
// 🔴 AHORA FILTRAMOS POR EL OWNER_ID EXACTO DEL SERVICIO
const q = await pool.query( const q = await pool.query(
"SELECT username, password_hash FROM provider_credentials WHERE provider = 'homeserve' AND status = 'active' AND owner_id = $1 LIMIT 1", "SELECT username, password_hash FROM provider_credentials WHERE provider = 'homeserve' AND status = 'active' AND owner_id = $1 LIMIT 1",
[ownerId] [ownerId]
@@ -89,14 +88,6 @@ async function fillFirstThatExists(page, selectors, value) {
return null; return null;
} }
async function getDebugInfo(page) {
try {
const title = await page.title();
const url = page.url();
return `URL: ${url} | Titulo: ${title}`;
} catch (e) { return "Error extrayendo debug info"; }
}
// --- INYECCIÓN EN HOMESERVE --- // --- INYECCIÓN EN HOMESERVE ---
async function loginAndProcess(page, creds, jobData) { async function loginAndProcess(page, creds, jobData) {
console.log(`>>> 1. Login en HomeServe con usuario: ${creds.user}`); console.log(`>>> 1. Login en HomeServe con usuario: ${creds.user}`);
@@ -136,13 +127,12 @@ async function loginAndProcess(page, creds, jobData) {
// 🔴 MAGIA: DICCIONARIO TRADUCTOR DE ESTADOS // 🔴 MAGIA: DICCIONARIO TRADUCTOR DE ESTADOS
const HOMESERVE_MAP = { const HOMESERVE_MAP = {
'CITADO': '307', // En espera de Prof. por fecha de inicio de trabajos 'CITADO': '307',
'ESPERA': '303', // En espera de Cliente por aceptacion Presupuesto 'ESPERA': '303',
'TERMINADO': '345', // En espera de Prof. en realizacion pendiente Terminar 'TERMINADO': '345',
'ANULADO': '352' // Provisional: En espera de Perjudicado por indicaciones 'ANULADO': '352'
}; };
// Traduce "CITADO" a "307" antes de buscarlo
let targetCode = jobData.new_status.toUpperCase(); let targetCode = jobData.new_status.toUpperCase();
if (HOMESERVE_MAP[targetCode]) { if (HOMESERVE_MAP[targetCode]) {
targetCode = HOMESERVE_MAP[targetCode]; targetCode = HOMESERVE_MAP[targetCode];
@@ -152,7 +142,6 @@ async function loginAndProcess(page, creds, jobData) {
const select = document.querySelector('select[name="ESTADO"]'); const select = document.querySelector('select[name="ESTADO"]');
if (!select) return false; if (!select) return false;
for (const opt of select.options) { for (const opt of select.options) {
// Busca el código exacto
if (opt.value == code || opt.text.toUpperCase().includes(code.toUpperCase())) { if (opt.value == code || opt.text.toUpperCase().includes(code.toUpperCase())) {
select.value = opt.value; select.value = opt.value;
return true; return true;
@@ -180,23 +169,27 @@ async function loginAndProcess(page, creds, jobData) {
console.log('>>> 4. Guardando cambios en HomeServe...'); console.log('>>> 4. Guardando cambios en HomeServe...');
// 🔴 CLICK SEGURO: Usamos Promise.all para asegurarnos de que el clic desencadena la recarga
const saveBtnLocator = page.locator('input[name="BTNCAMBIAESTADO"]'); const saveBtnLocator = page.locator('input[name="BTNCAMBIAESTADO"]');
if (await saveBtnLocator.count() === 0) { if (await saveBtnLocator.count() === 0) {
throw new Error('No encuentro el botón para guardar los cambios en HomeServe.'); throw new Error('No encuentro el botón para guardar los cambios en HomeServe.');
} }
// Esperamos a que la página navegue DESPUÉS de hacer clic // Esperamos a que la página navegue DESPUÉS de hacer clic (El Clic Seguro)
await Promise.all([ await Promise.all([
page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: CONFIG.NAV_TIMEOUT }), page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: CONFIG.NAV_TIMEOUT }),
saveBtnLocator.first().click() saveBtnLocator.first().click()
]); ]);
// Verificación extra: Comprobar si hay algún mensaje de error rojo devuelto por HomeServe // 🔴 LECTURA INTELIGENTE DEL RESULTADO (Evita los falsos errores rojos)
const errorText = await page.locator('font[color="#FF0000"], .Estilo4').first().textContent().catch(() => null); const alertText = await page.locator('font[color="#FF0000"], .Estilo4').first().textContent().catch(() => null);
if (errorText && errorText.trim().length > 0) { if (alertText && alertText.trim().length > 0) {
throw new Error(`HomeServe devolvió un error al guardar: ${errorText.trim()}`); const textUpper = alertText.toUpperCase();
if (!textUpper.includes('EXITO') && !textUpper.includes('ÉXITO')) {
throw new Error(`HomeServe devolvió un error: ${alertText.trim()}`);
} else {
console.log(`>>> Confirmación positiva de HomeServe: ${alertText.trim()}`);
}
} }
await page.waitForTimeout(2000); await page.waitForTimeout(2000);