Actualizar worker-multi-estado.js
This commit is contained in:
parent
329494c1ee
commit
36073d8b3b
|
|
@ -1,4 +1,4 @@
|
||||||
// worker-multi-estado.js (V7 - CON RELLENO DE FECHA CONTACTO)
|
// worker-multi-estado.js (V7 - CON DEBUG DE SELECTOR Y FECHA CONTACTO)
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { chromium } = require('playwright');
|
const { chromium } = require('playwright');
|
||||||
|
|
@ -16,7 +16,10 @@ const CONFIG = {
|
||||||
|
|
||||||
// --- UTILS ---
|
// --- UTILS ---
|
||||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||||
function toServerTimestamp() { return admin.firestore.FieldValue.serverTimestamp(); }
|
|
||||||
|
function toServerTimestamp() {
|
||||||
|
return admin.firestore.FieldValue.serverTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
function timeToMultiValue(timeStr) {
|
function timeToMultiValue(timeStr) {
|
||||||
if (!timeStr) return "";
|
if (!timeStr) return "";
|
||||||
|
|
@ -28,6 +31,7 @@ function timeToMultiValue(timeStr) {
|
||||||
// --- FIREBASE INIT ---
|
// --- FIREBASE INIT ---
|
||||||
function initFirebase() {
|
function initFirebase() {
|
||||||
if (!process.env.FIREBASE_PRIVATE_KEY) throw new Error('Missing FIREBASE_PRIVATE_KEY');
|
if (!process.env.FIREBASE_PRIVATE_KEY) throw new Error('Missing FIREBASE_PRIVATE_KEY');
|
||||||
|
|
||||||
if (!admin.apps.length) {
|
if (!admin.apps.length) {
|
||||||
admin.initializeApp({
|
admin.initializeApp({
|
||||||
credential: admin.credential.cert({
|
credential: admin.credential.cert({
|
||||||
|
|
@ -44,7 +48,11 @@ function initFirebase() {
|
||||||
async function loginMulti(page, db) {
|
async function loginMulti(page, db) {
|
||||||
let user = "", pass = "";
|
let user = "", pass = "";
|
||||||
const doc = await db.collection("providerCredentials").doc("multiasistencia").get();
|
const doc = await db.collection("providerCredentials").doc("multiasistencia").get();
|
||||||
if (doc.exists) { user = doc.data().user; pass = doc.data().pass; }
|
|
||||||
|
if (doc.exists) {
|
||||||
|
user = doc.data().user;
|
||||||
|
pass = doc.data().pass;
|
||||||
|
}
|
||||||
|
|
||||||
if (!user) throw new Error("Faltan credenciales en providerCredentials/multiasistencia");
|
if (!user) throw new Error("Faltan credenciales en providerCredentials/multiasistencia");
|
||||||
|
|
||||||
|
|
@ -53,7 +61,11 @@ async function loginMulti(page, db) {
|
||||||
|
|
||||||
const userFilled = await page.evaluate((u) => {
|
const userFilled = await page.evaluate((u) => {
|
||||||
const el = document.querySelector('input[name="usuario"]') || document.querySelector('input[type="text"]');
|
const el = document.querySelector('input[name="usuario"]') || document.querySelector('input[type="text"]');
|
||||||
if (el) { el.value = u; el.dispatchEvent(new Event('input', { bubbles: true })); return true; }
|
if (el) {
|
||||||
|
el.value = u;
|
||||||
|
el.dispatchEvent(new Event('input', { bubbles: true }));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}, user);
|
}, user);
|
||||||
|
|
||||||
|
|
@ -95,12 +107,31 @@ async function processChangeState(page, db, jobData) {
|
||||||
|
|
||||||
await page.waitForSelector('select.answer-select', { timeout: 20000 });
|
await page.waitForSelector('select.answer-select', { timeout: 20000 });
|
||||||
await page.waitForTimeout(1500);
|
await page.waitForTimeout(1500);
|
||||||
|
|
||||||
console.log('📝 Rellenando formulario...');
|
console.log('📝 Rellenando formulario...');
|
||||||
|
|
||||||
// 3. MOTIVO
|
// 3. MOTIVO (CON DIAGNÓSTICO DE ERROR)
|
||||||
const reasonSel = page.locator('select.answer-select').first();
|
const reasonSel = page.locator('select.answer-select').first();
|
||||||
await reasonSel.selectOption(String(reasonValue));
|
const targetValue = String(reasonValue);
|
||||||
|
|
||||||
|
// --- BLOQUE DE DIAGNÓSTICO ---
|
||||||
|
const availableOptions = await reasonSel.evaluate((select) => {
|
||||||
|
return Array.from(select.options).map(o => ({
|
||||||
|
value: o.value,
|
||||||
|
text: o.innerText.trim()
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`🔍 Intentando seleccionar motivo ID: "${targetValue}"`);
|
||||||
|
const optionExists = availableOptions.find(o => o.value === targetValue);
|
||||||
|
|
||||||
|
if (!optionExists) {
|
||||||
|
const validList = availableOptions.map(o => `[${o.value}: ${o.text}]`).join(', ');
|
||||||
|
console.error(`❌ ERROR: El motivo "${targetValue}" no existe.`);
|
||||||
|
throw new Error(`MOTIVO INVÁLIDO: El ID "${targetValue}" no está disponible en este estado. Opciones válidas: ${validList}`);
|
||||||
|
}
|
||||||
|
// -----------------------------
|
||||||
|
|
||||||
|
await reasonSel.selectOption(targetValue);
|
||||||
await forceUpdate(await reasonSel.elementHandle());
|
await forceUpdate(await reasonSel.elementHandle());
|
||||||
|
|
||||||
// 4. COMENTARIO
|
// 4. COMENTARIO
|
||||||
|
|
@ -122,7 +153,7 @@ async function processChangeState(page, db, jobData) {
|
||||||
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}"]]`);
|
||||||
|
|
||||||
if (timeSelectHandle) {
|
if (timeSelectHandle) {
|
||||||
await timeSelectHandle.selectOption(secondsValue);
|
await timeSelectHandle.selectOption(secondsValue);
|
||||||
await forceUpdate(timeSelectHandle);
|
await forceUpdate(timeSelectHandle);
|
||||||
|
|
@ -138,7 +169,7 @@ async function processChangeState(page, db, jobData) {
|
||||||
// --- NUEVO BLOQUE: FECHA DE CONTACTO (CONDICIONAL) ---
|
// --- NUEVO BLOQUE: FECHA DE CONTACTO (CONDICIONAL) ---
|
||||||
// Buscamos si existe el campo "Fecha en la que contactó con el cliente"
|
// 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' });
|
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()) {
|
if (await contactBlock.count() > 0 && await contactBlock.isVisible()) {
|
||||||
console.log('📞 Detectado campo obligatorio "Fecha contacto cliente". Rellenando...');
|
console.log('📞 Detectado campo obligatorio "Fecha contacto cliente". Rellenando...');
|
||||||
|
|
||||||
|
|
@ -157,6 +188,7 @@ async function processChangeState(page, db, jobData) {
|
||||||
const mVal = mRaw; // Los minutos sí suelen tener el "00"
|
const mVal = mRaw; // Los minutos sí suelen tener el "00"
|
||||||
|
|
||||||
const selects = contactBlock.locator('select');
|
const selects = contactBlock.locator('select');
|
||||||
|
|
||||||
// Asumimos que el primer select es Hora y el segundo Minutos dentro de este bloque
|
// Asumimos que el primer select es Hora y el segundo Minutos dentro de este bloque
|
||||||
if (await selects.count() >= 1) {
|
if (await selects.count() >= 1) {
|
||||||
await selects.nth(0).selectOption(hVal).catch(() => {});
|
await selects.nth(0).selectOption(hVal).catch(() => {});
|
||||||
|
|
@ -191,9 +223,8 @@ async function processChangeState(page, db, jobData) {
|
||||||
|
|
||||||
// 8. GESTIÓN DE ALERTAS (POPUP "SÍ")
|
// 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í' });
|
||||||
|
|
||||||
if (await confirmBtn.count() > 0 && await confirmBtn.isVisible()) {
|
if (await confirmBtn.count() > 0 && await confirmBtn.isVisible()) {
|
||||||
console.log('🚨 ALERTA SMS DETECTADA. Pulsando "Sí"...');
|
console.log('🚨 ALERTA SMS DETECTADA. Pulsando "Sí"...');
|
||||||
await confirmBtn.click();
|
await confirmBtn.click();
|
||||||
|
|
@ -245,9 +276,10 @@ async function claimJobById(db, jobId) {
|
||||||
async function markJobDone(db, job, result) {
|
async function markJobDone(db, job, result) {
|
||||||
const jobId = job.id;
|
const jobId = job.id;
|
||||||
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 });
|
||||||
|
|
||||||
await db.collection(CONFIG.RESULT_COLLECTION).add({
|
await db.collection(CONFIG.RESULT_COLLECTION).add({
|
||||||
jobId,
|
jobId,
|
||||||
ok: true,
|
ok: true,
|
||||||
serviceNumber: job.serviceNumber || '',
|
serviceNumber: job.serviceNumber || '',
|
||||||
reason: job.reasonValue || '',
|
reason: job.reasonValue || '',
|
||||||
comment: job.comment || '',
|
comment: job.comment || '',
|
||||||
|
|
@ -303,10 +335,12 @@ function startWorker(db) {
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
while(queue.length) { await processJob(db, await claimJobById(db, queue.shift())); }
|
while(queue.length) { await processJob(db, await claimJobById(db, queue.shift())); }
|
||||||
};
|
};
|
||||||
|
|
||||||
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 (V7 - CON FECHA CONTACTO) LISTO.');
|
|
||||||
|
console.log('🚀 Worker Multiasistencia (V7 - CON DEBUG) LISTO.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const db = initFirebase();
|
const db = initFirebase();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue