Actualizar worker-multi-estado.js

This commit is contained in:
marsalva 2026-01-06 23:26:21 +00:00
parent 0fac382d4d
commit 329494c1ee
1 changed files with 43 additions and 18 deletions

View File

@ -1,4 +1,4 @@
// worker-multi-estado.js (V6 - LOG COMPLETO DE DATOS) // worker-multi-estado.js (V7 - CON RELLENO DE FECHA CONTACTO)
'use strict'; 'use strict';
const { chromium } = require('playwright'); const { chromium } = require('playwright');
@ -21,6 +21,7 @@ function toServerTimestamp() { return admin.firestore.FieldValue.serverTimestamp
function timeToMultiValue(timeStr) { function timeToMultiValue(timeStr) {
if (!timeStr) return ""; if (!timeStr) return "";
const [h, m] = timeStr.split(':').map(Number); const [h, m] = timeStr.split(':').map(Number);
// Para el desplegable principal (segundos desde medianoche)
return String((h * 3600) + (m * 60)); return String((h * 3600) + (m * 60));
} }
@ -109,7 +110,7 @@ async function processChangeState(page, db, jobData) {
await forceUpdate(await commentBox.elementHandle()); await forceUpdate(await commentBox.elementHandle());
} }
// 5. FECHA // 5. FECHA (Siguiente Acción)
if (dateStr) { if (dateStr) {
const dateInput = page.locator('input[type="date"]').first(); const dateInput = page.locator('input[type="date"]').first();
await dateInput.fill(dateStr); await dateInput.fill(dateStr);
@ -117,7 +118,7 @@ async function processChangeState(page, db, jobData) {
await page.click('body'); await page.click('body');
} }
// 6. HORA // 6. HORA (Siguiente Acción)
if (timeStr) { if (timeStr) {
const secondsValue = timeToMultiValue(timeStr); const secondsValue = timeToMultiValue(timeStr);
const timeSelectHandle = await page.$(`xpath=//select[.//option[@value="${secondsValue}"]]`); const timeSelectHandle = await page.$(`xpath=//select[.//option[@value="${secondsValue}"]]`);
@ -134,6 +135,41 @@ async function processChangeState(page, db, jobData) {
} }
} }
// --- NUEVO BLOQUE: FECHA DE CONTACTO (CONDICIONAL) ---
// Buscamos si existe el campo "Fecha en la que contactó con el cliente"
const contactBlock = page.locator('encastrables-date-hour-field').filter({ hasText: 'Fecha en la que contactó con el cliente' });
if (await contactBlock.count() > 0 && await contactBlock.isVisible()) {
console.log('📞 Detectado campo obligatorio "Fecha contacto cliente". Rellenando...');
// Rellenar Fecha
if (dateStr) {
const contactDateInput = contactBlock.locator('input[type="date"]');
await contactDateInput.fill(dateStr);
await forceUpdate(await contactDateInput.elementHandle());
}
// Rellenar Hora (Este campo es especial, tiene 2 desplegables: Hora y Minutos por separado)
if (timeStr) {
const [hRaw, mRaw] = timeStr.split(':');
// La web usa "8", "9" para horas de un dígito, no "08"
const hVal = String(Number(hRaw));
const mVal = mRaw; // Los minutos sí suelen tener el "00"
const selects = contactBlock.locator('select');
// Asumimos que el primer select es Hora y el segundo Minutos dentro de este bloque
if (await selects.count() >= 1) {
await selects.nth(0).selectOption(hVal).catch(() => {});
await forceUpdate(await selects.nth(0).elementHandle());
}
if (await selects.count() >= 2) {
await selects.nth(1).selectOption(mVal).catch(() => {});
await forceUpdate(await selects.nth(1).elementHandle());
}
}
}
// -----------------------------------------------------
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
// 7. GUARDAR // 7. GUARDAR
@ -153,7 +189,7 @@ async function processChangeState(page, db, jobData) {
console.log('💾 Click en Guardar...'); console.log('💾 Click en Guardar...');
await btn.click(); await btn.click();
// 8. GESTIÓN DE ALERTAS // 8. GESTIÓN DE ALERTAS (POPUP "SÍ")
await page.waitForTimeout(3000); await page.waitForTimeout(3000);
const confirmBtn = page.locator('button.form-container-button-submit-toast').filter({ hasText: 'Sí' }); const confirmBtn = page.locator('button.form-container-button-submit-toast').filter({ hasText: 'Sí' });
@ -195,7 +231,7 @@ async function processChangeState(page, db, jobData) {
}; };
} }
// --- WORKER LOOP (ACTUALIZADO PARA GUARDAR INFO) --- // --- WORKER LOOP ---
async function claimJobById(db, jobId) { async function claimJobById(db, jobId) {
const ref = db.collection(CONFIG.QUEUE_COLLECTION).doc(jobId); const ref = db.collection(CONFIG.QUEUE_COLLECTION).doc(jobId);
return await db.runTransaction(async (tx) => { return await db.runTransaction(async (tx) => {
@ -206,29 +242,22 @@ async function claimJobById(db, jobId) {
}); });
} }
// ✅ MODIFICADO: Ahora recibe el objeto 'job' completo para guardar sus datos
async function markJobDone(db, job, result) { async function markJobDone(db, job, result) {
const jobId = job.id; const jobId = job.id;
// 1. Actualizamos el estado en la cola
await db.collection(CONFIG.QUEUE_COLLECTION).doc(jobId).set({ status: 'DONE', result }, { merge: true }); await db.collection(CONFIG.QUEUE_COLLECTION).doc(jobId).set({ status: 'DONE', result }, { merge: true });
// 2. Guardamos el LOG COMPLETO con los datos de entrada
await db.collection(CONFIG.RESULT_COLLECTION).add({ await db.collection(CONFIG.RESULT_COLLECTION).add({
jobId, jobId,
ok: true, ok: true,
// Datos del servicio enviados:
serviceNumber: job.serviceNumber || '', serviceNumber: job.serviceNumber || '',
reason: job.reasonValue || '', reason: job.reasonValue || '',
comment: job.comment || '', comment: job.comment || '',
date: job.dateStr || '', date: job.dateStr || '',
time: job.timeStr || '', time: job.timeStr || '',
// Resultado del robot: ...result,
...result, // Incluye screenshot y message
createdAt: toServerTimestamp() createdAt: toServerTimestamp()
}); });
} }
// ✅ MODIFICADO: También guardamos los datos si falla, para saber qué provocó el error
async function markJobFailed(db, job, err) { async function markJobFailed(db, job, err) {
const jobId = job.id; const jobId = job.id;
await db.collection(CONFIG.QUEUE_COLLECTION).doc(jobId).set({ await db.collection(CONFIG.QUEUE_COLLECTION).doc(jobId).set({
@ -239,13 +268,11 @@ async function markJobFailed(db, job, err) {
await db.collection(CONFIG.RESULT_COLLECTION).add({ await db.collection(CONFIG.RESULT_COLLECTION).add({
jobId, jobId,
ok: false, ok: false,
// Datos del servicio:
serviceNumber: job.serviceNumber || '', serviceNumber: job.serviceNumber || '',
reason: job.reasonValue || '', reason: job.reasonValue || '',
comment: job.comment || '', comment: job.comment || '',
date: job.dateStr || '', date: job.dateStr || '',
time: job.timeStr || '', time: job.timeStr || '',
// Error:
error: err.message, error: err.message,
createdAt: toServerTimestamp() createdAt: toServerTimestamp()
}); });
@ -262,13 +289,11 @@ async function processJob(db, job) {
dateStr: job.dateStr, dateStr: job.dateStr,
timeStr: job.timeStr timeStr: job.timeStr
}); });
// Pasamos el objeto 'job' entero
await markJobDone(db, job, res); await markJobDone(db, job, res);
console.log(`✅ Job ${job.id} Completado.`); console.log(`✅ Job ${job.id} Completado.`);
}); });
} catch (err) { } catch (err) {
console.error(`❌ Job ${job.id} Falló:`, err.message); console.error(`❌ Job ${job.id} Falló:`, err.message);
// Pasamos el objeto 'job' entero
await markJobFailed(db, job, err); await markJobFailed(db, job, err);
} }
} }
@ -281,7 +306,7 @@ function startWorker(db) {
db.collection(CONFIG.QUEUE_COLLECTION).where('status', '==', 'PENDING').onSnapshot(s => { db.collection(CONFIG.QUEUE_COLLECTION).where('status', '==', 'PENDING').onSnapshot(s => {
s.docChanges().forEach(c => { if(c.type==='added') { queue.push(c.doc.id); run(); } }); s.docChanges().forEach(c => { if(c.type==='added') { queue.push(c.doc.id); run(); } });
}); });
console.log('🚀 Worker Multiasistencia (V6 - LOG COMPLETO) LISTO.'); console.log('🚀 Worker Multiasistencia (V7 - CON FECHA CONTACTO) LISTO.');
} }
const db = initFirebase(); const db = initFirebase();