Actualizar worker-multiasistencia.js
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
// worker-multiasistencia.js (Versión PostgreSQL SaaS)
|
// worker-multiasistencia.js (Versión PostgreSQL SaaS + Escáner de Campos Dinámicos)
|
||||||
import { chromium } from 'playwright';
|
import { chromium } from 'playwright';
|
||||||
import pg from 'pg';
|
import pg from 'pg';
|
||||||
|
|
||||||
@@ -114,7 +114,6 @@ async function loginMulti(page, creds) {
|
|||||||
await page.click('input[type="submit"]');
|
await page.click('input[type="submit"]');
|
||||||
await page.waitForTimeout(4000);
|
await page.waitForTimeout(4000);
|
||||||
|
|
||||||
// Verificación básica de login (Si sigue estando el input de password, falló)
|
|
||||||
const isStillLogin = await page.locator('input[type="password"]').count();
|
const isStillLogin = await page.locator('input[type="password"]').count();
|
||||||
if (isStillLogin > 0) throw new Error("Credenciales rechazadas por Multiasistencia.");
|
if (isStillLogin > 0) throw new Error("Credenciales rechazadas por Multiasistencia.");
|
||||||
}
|
}
|
||||||
@@ -122,7 +121,7 @@ async function loginMulti(page, creds) {
|
|||||||
// --- PROCESO PRINCIPAL ---
|
// --- PROCESO PRINCIPAL ---
|
||||||
async function processChangeState(page, creds, jobData) {
|
async function processChangeState(page, creds, jobData) {
|
||||||
const serviceNumber = jobData.service_number;
|
const serviceNumber = jobData.service_number;
|
||||||
const reasonValue = jobData.new_status; // Asumimos que la API ya le pasa el ID numérico web
|
const reasonValue = jobData.new_status;
|
||||||
const comment = jobData.observation;
|
const comment = jobData.observation;
|
||||||
const dateStr = normalizeDate(jobData.appointment_date);
|
const dateStr = normalizeDate(jobData.appointment_date);
|
||||||
|
|
||||||
@@ -142,7 +141,7 @@ async function processChangeState(page, creds, jobData) {
|
|||||||
await page.waitForSelector('select.answer-select', { timeout: 20000 });
|
await page.waitForSelector('select.answer-select', { timeout: 20000 });
|
||||||
await page.waitForTimeout(1000);
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
// SELECCIONAR MOTIVO
|
// 1. SELECCIONAR MOTIVO
|
||||||
console.log(` [3] Seleccionando estado ${reasonValue}...`);
|
console.log(` [3] Seleccionando estado ${reasonValue}...`);
|
||||||
const reasonSel = page.locator('select.answer-select').first();
|
const reasonSel = page.locator('select.answer-select').first();
|
||||||
const options = await reasonSel.evaluate(s => Array.from(s.options).map(o => o.value));
|
const options = await reasonSel.evaluate(s => Array.from(s.options).map(o => o.value));
|
||||||
@@ -154,14 +153,14 @@ async function processChangeState(page, creds, jobData) {
|
|||||||
await reasonSel.selectOption(String(reasonValue));
|
await reasonSel.selectOption(String(reasonValue));
|
||||||
await forceUpdate(await reasonSel.elementHandle());
|
await forceUpdate(await reasonSel.elementHandle());
|
||||||
|
|
||||||
// COMENTARIO
|
// 2. COMENTARIO
|
||||||
if (comment) {
|
if (comment) {
|
||||||
const commentBox = page.locator('textarea[formcontrolname="comment"]');
|
const commentBox = page.locator('textarea[formcontrolname="comment"]');
|
||||||
await commentBox.fill(comment);
|
await commentBox.fill(comment);
|
||||||
await forceUpdate(await commentBox.elementHandle());
|
await forceUpdate(await commentBox.elementHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
// FECHA SIGUIENTE ACCIÓN (Solo si existe fecha y es válida)
|
// 3. FECHA SIGUIENTE ACCIÓN (TXTFACCION) - La de la cita real
|
||||||
if (dateStr) {
|
if (dateStr) {
|
||||||
const actionBlock = page.locator('encastrables-date-hour-field[label="TXTFACCION"]');
|
const actionBlock = page.locator('encastrables-date-hour-field[label="TXTFACCION"]');
|
||||||
if (await actionBlock.count() > 0) {
|
if (await actionBlock.count() > 0) {
|
||||||
@@ -173,52 +172,62 @@ async function processChangeState(page, creds, jobData) {
|
|||||||
if (timeStr) {
|
if (timeStr) {
|
||||||
const seconds = timeToMultiValue(timeStr);
|
const seconds = timeToMultiValue(timeStr);
|
||||||
const timeSel = actionBlock.locator('select.answer-select');
|
const timeSel = actionBlock.locator('select.answer-select');
|
||||||
await timeSel.selectOption(seconds).catch(()=>{ console.log(' ⚠️ No se pudo poner la hora exacta') });
|
await timeSel.selectOption(seconds).catch(()=>{});
|
||||||
await forceUpdate(await timeSel.elementHandle());
|
await forceUpdate(await timeSel.elementHandle());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback
|
// Fallback genérico por si cambia la etiqueta
|
||||||
const genDate = page.locator('input[type="date"]').first();
|
const genDate = page.locator('input[type="date"]').first();
|
||||||
await genDate.fill(dateStr);
|
if (await genDate.count() > 0) {
|
||||||
await forceUpdate(await genDate.elementHandle());
|
await genDate.fill(dateStr);
|
||||||
|
await forceUpdate(await genDate.elementHandle());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FECHA CONTACTO (AUTOMÁTICA - HOY)
|
// 4. AUTO-RELLENADOR INTELIGENTE (Detecta campos obligatorios dinámicos)
|
||||||
const contactBlock = page.locator('encastrables-date-hour-field[label="TXTFCONTACTO"]');
|
const extraDynamicFields = ['TXTFCONTACTO', 'TXTFPRIMERAV'];
|
||||||
if (await contactBlock.count() > 0 && await contactBlock.isVisible()) {
|
|
||||||
console.log(' [INFO] Rellenando fecha de contacto (Auto Hoy)...');
|
|
||||||
const now = getCurrentDateTime();
|
|
||||||
|
|
||||||
const cDate = contactBlock.locator('input[type="date"]');
|
for (const label of extraDynamicFields) {
|
||||||
await cDate.fill(now.dateStr);
|
const block = page.locator(`encastrables-date-hour-field[label="${label}"]`);
|
||||||
await forceUpdate(await cDate.elementHandle());
|
if (await block.count() > 0 && await block.isVisible()) {
|
||||||
|
console.log(` [INFO] Detectado campo obligatorio "${label}". Auto-rellenando...`);
|
||||||
|
const now = getCurrentDateTime();
|
||||||
|
|
||||||
const selects = contactBlock.locator('select.answer-select-time');
|
// Rellenar Fecha
|
||||||
if (await selects.count() >= 2) {
|
const cDate = block.locator('input[type="date"]');
|
||||||
await selects.nth(0).selectOption(now.hourStr).catch(()=>{});
|
await cDate.fill(now.dateStr);
|
||||||
await forceUpdate(await selects.nth(0).elementHandle());
|
await forceUpdate(await cDate.elementHandle());
|
||||||
await selects.nth(1).selectOption(now.minStr).catch(()=>{});
|
|
||||||
await forceUpdate(await selects.nth(1).elementHandle());
|
// Rellenar Hora y Minutos (Multiasistencia usa 2 selects separados para esto)
|
||||||
|
const selects = block.locator('select.answer-select-time');
|
||||||
|
if (await selects.count() >= 2) {
|
||||||
|
await selects.nth(0).selectOption(now.hourStr).catch(()=>{});
|
||||||
|
await forceUpdate(await selects.nth(0).elementHandle());
|
||||||
|
|
||||||
|
await selects.nth(1).selectOption(now.minStr).catch(()=>{});
|
||||||
|
await forceUpdate(await selects.nth(1).elementHandle());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
// GUARDAR (CON INTELIGENCIA ANTI-BLOQUEO)
|
// 5. GUARDAR (CON INTELIGENCIA ANTI-BLOQUEO)
|
||||||
const btn = page.locator('button.form-container-button-submit');
|
const btn = page.locator('button.form-container-button-submit');
|
||||||
if (await btn.isDisabled()) {
|
if (await btn.isDisabled()) {
|
||||||
console.log(' [INFO] Botón bloqueado. Forzando actualización de inputs...');
|
console.log(' [INFO] Botón bloqueado. Forzando actualización de inputs...');
|
||||||
await page.locator('textarea[formcontrolname="comment"]').click();
|
await page.locator('textarea[formcontrolname="comment"]').click();
|
||||||
await page.keyboard.press('Tab');
|
await page.keyboard.press('Tab');
|
||||||
await page.waitForTimeout(1000);
|
await page.waitForTimeout(1000);
|
||||||
if (await btn.isDisabled()) throw new Error(`El formulario está bloqueado (falta algún dato obligatorio).`);
|
|
||||||
|
if (await btn.isDisabled()) throw new Error(`El formulario está bloqueado. Multiasistencia pide más datos de los previstos.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(' [4] Guardando cambios en Multiasistencia...');
|
console.log(' [4] Guardando cambios en Multiasistencia...');
|
||||||
await btn.click();
|
await btn.click();
|
||||||
|
|
||||||
// GESTIÓN DE ALERTAS (Popups de confirmación)
|
// GESTIÓN DE ALERTAS (Popups de confirmación que a veces lanza la web)
|
||||||
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()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user