Aggiunti file javascript
This commit is contained in:
@@ -0,0 +1,645 @@
|
||||
// ==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();
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user