645 lines
27 KiB
JavaScript
645 lines
27 KiB
JavaScript
// ==UserScript==
|
|
// @name DOC_NRAP & AB_NRAP portale trasporto v4.5 WORKING.
|
|
// @namespace http://tampermonkey.net/
|
|
// @version 4.5
|
|
// @description Automazione DOC_NRAP e AB_NRAP con gestione modale di conferma
|
|
// @author Tu
|
|
// @match *://www.ilportaledeltrasporto.it/nove/gestioneistanzanove/spa/*
|
|
// @grant GM_xmlhttpRequest
|
|
// @connect localhost
|
|
// @run-at document-end
|
|
// ==/UserScript==
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
// --- VARIABILI DI STATO ---
|
|
let TELAIO = '';
|
|
let VALORE2 = '0';
|
|
let VALORE3 = '';
|
|
let TIPO_ATTUALE = '';
|
|
let taskAttivo = false;
|
|
let downloadInCorso = false;
|
|
let completatoLocalmente = false;
|
|
const ENDPOINT_GET = 'http://localhost/hook/dati2.php';
|
|
|
|
// --- HELPER FUNCTIONS ---
|
|
|
|
// Funzione per discriminare lo stato delle schede/tessere
|
|
|
|
function getTessereStatus() {
|
|
let stati = { Tess1: "Sconosciuto", Tess2: "Sconosciuto", Tess3: "Sconosciuto" };
|
|
|
|
const cardContainers = document.querySelectorAll('.CardComponent.d-flex.col');
|
|
|
|
// Se non ci sono tessere, esci silenziosamente senza fare log di errore
|
|
if (cardContainers.length === 0) {
|
|
return null; // Restituiamo null per capire che non siamo nella dashboard
|
|
}
|
|
|
|
cardContainers.forEach((container, index) => {
|
|
const article = container.querySelector('article.Card');
|
|
const h2 = container.querySelector('.cardText h2');
|
|
|
|
if (article && h2) {
|
|
const titolo = h2.innerText.trim().toLowerCase();
|
|
let statoRilevato = "Sconosciuto";
|
|
|
|
// Verifica lo stato dalle classi dell'elemento article
|
|
if (article.classList.contains('Active')) statoRilevato = "Attivo";
|
|
else if (article.classList.contains('Locked')) statoRilevato = "Bloccato";
|
|
else if (article.classList.contains('Completed')) statoRilevato = "Completato";
|
|
|
|
// Mappatura precisa basata sul testo dell'H2
|
|
if (titolo.includes("verifica documentazione")) {
|
|
stati.Tess1 = statoRilevato;
|
|
} else if (titolo.includes("visita e prova")) {
|
|
stati.Tess2 = statoRilevato;
|
|
} else if (titolo.includes("abilitazione telaio")) {
|
|
stati.Tess3 = statoRilevato;
|
|
}
|
|
|
|
// console.log(`[TM] Rilevata Tessera: "${h2.innerText.trim()}" | Stato: ${statoRilevato}`);
|
|
}
|
|
});
|
|
|
|
return stati;
|
|
}
|
|
|
|
function getTessereStatus_old() {
|
|
let stati = {
|
|
Tess1: "Sconosciuto",
|
|
Tess2: "Sconosciuto",
|
|
Tess3: "Sconosciuto"
|
|
};
|
|
|
|
// Seleziona i contenitori basandosi sulla classe che hai indicato
|
|
const cardContainers = document.querySelectorAll('.CardComponent.d-flex.col');
|
|
|
|
if (cardContainers.length === 0) {
|
|
console.warn("[TM] Nessun contenitore CardComponent trovato.");
|
|
return stati;
|
|
}
|
|
|
|
cardContainers.forEach((container, index) => {
|
|
const article = container.querySelector('article.Card');
|
|
const h2 = container.querySelector('.cardText h2');
|
|
|
|
if (article && h2) {
|
|
const titolo = h2.innerText.trim().toLowerCase();
|
|
let statoRilevato = "Sconosciuto";
|
|
|
|
// Verifica lo stato dalle classi dell'elemento article
|
|
if (article.classList.contains('Active')) statoRilevato = "Attivo";
|
|
else if (article.classList.contains('Locked')) statoRilevato = "Bloccato";
|
|
else if (article.classList.contains('Completed')) statoRilevato = "Completato";
|
|
|
|
// Mappatura precisa basata sul testo dell'H2
|
|
if (titolo.includes("verifica documentazione")) {
|
|
stati.Tess1 = statoRilevato;
|
|
} else if (titolo.includes("visita e prova")) {
|
|
stati.Tess2 = statoRilevato;
|
|
} else if (titolo.includes("abilitazione telaio")) {
|
|
stati.Tess3 = statoRilevato;
|
|
}
|
|
|
|
// console.log(`[TM] Rilevata Tessera: "${h2.innerText.trim()}" | Stato: ${statoRilevato}`);
|
|
}
|
|
});
|
|
|
|
return stati;
|
|
}
|
|
|
|
// Pulizia stringhe: rimuove ogni spazio (inizio, fine, centro) e porta in maiuscolo
|
|
function cleanString(str) {
|
|
if (!str) return "";
|
|
return str.toString().replace(/\s+/g, '').toUpperCase();
|
|
}
|
|
|
|
// Click sicuro per elementi React
|
|
function clickReactSafe(element) {
|
|
if (!element || typeof element.dispatchEvent !== 'function') return;
|
|
const opts = { bubbles: true, cancelable: true, view: window.unsafeWindow || window };
|
|
try {
|
|
element.dispatchEvent(new MouseEvent('mousedown', opts));
|
|
element.dispatchEvent(new MouseEvent('mouseup', opts));
|
|
element.click();
|
|
} catch (e) {
|
|
element.dispatchEvent(new Event('mousedown', { bubbles: true }));
|
|
element.dispatchEvent(new Event('mouseup', { bubbles: true }));
|
|
element.click();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Premere il pulsante "Procedi" della tessera ennesima (1-based).
|
|
* @param {number} n - Indice della tessera (1 per la prima, 2 per la seconda, ecc.)
|
|
*/
|
|
function Procedi(n) {
|
|
console.log(`[TM] Test Procedi(${n}) avviato...`);
|
|
|
|
// CORREZIONE: Le classi devono essere unite dai punti senza spazi
|
|
// perché appartengono allo stesso elemento div
|
|
const cardContainers = document.querySelectorAll('.CardComponent.d-flex.col');
|
|
|
|
if (cardContainers.length === 0) {
|
|
console.error("[TM] ERRORE: Nessun contenitore trovato. Verificare il selettore .CardComponent.d-flex.col");
|
|
return;
|
|
}
|
|
|
|
console.log(`[TM] Tessere trovate in pagina: ${cardContainers.length}`);
|
|
|
|
// Controllo indice
|
|
if (n < 1 || n > cardContainers.length) {
|
|
console.error(`[TM] ERRORE: Indice ${n} non valido. Tessere disponibili: ${cardContainers.length}`);
|
|
return;
|
|
}
|
|
|
|
// Selezioniamo la tessera corretta (n-1)
|
|
const targetCard = cardContainers[n - 1];
|
|
console.log(`[TM] Opero sulla tessera #${n}:`, targetCard.querySelector('h2')?.innerText);
|
|
|
|
// Cerchiamo il pulsante Procedi
|
|
// Nota: nell'HTML inviato la classe del footer è "cardFooter" (minuscolo/maiuscolo come nel DOM)
|
|
const btnProcedi = Array.from(targetCard.querySelectorAll('button'))
|
|
.find(b => b.textContent.trim().toUpperCase() === 'PROCEDI');
|
|
|
|
if (!btnProcedi) {
|
|
console.error(`[TM] Pulsante 'Procedi' non trovato nella tessera #${n}.`);
|
|
return;
|
|
}
|
|
|
|
if (btnProcedi.disabled) {
|
|
console.warn(`[TM] Il pulsante della tessera #${n} è DISABILITATO.`);
|
|
return;
|
|
}
|
|
|
|
console.log(`[TM] Click sulla tessera #${n}...`);
|
|
clickReactSafe(btnProcedi);
|
|
};
|
|
|
|
// Input sicuro per elementi React
|
|
|
|
function setInputReactSafe(element, value) {
|
|
if (!element) return;
|
|
|
|
// Determina se è un input o una textarea per usare il prototipo corretto
|
|
const prototype = element.tagName === 'TEXTAREA'
|
|
? HTMLTextAreaElement.prototype
|
|
: HTMLInputElement.prototype;
|
|
|
|
const setter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
|
|
|
|
element.focus();
|
|
setter.call(element, value);
|
|
|
|
// Trigger degli eventi per far capire a React che il testo è cambiato
|
|
element.dispatchEvent(new Event('input', { bubbles: true }));
|
|
element.dispatchEvent(new Event('change', { bubbles: true }));
|
|
element.dispatchEvent(new Event('blur', { bubbles: true }));
|
|
}
|
|
|
|
function setInputReactSafe_old(input, value) {
|
|
if (!input) return;
|
|
const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set;
|
|
input.focus();
|
|
setter.call(input, value);
|
|
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
}
|
|
|
|
// Gestione della modale di conferma per AB_NRAP
|
|
function gestisciModaleConferma() {
|
|
const modale = document.querySelector('.ModalsPortal__container.mx-auto');
|
|
if (modale) {
|
|
const btnConfermaModale = Array.from(modale.querySelectorAll('button'))
|
|
.find(b => {
|
|
const spans = b.querySelectorAll('span');
|
|
return Array.from(spans).some(s => s.textContent.trim() === "Conferma");
|
|
});
|
|
|
|
if (btnConfermaModale) {
|
|
console.log("[TM] Pulsante 'Conferma' trovato nella modale. Clicco...");
|
|
clickReactSafe(btnConfermaModale);
|
|
// Attendiamo che la modale si chiuda e il sistema elabori prima di segnare fine task
|
|
setTimeout(segnaComeCompletato, 3000);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// --- LOGICA SERVER ---
|
|
function avviaDownloadDocumenti() {
|
|
if (downloadInCorso) return;
|
|
|
|
const tuttiIBottoni = Array.from(document.querySelectorAll('button.DocumentsSection__file-btn'));
|
|
if (tuttiIBottoni.length === 0) return;
|
|
|
|
downloadInCorso = true;
|
|
const titoliGiaVisti = new Set();
|
|
let delayDoc = 0;
|
|
|
|
tuttiIBottoni.forEach((btn, index, array) => {
|
|
const riga = btn.closest('tr');
|
|
const titolo = riga ? riga.innerText.trim().split('\t')[0] : btn.innerText.trim();
|
|
|
|
if (!titoliGiaVisti.has(titolo)) {
|
|
titoliGiaVisti.add(titolo);
|
|
|
|
setTimeout(() => {
|
|
console.log(`[TM] 1. Avvio Download: ${titolo}`);
|
|
clickReactSafe(btn);
|
|
|
|
// --- SEQUENZA MODALE ---
|
|
|
|
// STEP A: Click Esporta File (dopo 1.2 secondi)
|
|
setTimeout(() => {
|
|
const btnEsporta = Array.from(document.querySelectorAll('button.btn-primary.btn-xs'));
|
|
|
|
if (btnEsporta) {
|
|
console.log(`[TM] 2. Click Esporta File per: ${titolo}`);
|
|
clickReactSafe(btnEsporta);
|
|
}
|
|
|
|
// STEP B: Click Chiudi Modale (dopo altri 1.5 secondi dal click esporta)
|
|
setTimeout(() => {
|
|
const btnChiudiModale = document.querySelector('button.ModalContent__header--btn');
|
|
if (btnChiudiModale) {
|
|
console.log(`[TM] 3. Chiusura modale per: ${titolo}`);
|
|
clickReactSafe(btnChiudiModale);
|
|
}
|
|
}, 1500);
|
|
|
|
}, 1200);
|
|
// -----------------------
|
|
|
|
if (index === array.length - 1) {
|
|
setTimeout(segnaComeCompletato, 5000);
|
|
}
|
|
}, delayDoc);
|
|
|
|
delayDoc += 3000;
|
|
}
|
|
});
|
|
}
|
|
|
|
function fetchDati() {
|
|
GM_xmlhttpRequest({
|
|
method: "GET",
|
|
url: ENDPOINT_GET,
|
|
onload: function(response) {
|
|
try {
|
|
const data = JSON.parse(response.responseText);
|
|
const targetHome = 'https://www.ilportaledeltrasporto.it/nove/gestioneistanzanove/spa/le-mie-istanze';
|
|
|
|
// Cerca questo blocco dentro fetchDati() e sostituiscilo:
|
|
|
|
if (data.tipo === 'RESET_NRAP') {
|
|
console.log("[TM] Ricevuto comando RESET. Fermo i task e avviso il server...");
|
|
|
|
// 1. Impostiamo lo stato su RESET così segnaComeCompletato() sa cosa inviare
|
|
TIPO_ATTUALE = 'RESET_NRAP';
|
|
TELAIO = '';
|
|
VALORE2 = '0';
|
|
VALORE3 = '';
|
|
|
|
// 2. Chiamiamo la funzione che già possiedi per notificare il server
|
|
segnaComeCompletato();
|
|
|
|
// 3. Opzionale: Torna in home solo se non ci sei già
|
|
if (window.location.href !== targetHome) {
|
|
window.location.href = targetHome;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if ((data.tipo === 'DOC_NRAP' || data.tipo === 'AB_NRAP') && data.task === 'fare') {
|
|
|
|
if (TELAIO !== '' && TELAIO !== data.valore1) {
|
|
TELAIO = data.valore1;
|
|
window.location.href = targetHome;
|
|
return;
|
|
}
|
|
|
|
if (TELAIO !== data.valore1 || TIPO_ATTUALE !== data.tipo) {
|
|
TELAIO = data.valore1;
|
|
VALORE2 = data.valore2;
|
|
VALORE3 = data.valore3;
|
|
TIPO_ATTUALE = data.tipo;
|
|
completatoLocalmente = false;
|
|
console.log(`[TM] Ricevuto task ${TIPO_ATTUALE} per: ${TELAIO}`);
|
|
}
|
|
|
|
if (!completatoLocalmente) {
|
|
taskAttivo = true;
|
|
eseguiAutomazione();
|
|
}
|
|
// Dentro l'else di fetchDati (quando data.task NON è 'fare')
|
|
} else {
|
|
if (taskAttivo) {
|
|
console.log("[TM] Nessun task attivo dal server, rilascio il controllo manuale.");
|
|
}
|
|
taskAttivo = false;
|
|
completatoLocalmente = false; // Rimuovi o commenta questa riga se vuoi evitare loop continui
|
|
}
|
|
} catch (e) {
|
|
console.error("[TM] Errore parsing dati", e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function segnaComeCompletato() {
|
|
if (completatoLocalmente) return;
|
|
completatoLocalmente = true;
|
|
taskAttivo = false;
|
|
|
|
const payload = {
|
|
tipo: TIPO_ATTUALE,
|
|
task: "COMPLETATO",
|
|
valore1: TELAIO,
|
|
valore2: VALORE2,
|
|
valore3: VALORE3
|
|
};
|
|
|
|
GM_xmlhttpRequest({
|
|
method: "POST",
|
|
url: ENDPOINT_GET,
|
|
data: JSON.stringify(payload),
|
|
headers: { "Content-Type": "application/json" },
|
|
onload: function() {
|
|
console.log(`[TM] Task ${TIPO_ATTUALE} completato sul server.`);
|
|
downloadInCorso = false;
|
|
}
|
|
});
|
|
}
|
|
|
|
// --- AUTOMAZIONE PAGINE ---
|
|
|
|
function eseguiAutomazione() {
|
|
// Se il task non è attivo o abbiamo già finito su questa pagina, esci subito
|
|
if (!taskAttivo || completatoLocalmente) return;
|
|
|
|
const url = window.location.href;
|
|
|
|
// --- 1. Pagina di Ricerca ---
|
|
if (url.includes('le-mie-istanze')) {
|
|
const input = document.getElementById('numeroTelaio');
|
|
const btnCerca = Array.from(document.querySelectorAll('button')).find(b => b.textContent.includes('Cerca'));
|
|
const btnTabella = document.querySelector('button.action-button-table');
|
|
|
|
if (input && TELAIO !== '' && cleanString(input.value) !== cleanString(TELAIO)) {
|
|
setInputReactSafe(input, TELAIO);
|
|
setTimeout(() => { if(btnCerca) clickReactSafe(btnCerca); }, 800);
|
|
}
|
|
if (btnTabella) setTimeout(() => clickReactSafe(btnTabella), 1500);
|
|
return; // Fine logica ricerca
|
|
}
|
|
|
|
// --- 2. Gestione Dashboard vs Dettaglio ---
|
|
// Recuperiamo lo stato delle tessere. getTessereStatus() ora deve restituire null
|
|
// se non trova i contenitori (come spiegato prima), evitando log di errore.
|
|
const situazione = getTessereStatus();
|
|
|
|
// CASO A: Siamo nella Dashboard (Tessere visibili)
|
|
if (situazione !== null && !url.includes('dettaglio-istanza') && !url.includes('abilitazione-telaio')) {
|
|
const btnProcedi = Array.from(document.querySelectorAll('button')).find(b => b.textContent.trim() === 'Procedi');
|
|
|
|
if (btnProcedi && !btnProcedi.disabled) {
|
|
if (TIPO_ATTUALE === 'DOC_NRAP' && situazione.Tess1 === "Attivo") {
|
|
console.log("[TM] Dashboard: Apro Tessera 1 (Documentazione)");
|
|
setTimeout(() => { Procedi(1); }, 1000);
|
|
} else if (TIPO_ATTUALE === 'AB_NRAP' && situazione.Tess3 === "Attivo") {
|
|
console.log("[TM] Dashboard: Apro Tessera 3 (Abilitazione)");
|
|
setTimeout(() => { Procedi(3); }, 1000);
|
|
}
|
|
}
|
|
return; // Esci: abbiamo gestito la dashboard
|
|
}
|
|
|
|
// CASO B: Siamo nella Pagina di Dettaglio/Compilazione (Abilitazione o Download)
|
|
if (url.includes('dettaglio-istanza') || url.includes('abilitazione-telaio')) {
|
|
|
|
// Sotto-caso: Compilazione Dati (AB_NRAP)
|
|
if (TIPO_ATTUALE === 'AB_NRAP') {
|
|
const inputCodImmat = document.getElementById('Codice immatricolazione');
|
|
const inputNota = document.getElementById('Nota*') || document.getElementById('Nota');
|
|
|
|
if (inputCodImmat && inputNota) {
|
|
console.log("[TM] Pagina compilazione rilevata. Inserisco dati...");
|
|
|
|
// Inserimento dati con logica React
|
|
setInputReactSafe(inputCodImmat, VALORE2);
|
|
setInputReactSafe(inputNota, VALORE3);
|
|
|
|
// Forza il focus out per "fissare" il valore in React
|
|
inputCodImmat.dispatchEvent(new Event('blur', { bubbles: true }));
|
|
inputNota.dispatchEvent(new Event('blur', { bubbles: true }));
|
|
|
|
console.log("[TM] Compilazione eseguita. Ora l'Observer si ferma.");
|
|
|
|
// BLOCCA L'OBSERVER: impostando a true, questa intera funzione
|
|
// si fermerà al primo IF nei cicli successivi.
|
|
completatoLocalmente = true;
|
|
}
|
|
}
|
|
|
|
// Sotto-caso: Download Documenti (DOC_NRAP)
|
|
else if (TIPO_ATTUALE === 'DOC_NRAP') {
|
|
if (downloadInCorso) return;
|
|
|
|
if (parseInt(VALORE2) > 0) {
|
|
console.log("[TM] Pagina documenti rilevata. Avvio download...");
|
|
avviaDownloadDocumenti();
|
|
} else {
|
|
console.log("[TM] Nessun documento richiesto (Valore2=0). Chiudo.");
|
|
segnaComeCompletato();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function eseguiAutomazione_old() {
|
|
if (!taskAttivo || completatoLocalmente) return;
|
|
|
|
const url = window.location.href;
|
|
|
|
// 1. Pagina di Ricerca
|
|
if (url.includes('le-mie-istanze')) {
|
|
const input = document.getElementById('numeroTelaio');
|
|
const btnCerca = Array.from(document.querySelectorAll('button')).find(b => b.textContent.includes('Cerca'));
|
|
const btnTabella = document.querySelector('button.action-button-table');
|
|
|
|
if (input && TELAIO !== '' && cleanString(input.value) !== cleanString(TELAIO)) {
|
|
setInputReactSafe(input, TELAIO);
|
|
setTimeout(() => { if(btnCerca) clickReactSafe(btnCerca); }, 800);
|
|
}
|
|
if (btnTabella) setTimeout(() => clickReactSafe(btnTabella), 1500);
|
|
//if (btnTabella) console.log("Pulsante Tabella trovato! esegui il comando a mano");
|
|
}
|
|
|
|
// --- 2. Pagina Dashboard (Tessere) ---
|
|
if (url.includes('/abilitazione/') && !url.includes('dettaglio-istanza')) {
|
|
const situazione = getTessereStatus();
|
|
const btnProcedi = Array.from(document.querySelectorAll('button')).find(b => b.textContent.trim() === 'Procedi');
|
|
|
|
if (btnProcedi && !btnProcedi.disabled) {
|
|
if (TIPO_ATTUALE === 'DOC_NRAP' && situazione.Tess1 === "Attivo") {
|
|
setTimeout(() => { Procedi(1); }, 1000);
|
|
} else if (TIPO_ATTUALE === 'AB_NRAP' && situazione.Tess3 === "Attivo") {
|
|
setTimeout(() => { Procedi(3); }, 1000);
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- 3. Pagina di Abilitazione (Dettaglio) ---
|
|
if (url.includes('/abilitazione/') && url.includes('/abilitazione-telaio')) {
|
|
|
|
if (TIPO_ATTUALE === 'AB_NRAP') {
|
|
const inputCodImmat = document.getElementById('Codice immatricolazione');
|
|
// Cerca la nota sia con che senza asterisco
|
|
const inputNota = document.getElementById('Nota*') || document.getElementById('Nota');
|
|
console.log("[TM] Pagina di abilitazione rilevata. Compilo...");
|
|
if (inputCodImmat && inputNota) {
|
|
console.log("[TM] Pagina di abilitazione rilevata. Compilo...");
|
|
|
|
//setInputReactSafe(inputCodImmat, VALORE2);
|
|
//setInputReactSafe(inputNota, VALORE3);
|
|
|
|
console.log("[TM] Dati inseriti. Ora mi fermo e ti lascio il controllo.");
|
|
|
|
// IMPORTANTE: Segniamo come completato localmente solo la "scrittura"
|
|
// così l'Observer smette di chiamare eseguiAutomazione() per questa pagina.
|
|
completatoLocalmente = true;
|
|
}
|
|
}
|
|
|
|
if (TIPO_ATTUALE === 'DOC_NRAP') {
|
|
if (downloadInCorso) return;
|
|
if (parseInt(VALORE2) > 0) {
|
|
avviaDownloadDocumenti();
|
|
} else {
|
|
segnaComeCompletato();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function eseguiAutomazione2() {
|
|
if (!taskAttivo || completatoLocalmente) return;
|
|
const situazione = getTessereStatus();
|
|
|
|
// GUARDIA: Se tutte le tessere sono "Bloccato" o "Sconosciuto",
|
|
// probabilmente React sta ancora caricando. Fermati e aspetta il prossimo ciclo.
|
|
if (situazione.Tess1 === "Bloccato" && situazione.Tess2 === "Bloccato") {
|
|
return;
|
|
}
|
|
|
|
const url = window.location.href;
|
|
|
|
// 1. Pagina di Ricerca
|
|
if (url.includes('le-mie-istanze')) {
|
|
const input = document.getElementById('numeroTelaio');
|
|
const btnCerca = Array.from(document.querySelectorAll('button')).find(b => b.textContent.includes('Cerca'));
|
|
const btnTabella = document.querySelector('button.action-button-table');
|
|
|
|
if (input && TELAIO !== '' && cleanString(input.value) !== cleanString(TELAIO)) {
|
|
setInputReactSafe(input, TELAIO);
|
|
setTimeout(() => { if(btnCerca) clickReactSafe(btnCerca); }, 800);
|
|
}
|
|
if (btnTabella) setTimeout(() => clickReactSafe(btnTabella), 1500);
|
|
//if (btnTabella) console.log("Pulsante Tabella trovato! esegui il comando a mano");
|
|
}
|
|
|
|
// 2. Pagina Intermedia (Abilitazione / Dashboard)
|
|
if (url.includes('/abilitazione/') && !url.includes('dettaglio-istanza')) {
|
|
|
|
const btnProcedi = Array.from(document.querySelectorAll('button')).find(b => b.textContent.trim() === 'Procedi');
|
|
|
|
if (btnProcedi && !btnProcedi.disabled) {
|
|
|
|
// --- LOGICA SELETTIVA ---
|
|
|
|
if (TIPO_ATTUALE === 'DOC_NRAP') {
|
|
console.log("Stato tessere al click:", situazione);
|
|
if (situazione.Tess1 === "Attivo" && situazione.Tess3 === "Bloccato") {
|
|
console.log("[TM] DOC_NRAP: Tessera 1 pronta. Procedo apertura documenti...");
|
|
setTimeout(() => { Procedi(1); }, 1000);
|
|
} else if (situazione.Tess1 === "Completato"){
|
|
console.warn("[TM] DOC_NRAP: Vista documentazione");
|
|
} else if (situazione.Tess1 === "Bloccato"){
|
|
console.warn("[TM] DOC_NRAP: Documentazione bloccata, attendere");
|
|
}
|
|
}
|
|
|
|
else if (TIPO_ATTUALE === 'AB_NRAP') {
|
|
// Logica specifica per AB_NRAP (es. solo se Tess3 è Attiva)
|
|
if (situazione.Tess3 === "Attivo") {
|
|
console.log("[TM] DOC_NRAP: Tessera 3 Ok si procede a validazione...");
|
|
setTimeout(() => { Procedi(3); }, 1000);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// 3. Pagina Dettaglio Istanza
|
|
if (url.includes('dettaglio-istanza')) {
|
|
const situazioneInDettaglio = getTessereStatus();
|
|
|
|
// CASO A: Operazione AB_NRAP (Solo inserimento dati, NO clic automatico)
|
|
if (TIPO_ATTUALE === 'AB_NRAP') {
|
|
const inputCodImmat = document.getElementById('Codice immatricolazione');
|
|
const inputNota = document.getElementById('Nota*');
|
|
|
|
let datiInseriti = false;
|
|
|
|
// 1. Inserimento Codice Immatricolazione (Valore2)
|
|
if (inputCodImmat.value !== VALORE2) {
|
|
console.log("[TM] Inserisco Codice Immatricolazione:", VALORE2);
|
|
setInputReactSafe(inputCodImmat, VALORE2);
|
|
datiInseriti = true;
|
|
}
|
|
|
|
// 2. Inserimento Nota (Valore3)
|
|
if (inputNota.value !== VALORE3) {
|
|
console.log("[TM] Inserisco Nota:", VALORE3);
|
|
setInputReactSafe(inputNota, VALORE3);
|
|
datiInseriti = true;
|
|
}
|
|
|
|
// 3. Feedback visivo e stop
|
|
if (datiInseriti) {
|
|
console.log("[TM] Campi compilati. Attendo interazione manuale per il tasto Conferma.");
|
|
// Non facciamo nulla: il ciclo MutationObserver continuerà a girare
|
|
// ma non troverà discrepanze nei valori e non farà clic.
|
|
}
|
|
}
|
|
|
|
// CASO B: Operazione DOC_NRAP (Download)
|
|
else if (TIPO_ATTUALE === 'DOC_NRAP') {
|
|
if (downloadInCorso) return; // Se sto già scaricando, NON rientrare nella funzione
|
|
if (parseInt(VALORE2) > 0) {
|
|
avviaDownloadDocumenti();
|
|
//console.log("Avvio download documenti. Stato attuale tessere:", situazione);
|
|
} else {
|
|
console.log("[TM] Valore2 <= 1, chiusura task senza download.");
|
|
segnaComeCompletato();
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// --- INITIALIZATION ---
|
|
|
|
const observer = new MutationObserver(() => {
|
|
if (taskAttivo) eseguiAutomazione();
|
|
});
|
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
|
|
setInterval(fetchDati, 2500);
|
|
fetchDati();
|
|
|
|
})(); |