Guida Funzionalità TIMS
Manuale operativo completo del TiLog Information Management System — come usare ogni funzione, cosa fa ogni sezione, come risolvere i problemi.
Panoramica
TIMS (TiLog Information Management System) è un'applicazione web per la gestione di magazzino, ordini e anagrafiche. Funziona come un pannello di visualizzazione e gestione dati connesso al database SQL Server EMS_Premi.
Visualizzare — Tutti i dati di magazzino (movimenti, giacenza, locazioni), anagrafiche (articoli, clienti/fornitori), ordini in ingresso e in uscita, configurazioni di sistema.
Filtrare — Ogni colonna è filtrabile. Filtri testuali, numerici e booleani. Ricerca globale su tutti i campi.
Modificare — I campi contrassegnati come "editabili" nella configurazione possono essere aggiornati direttamente dall'interfaccia (solo utenti livello 50+).
Esportare — Ogni griglia è esportabile in Excel (XLSX), PDF, o condivisibile via WhatsApp. L'export riguarda sempre i dati filtrati/visibili, non l'intero dataset.
Gestire ordini — Le viste ordini in ingresso e in uscita usano il layout master-detail: testata espandibile con righe di dettaglio. Azioni massive come "Chiudi Ordini" disponibili tramite bottoni custom.
Architettura file
Struttura del progetto e ruolo di ogni componente.
| File / Cartella | Ruolo |
|---|---|
| login.php | Pagina di login (3 campi: username, password, codSoc) |
| index.php | Interfaccia principale (SPA-like): header, sidebar, griglia, modali |
| config/database.json | Cuore della configurazione: connessione DB, definizione query, campi, regole |
| config/config.php | Configurazione PHP (caricamento database.json, funzione log) |
| includes/Auth.php | Classe autenticazione: login, sessione, controllo livelli, permessi scrittura, caricamento preferenze griglia |
| includes/Database.php | Classe connessione PDO al SQL Server (singleton). Carica credenziali da C:\inetpub\config_secure\ o da config/db_connection.json |
| includes/Query.php | Classe per trovare query nella config, eseguire con filtro codSoc, rimuovere colonne NULL |
| includes/Features.php | Feature flags per codSoc: abilita/disabilita funzionalità specifiche per società. Legge C:\inetpub\config_secure\features_config.php |
| includes/Encoding.php | Conversione encoding Windows-1252 → UTF-8 per risolvere problemi di caratteri speciali con SQL Server collation Latin1_General_CI_AS |
| api/auth.php | API login/logout (POST JSON) |
| api/data.php | API CRUD principale: list, get, update (con filtri, paginazione, ordinamento SQL) |
| api/menu.php | API che restituisce i gruppi e query visibili per il menu sidebar |
| api/ordini.php | API per caricare i dettagli (righe) di ordini master-detail |
| api/custom_action.php | API per eseguire le azioni dei bottoni custom (SQL o API call) |
| assets/js/app.js | Logica principale frontend: caricamento menu, rendering griglia, filtri, paginazione, editing, heartbeat sessione |
| assets/js/grid-preferences.js | Personalizzazione colonne: modal drag-drop per riordinare/nascondere colonne. Salva preferenze in DB (TimsUserGridPreferences) |
| assets/js/master-detail.js | Logica espansione/compressione righe master-detail, cache dettagli in memoria |
| assets/js/export.js | Logica export: Excel (SheetJS), PDF (jsPDF), WhatsApp. Legge dati dal DOM. |
| assets/css/styles.css | Stili principali (tema dark completo) |
| assets/css/filters-fix.css | Fix specifici per il layout filtri (label a sinistra, sticky header/footer) |
| printflow/ | Modulo stampa template (DDT, etichette, ecc.) |
| logs/ | File di log applicazione |
Login
TIMS utilizza un sistema di login a 3 campi. Tutti i campi sono obbligatori.
| Campo | Descrizione | Note |
|---|---|---|
| Username | Nome utente registrato nella tabella AnUtenti | Campo Login |
| Password | Password dell'utente | Campo Password, min 4 caratteri |
| Codice Società | Identifica la società/azienda a cui appartieni | Campo codSoc, convertito in MAIUSCOLO |
Interfaccia principale
Dopo il login si accede a index.php, che è un'applicazione single-page con 4 zone principali:
1. Header (barra superiore)
Contiene il toggle sidebar (hamburger), il titolo della pagina/query corrente, le informazioni utente (nome, codSoc, livello), il link a PrintFlow, e il bottone Logout.
2. Sidebar (pannello sinistro)
Mostra i gruppi di query (Magazzino, Anagrafiche, Spedizioni, Configurazione) con le singole query cliccabili. Ha una barra di ricerca in alto per filtrare le voci del menu. La sidebar è collassabile su mobile.
3. Area centrale (griglia dati)
La zona principale dove vengono mostrati i dati della query selezionata. Include: barra azioni (Aggiorna, Nuovo, Esporta, Filtri), pannello filtri (collassabile), tabella dati con header ordinabili, e paginazione in fondo.
4. Modali
Finestre modali per il dettaglio/modifica di un record. Si aprono cliccando su una riga (o sull'icona modifica nelle master-detail). Contengono un form con campi editabili e readonly, e bottoni Annulla/Salva.
Griglia dati
Il cuore dell'applicazione. Ogni query produce una tabella interattiva.
Header colonne cliccabili — Clicca sull'intestazione di una colonna per ordinare i dati (l'ordinamento avviene lato SQL, non lato client, per efficienza con grandi dataset).
Paginazione dinamica con Ellipsis — Di default 50 righe per pagina (configurabile con rows_per_page). Navigazione: bottoni prev/next + numeri di pagina intelligenti che si adattano dinamicamente. Mostra sempre pagina 1, l'ultima pagina, e un range intorno a quella corrente (±2 pagine). Aggiunge ... per indicare gap tra sezioni (es. 1 ... 8 9 [10] 11 12 ... 100). Implementato in assets/js/app.js con funzioni generatePaginationArray() e updatePagination().
Conteggio record — In basso a sinistra viene mostrato il numero totale di record e la pagina corrente.
Dual scrollbar — La tabella ha scrollbar sia in alto che in basso per una navigazione comoda con molte colonne.
Colonne NULL rimosse — Se una colonna ha tutti valori NULL viene nascosta automaticamente (ma i campi editabili sono sempre preservati).
Preferenze griglia
Ogni utente può personalizzare le colonne visibili e il loro ordine per ogni query. Le preferenze vengono salvate nel database e ripristinate automaticamente al prossimo accesso.
Nella barra azioni in cima alla griglia è presente il pulsante Preferenze colonne (icona ingranaggio o colonne). Cliccandolo si apre un pannello modal con la lista di tutte le colonne disponibili per la query corrente.
Nascondere/mostrare colonne — Usa il toggle accanto al nome di ogni colonna per mostrarla o nasconderla dalla griglia.
Riordinare colonne — Trascina le righe con il handle (icona ≡) per cambiare l'ordine di visualizzazione. Usa la libreria SortableJS per il drag-drop.
Salvare — Clicca Salva per persistere le preferenze. Vengono inviate a api/user_preferences.php e salvate in dbo.TimsUserGridPreferences.
Ripristinare i default — Il pulsante Ripristina default elimina le preferenze salvate e riporta la griglia alla configurazione originale del database.json.
Sistema filtri
Premendo il bottone Filtri nella barra azioni si apre il pannello filtri. Ogni colonna della query corrente ha il proprio campo di filtro.
| Tipo | Comportamento | Esempio |
|---|---|---|
| text | Cerca il testo contenuto (LIKE %...%) | "alfa" trova "Alfa Romeo", "alfa123" |
| numeric-min | Valore minimo (>=) | Qta >= 10 |
| numeric-max | Valore massimo (<=) | Qta <= 100 |
| bool | Vero/Falso (1/0) | OrdineChiuso = 1 |
Le label sono posizionate a sinistra dell'input (non sopra). L'header e il footer del pannello filtri sono sticky: restano visibili durante lo scroll. Il footer contiene il conteggio record, il bottone "Pulisci" (resetta tutti i filtri) e "Applica".
Ordinamento
Clicca su qualsiasi intestazione di colonna per ordinare. Un altro click inverte l'ordine (ASC/DESC).
Quando ordini, la SQL originale viene modificata: se contiene già un ORDER BY, viene sostituito; altrimenti viene aggiunto.
Master-Detail (ordini)
Le query di tipo master_detail mostrano una griglia con righe espandibili. Usato per ordini in ingresso e ordini di spedizione.
- La griglia mostra le testate (master). Ogni riga ha un pulsante + a sinistra.
- Cliccando +, il sistema chiama api/ordini.php?action=get_details&master_id=XXX per caricare le righe di dettaglio.
- Le righe di dettaglio appaiono sotto la testata in una sotto-tabella.
- I dettagli vengono messi in cache: riaprire la stessa riga non rifa la chiamata API.
- Cliccando - la riga si richiude.
I dettagli possono avere regole di evidenziazione. Per esempio, in ordini_in le righe con daControllare = 1 vengono evidenziate in giallo (stile "warning"). In ordini_out, le righe con ORR_InPrelievo = 1 si evidenziano allo stesso modo.
Modifica record
Solo gli utenti con livello ≥ 50 (SuperUser, Administrator) possono modificare i dati.
- Clicca su una riga nella griglia (o sull'icona 🔧 nelle master-detail) per aprire la modale dettaglio.
- La modale mostra tutti i campi del record. I campi readonly sono grigi e non modificabili. I campi editabili sono interattivi.
- I campi required sono contrassegnati e devono avere un valore per poter salvare.
- Clicca Salva — il sistema invia un POST a api/data.php?action=update con solo i campi editabili modificati.
- Il backend filtra i campi ricevuti rispetto a editable_fields della config (sicurezza lato server). Costruisce una query UPDATE sulla tabella, usando la primary_key.
Sistema di export
Il dropdown "Esporta" nella barra azioni offre 3 formati. Tutti leggono i dati direttamente dal DOM (la tabella visibile), quindi l'export riguarda sempre e solo i dati filtrati.
| Formato | Libreria | Comportamento |
|---|---|---|
| Excel (XLSX) | SheetJS | Genera un file .xlsx con i dati filtrati. Per master-detail: due fogli separati (testate + righe). |
| jsPDF + AutoTable | Genera un PDF con tabella formattata. Orientamento auto (landscape se molte colonne). | |
| SheetJS + Web Share API | Genera un file XLSX e apre il dialog di condivisione del dispositivo (WhatsApp, email, ecc.). |
Livelli utente e permessi
| Livello | Ruolo | Vede query | Modifica dati | Bottoni custom |
|---|---|---|---|---|
| 100 | Administrator | Tutte | Sì | Tutti |
| 90 | Administrator | Tutte (incl. Configurazione, Locazioni) | Sì | Tutti |
| 50 | SuperUser | Query con min_level ≤ 50 | Sì | Quelli con min_level ≤ 50 |
| 10 | StandardUser | Query con min_level ≤ 10 | No | Quelli con min_level ≤ 10 (es. Stampa DDT) |
Il bottone Nuovo e il bottone Salva nella modale appaiono solo se l'utente ha livello ≥ 50 (verificato in PHP nel rendering di index.php).
Filtro società (codSoc)
Il filtro società è un meccanismo di sicurezza fondamentale. Ogni utente è associato a un codSoc e può vedere solo i dati della propria società.
Quando l'utente carica una query, il backend aggiunge automaticamente AND codSoc = @userCodSoc alla WHERE della SQL. L'utente non può mai vedere dati di un'altra società.
La classe Query.php ha il metodo executeWithCodSoc() che gestisce l'iniezione del filtro, tenendo conto della struttura della query (JOIN, subquery, posizione della WHERE).
Gestione sessione
TIMS implementa un sistema di sessioni per-tab indipendenti usando token univoci invece dei tradizionali cookie PHP. Questo permette lo stesso utente di avere sessioni separate in tab diverse del browser.
Come funziona: Al login, il server genera un tabToken univoco di 48 caratteri esadecimali. Questo token identifica la sessione per quella specifica tab/finestra.
Trasmissione del token: Il token viene passato al frontend e deve essere incluso in ogni richiesta API tramite:
X-Tab-Token (header HTTP preferito)
_tab_token (parametro GET come fallback per pagine di stampa)
Sessioni indipendenti: Ogni tab mantiene la sua sessione in memoria sul server. Lo stesso utente loggato da browser diversi o tab diversi avrà sessioni completamente separate, con login_time indipendenti.
Timeout: 3600 secondi (1 ora). Il timer si resetta ad ogni chiamata API autenticata (il metodo isAuthenticated() aggiorna il login_time).
Validazione: Il backend estrae il tabToken dal header X-Tab-Token, lo passa a session_id($tabToken), e verifica che la sessione sia ancora attiva e non scaduta.
Sessione scaduta: Se una chiamata API ritorna HTTP 401 ("Autenticazione richiesta"), il frontend mostra un modal di errore e redirige a login.php dopo qualche secondo.
L'applicazione esegue periodicamente un ping a api/ping.php (con X-Tab-Token header) per verificare se la sessione è ancora attiva senza rinnovarla. Questo permette di mostrare l'avviso di scadenza prima che avvenga una chiamata reale, evitando la perdita di dati in fase di editing.
ping.php controlla il timestamp della sessione senza aggiornarlo. Se la sessione è scaduta risponde HTTP 401, innescando il redirect al login.
Stampe e PrintFlow
Le stampe in TIMS avvengono in due modi: attraverso bottoni custom nelle griglie (che aprono l'HTML in nuova tab), oppure tramite il modulo PrintFlow accessibile dall'header.
I bottoni di stampa nelle griglie chiamano direttamente endpoint PHP che generano HTML stampabile. Si aprono in una nuova scheda del browser.
Nota auth: i file di stampa accettano l'autenticazione sia tramite sessione PHP (normale) che tramite parametri GET _user e _codsoc come fallback, per compatibilità con link diretti o apertura in nuova tab senza sessione attiva.
Le stampe LdP (api/print_ldp.php e api/print_ldp_Multi.php) supportano 3 modalità di ordinamento tramite il parametro sort:
| Valore sort | Ordinamento |
|---|---|
| seq | Sequenza di prelievo standard |
| xcorsia | Per corsia: Corsia → Posizione → Piano → SeqPrelievo |
| xarticolo | Per articolo: codArticolo → SeqPrelievo |
Gli articoli senza locazione (Out-Of-Stock) appaiono sempre in cima quando il parametro noLocFirst è attivo.
PrintFlow è un modulo standalone accessibile dal bottone nell'header. Si apre in una pagina separata (printing.php) e permette di cercare e stampare documenti senza dover navigare le griglie.
Funzionalità disponibili: ricerca per locazione (dropdown cascata), ricerca lista di prelievo per numero lista o numero ordine, stampa con scelta di ordinamento.
Usa api/printing_ajax.php per i dropdown e le ricerche dinamiche.
Per il bottone custom "Stampa DDT" (attualmente nascosto, visible=false) chiama l'endpoint printflow/api/generate.php. Per la documentazione completa di PrintFlow consultare la cartella Docs/.
Sezione: Magazzino
Contiene 3 query di sola lettura per consultare lo stato del magazzino.
Mostra lo storico di tutti i movimenti di carico/scarico. Ogni riga è un movimento con articolo, quantità, causale, DDT, lotto e scadenza. I dati arrivano dalla tabella StMovimenti con JOIN su AnArticoli per mostrare codice e descrizione articolo. Ordinati per ID decrescente (più recenti in cima).
Uso tipico: Cercare un movimento specifico filtrando per codArticolo, Lotto, DDT o NumeroOrdine.
Anagrafica delle posizioni fisiche del magazzino: magazzino fisico/logico, corsia, posizione, piano, alias. Mostra anche le proprietà (picking/scorta, prelevabile, multi-articolo, dimensioni, peso max). Usa la tabella AnLocazioni, che non ha codSoc.
Uso tipico: Consultare la struttura del magazzino, verificare caratteristiche di una locazione.
Stato attuale dello stock: mostra gli articoli in magazzino con quantità > 0, posizionati per locazione. Usa la vista vStockArticoliPosizioni. Include lotto, scadenza, pallet, quantità impegnata e posizione completa.
Uso tipico: Verificare la disponibilità di un articolo, controllare dove è posizionato, vedere le scadenze.
Sezione: Anagrafiche
Lista completa degli articoli attivi (Cancellato = 0). Mostra codice, descrizioni, quantità confezionamento/pezzo, pesi, gestione lotto/scadenza, unità misura. L'unico campo modificabile è descrizione1 (descrizione aggiuntiva).
Uso tipico: Cercare un articolo per codice o descrizione, consultare le caratteristiche, aggiornare la descrizione aggiuntiva.
Elenco clienti, fornitori e vettori dalla tabella AnCliForn. Mostra codice cliente, codice fornitore, ragione sociale, indirizzo, contatti e provincia. Per gli utenti livello ≥ 50 sono disponibili la creazione e la modifica dei record.
Regole di inserimento (insert rules):
• RagioneSociale è obbligatoria
• Almeno uno tra Cli, Forn, Vett deve essere impostato a 1 (il soggetto deve avere almeno un ruolo)
• Se Cli = 1 allora codCli diventa obbligatorio
• Se Forn = 1 o Vett = 1 allora codForn diventa obbligatorio
• I codici codCli e codForn devono essere unici per tipo (controllo duplicati automatico)
• Alcuni campi (codSoc, utenteCreazione, utenteUltModifica) vengono popolati automaticamente dal sistema
Uso tipico: Cercare un cliente o fornitore per ragione sociale o codice; aggiungere nuovi soggetti; aggiornare i dati anagrafici.
Sezione: Spedizioni
Gestione ordini fornitori. La testata mostra: ordine fornitore, progressivo arrivo, date, note (ordine/logistica/DDT/trasporto), DDT, stato chiusura, esito invio, ragione sociale e codice fornitore.
Espandendo una riga, il dettaglio mostra le righe dell'ordine: articolo, lotto atteso, scadenza attesa, quantità attesa/caricata, stato completamento, campi extra, flag "da controllare".
Azioni disponibili:
• Modifica testata/righe — Clic sulla riga per aprire la modale.
• Chiudi Ordine — Selezione multipla, imposta OrdineChiuso=1 (level ≥ 50). Handler: chiudiOrdineIn() in assets/js/chiudi-ordine-in.js. API: api/chiudi_ordine_in.php.
• Stampa Etichette IN — Selezione singola, apre modale split-pallet per configurare etichette × quantità per riga ordine (level ≥ 10). Handler: stampaEtichetteIn() in assets/js/etichette-in.js. API: api/etichette_in.php, api/print_etichette_in.php.
• Stampa DDT — Selezione singola, genera DDT via PrintFlow. API: api/print_ordini_in.php (attualmente nascosto: visible=false).
Liste di prelievo con dettaglio articoli e locazioni. Tabelle: OrListaPCOTes (master) + OrListaPCORig (detail). Sola lettura.
Master — Mostra: numero lista, data lista, numero ordine collegato, bolla, data bolla, stato InPrelievo.
Detail — Mostra: articolo, descrizione, lotto, pallet, quantità da prelevare/prelevata/out-of-stock, locazione fisica e logica (corsia, posizione, piano).
• Stampa LdP — Bottone custom per stampa lista di prelievo (level ≥ 10). API: api/print_ldp.php, api/print_ldp_Multi.php. Disponibile anche con api/printing_ajax.php per stampa automatica.
Gestione bordereau spedizioni dalla tabella OrBordereau (non ha filtro codSoc). Operazioni disponibili:
• Visualizza — Lista tutti i bordereau con paginazione, filtri dinamici (tutti gli utenti)
• Crea — Seleziona vettore e ordini di uscita, genera codice univoco da progressivo AnProgr, collega ordini (level ≥ 50)
• Chiudi — Imposta dataChiusura e utenteUltModifica (level ≥ 50, solo se dataChiusura IS NULL)
• Cancella — Cancellazione logica (Cancellato=1) + scollega automaticamente ordini (level ≥ 50, solo se non chiuso)
Bottoni custom stampa (dropdown):
• Stampa Lista di Carico — Genera la distinta di carico del bordereau selezionato (formato A4, colli deduplicati, totale peso). API: api/print_bordereau.php
• Bordereau per Vettore — Genera il documento bordereau con firma da consegnare al vettore (UDS per riga, totali deduplicati). API: api/print_bordereau_vettore.php
API Backend: api/bordereau.php con azioni: create, close, delete, get_vettori, get_available_orders
Handler JavaScript: assets/js/chiudi-bordereau.js — chiusura con verifica preliminare · assets/js/app.js (deleteBordereau) — cancellazione con transazione atomica
Gestione ordini clienti/spedizioni. La testata mostra: numero ordine, date, bolla, destinazione completa (rag. soc., indirizzo, località, CAP, provincia, nazione), note, contrassegno, fattura, ragione sociale cliente, anno, stato prelievo.
Il dettaglio mostra le righe: numero riga, riserve pallet/posizione, lotto, scadenza, matricola, pallet, varianti (1-8), quantità ordinata/prelevata, note riga.
Le righe con ORR_InPrelievo = 1 sono evidenziate in giallo.
Sezione: Configurazione
Accessibile solo ad Administrator (livello 90+).
Tabella AnOpzioni. Opzioni di configurazione del sistema: chiave-valore per società e utente. Sola lettura in TIMS.
Tabella AnUtenti. Lista utenti del sistema con login, tipo, token, menu di riferimento. L'unico campo modificabile è Abilitato (per attivare/disattivare un utente).
Tabella AnProgr (TOP 200). Gestione contatori/progressivi per numerazione automatica. Campi editabili: Progr (valore attuale), Abilitato, Prefisso. Ha chiave primaria composita [codSoc, NomeProgr].
Endpoint API
Riepilogo di tutte le API disponibili nel backend.
| Endpoint | Metodo | Funzione |
|---|---|---|
| api/auth.php | POST | Login (action: login) e Logout (action: logout) |
| api/data.php?action=config | GET | Ottiene gruppi, query e ui_settings |
| api/data.php?action=list&queryId=xxx | GET | Lista dati con filtri, paginazione, ordinamento |
| api/data.php?action=update | POST | Aggiorna record (solo campi editabili) |
| api/ping.php | GET | Heartbeat: verifica sessione attiva senza rinnovarla (risponde 401 se scaduta) |
| api/menu.php | GET | Struttura menu (gruppi + query) |
| api/user_preferences.php | GET/POST/DELETE | Gestione preferenze griglia utente (visibilità e ordine colonne per query) |
| api/ordini.php?action=get_details | GET | Righe dettaglio di una testata master-detail |
| api/custom_action.php | POST | Esegue azioni bottoni custom (SQL o api_call) |
| api/bordereau.php?action=create | POST | Crea nuovo bordereau con ordini collegati (richiede level ≥ 50) |
| api/bordereau.php?action=close | POST | Chiude bordereau: imposta dataChiusura (richiede level ≥ 50) |
| api/bordereau.php?action=delete | POST | Cancella logicamente bordereau e scollega ordini (richiede level ≥ 50) |
| api/bordereau.php?action=get_vettori | GET | Lista vettori disponibili per creazione bordereau |
| api/bordereau.php?action=get_available_orders | GET | Lista ordini di uscita da collegare al bordereau |
| api/chiudi_ordine_in.php | POST | Chiusura ordini in ingresso multi-step: validazione → dialogo delta → UPDATE OrdineChiuso=1 (level ≥ 50) |
| api/etichette_in.php | POST | Genera etichette per ordini in ingresso: action=load (carica righe) / action=generate (riserva pallet su AnProgr) |
| api/print_etichette_in.php | GET | Stampa etichette IN in formato HTML per stampa diretta |
| api/print_ordini_in.php | GET | Genera DDT per ordini in ingresso (attualmente nascosto: visible=false) |
| api/print_ldp.php | GET | Stampa Lista di Prelievo singola (parametro sort: seq/xcorsia/xarticolo) |
| api/print_ldp_Multi.php | GET | Stampa multipla Liste di Prelievo (parametro ids=id1,id2,...) |
| api/print_bordereau.php | GET | Stampa Distinta di Carico bordereau (A4, colli deduplicati, totale peso) |
| api/print_bordereau_vettore.php | GET | Stampa Bordereau per Vettore con firma (UDS per riga, totali deduplicati) |
| api/print_plist_berlin.php | GET | Stampa Packing List stile Berlin Packaging (usa view roviews.vImpPackingList) |
| api/print_etichette.php | GET | Stampa etichette generiche |
| api/printing_ajax.php | POST | AJAX per modulo Printing: dropdown cascata, ricerca locazioni, ricerca LdP |
| File JS | Handler | Funzione |
|---|---|---|
| assets/js/app.js | — | Logica principale: menu, griglia, filtri, paginazione ellipsis, editing, heartbeat sessione |
| assets/js/grid-preferences.js | — | Modal drag-drop preferenze colonne (SortableJS): visibilità + ordine, persistenza in TimsUserGridPreferences |
| assets/js/export.js | — | Sistema export lato client: Excel (SheetJS), PDF (jsPDF), WhatsApp |
| assets/js/master-detail.js | — | Gestione apertura/chiusura righe dettaglio master-detail, cache in memoria |
| assets/js/chiudi-bordereau.js | chiudiBordereau | Chiusura bordereau con verifica dataChiusura IS NULL |
| assets/js/chiudi-ordine-in.js | chiudiOrdineIn | Chiusura ordini in ingresso multi-step: validazione → dialogo delta quantità → conferma UPDATE |
| assets/js/etichette-in.js | stampaEtichetteIn | Modale split-pallet: configurazione N etichette × quantità per riga ordine, riserva ID pallet su AnProgr |
Troubleshooting
Sintomo: La pagina non carica dati, errori "JSON parse" nella console.
Causa: PHP sta stampando warning o errori prima del JSON.
Soluzione: Verificare che error_reporting(0) e ini_set('display_errors', 0) siano presenti all'inizio di ogni file API. Usare ob_start() e ob_clean() prima dell'output JSON.
Sintomo: Errore SQL "Ambiguous column name" quando si aggiunge il filtro codSoc.
Causa: Il campo codSoc esiste in più tabelle del JOIN.
Soluzione: Nella SQL, prefissare sempre codSoc con il nome tabella (es. OfOrdiniInTES.codSoc). Il metodo addCodSocFilter in Query.php cerca di determinare la tabella giusta, ma è meglio essere espliciti.
Sintomo: Errori SQL quando si usa GETDATE() senza alias.
Causa: SQL Server richiede un alias per le colonne calcolate.
Soluzione: Usare sempre GETDATE() AS nomeAlias nelle SELECT.
Sintomo: Errori con mb_strtolower, mb_substr su IIS.
Causa: L'estensione mbstring potrebbe non essere attiva su IIS.
Soluzione: Non usare funzioni mb_* nel codice. Il sistema è stato adattato per usare solo funzioni string standard di PHP.
Sintomo: Redirect a login dopo poco tempo.
Causa: Il timeout è 3600 secondi. Se il browser non fa chiamate API per un'ora, la sessione scade.
Soluzione: Il timeout si resetta ad ogni operazione. Se il problema persiste, verificare la configurazione PHP di session.gc_maxlifetime su IIS.
Sintomo: I nuovi record non appaiono in cima alla lista.
Causa: La SQL potrebbe non avere un ORDER BY DESC.
Soluzione: Aggiungere ORDER BY Id DESC (o campo data) alla SQL nel database.json. L'ordinamento avviene a livello SQL, non lato client.