Files
zibo-dashboard/public/userarea/sales_help.js
T
2026-10-16 15:37:01 +02:00

554 lines
32 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* sales_help.js - Guida contestuale delle pagine statistiche vendite.
*
* Uso nelle pagine:
* <div class="chart-title" data-help="st.monthly">...</div> → aggiunge l'icona ⓘ in fondo all'elemento
* <button data-help-open="page.stats">...</button> → apre la guida al click (guida di pagina)
*
* I testi sono tutti qui sotto (SALES_HELP): per cambiarli basta modificare questo file.
* Funziona anche sugli elementi creati dopo (box disegnati via JavaScript).
*/
(function () {
"use strict";
const SALES_HELP = {
/* ===================== GUIDE DI PAGINA ===================== */
"page.stats": {
t: "Andamento ordini: come si usa",
b: `<p>Qui vedi <b>gli ordini clienti</b> del periodo scelto: quanti sono, quanto valgono, a che punto sono.</p>
<ul>
<li><b>In alto</b> scegli il periodo (mese, trimestre, anno…) e se vuoi cliente, agente, area o stato.</li>
<li><b>I box colorati</b> sono cliccabili: filtrano tutta la pagina (es. clic su <i>In ritardo</i> = solo ordini in ritardo).</li>
<li><b>I grafici</b> sono cliccabili: un mese, una fetta, un cliente diventano un filtro.</li>
<li><b>L'elenco in fondo</b>: clic su una riga per il dettaglio dell'ordine con le sue righe; si esporta in Excel.</li>
<li>Il selettore <b>N° ordini / Valore</b> cambia cosa misurano i grafici.</li>
</ul>
<p class="sh-note">Gli ordini con la parola "listino" sono esclusi. I filtri restano memorizzati quando torni sulla pagina; la gomma 🧽 li azzera.</p>`,
},
"page.years": {
t: "Confronto anni: come si usa",
b: `<p>Qui confronti <b>gli anni tra loro</b> e vedi <b>la situazione ad oggi</b>.</p>
<ul>
<li><b>Situazione ad oggi</b> (in alto): portafoglio, book-to-bill e previsioni. Non dipende dagli anni scelti.</li>
<li><b>Chip degli anni</b>: scegli quali anni confrontare (ognuno ha il suo colore in tutti i grafici).</li>
<li><b>A pari data</b>: acceso, ogni anno è contato solo fino al giorno di oggi → confronto giusto con l'anno in corso. Spento: anni interi.</li>
<li><b>Clienti da richiamare</b> e <b>Clienti a confronto</b>: clic su un cliente per filtrare tutta la pagina; l'icona verde apre la sua scheda.</li>
</ul>
<p class="sh-note">Cliente, agente e area filtrano tutto, anche il fatturato.</p>`,
},
"page.deliveries": {
t: "Consegne: come si usa",
b: `<p>Qui vedi <b>le righe d'ordine ancora da consegnare</b>, cioè il lavoro da spedire.</p>
<ul>
<li><b>Data ZIBO</b> (rossa quando scaduta) = la settimana di consegna che abbiamo comunicato: è la scadenza che conta. La riga è in ritardo solo quando quella settimana è finita; durante la settimana compare <span class="sh-chip sh-amber">IN SETTIMANA</span>.</li>
<li><b>Data cliente</b> (arancione quando superata) = quando il cliente l'avrebbe voluta: è un riferimento.</li>
<li><b>Scadenza</b> (chip in alto), box e grafici filtrano le righe; si combinano con cliente, articolo, agente, area.</li>
</ul>
<p class="sh-note">Cosa fare: parti dalle <b>scadute</b>, poi guarda <b>i prossimi giorni</b> e le settimane più cariche del grafico.</p>`,
},
"page.customer": {
t: "Scheda cliente: come si usa",
b: `<p>Tutto su <b>un cliente</b> in una pagina. Cercalo per nome o codice, oppure clicca l'icona verde accanto a un cliente nelle altre pagine.</p>
<ul>
<li><b>Profilo</b>: da quando è cliente, ultimo ordine, ogni quanto ordina di solito e il suo stato (attivo, attenzione, dormiente…).</li>
<li><b>Box</b>: quest'anno rispetto allo scorso, cosa gli dobbiamo consegnare, note di credito.</li>
<li><b>Tabelle</b> in fondo: righe da consegnare, ordini, articoli, fatture. Tutte esportabili in Excel.</li>
</ul>
<p class="sh-note">Utile prima di una telefonata o di una visita. I clienti visti di recente restano a portata di clic.</p>`,
},
"page.summary": {
t: "Sommario: come si legge",
b: `<p>Il <b>riepilogo per la direzione</b>: in un colpo d'occhio cosa va bene e cosa no.</p>
<ul>
<li><b>Semaforo in alto</b>: il giudizio complessivo. Il punteggio su 100 conta i verdi (100), i gialli (50) e i rossi (0).</li>
<li><b>Cosa va bene / Cosa non va</b>: gli stessi indicatori, scritti in frasi semplici; i rossi sono in cima.</li>
<li><b>Tessere</b>: ogni indicatore ha il suo colore. <span class="sh-chip sh-green">Bene</span> <span class="sh-chip sh-amber">Così così</span> <span class="sh-chip sh-red">Male</span>. Clic sulla tessera per andare alla pagina con i dettagli.</li>
<li><b>Clienti da guardare</b>: chi cresce, chi cala, chi richiamare subito. Clic sul nome per la scheda cliente.</li>
</ul>
<p class="sh-note">Il sommario guarda sempre <b>tutta l'azienda ad oggi</b>: non ha filtri. Per approfondire usa le altre pagine.</p>`,
},
/* ===================== SOMMARIO ===================== */
"sm.invYtd": {
t: "Fatturato dell'anno",
b: `<p>Fatturato da gennaio a oggi rispetto allo <b>stesso periodo dell'anno scorso</b>.</p>
<p>🟢 almeno +3% · 🟡 tra −3% e +3% · 🔴 sotto −3%.</p>`,
},
"sm.ordYtd": {
t: "Ordinato dell'anno",
b: `<p>Ordini ricevuti da gennaio a oggi rispetto allo stesso periodo dell'anno scorso. È il fatturato dei prossimi mesi.</p>
<p>🟢 almeno +3% · 🟡 tra −3% e +3% · 🔴 sotto −3%.</p>`,
},
"sm.forecast": {
t: "Chiusura prevista",
b: `<p>Come chiuderà l'anno se si continua con lo stesso ritmo degli anni scorsi, confrontata con l'anno scorso intero.</p>
<p>🟢 almeno +3% · 🟡 tra −3% e +3% · 🔴 sotto −3%.</p>
<p class="sh-note">È una stima: diventa più affidabile man mano che l'anno avanza.</p>`,
},
"sm.b2b": {
t: "Book-to-bill",
b: `<p>Ordini entrati ÷ fatture emesse negli ultimi 90 giorni. Dice se il lavoro in arrivo tiene il passo con quello che consegniamo.</p>
<p>🟢 da 1,05 (il portafoglio cresce) · 🟡 tra 0,95 e 1,05 · 🔴 sotto 0,95 (lo stiamo consumando).</p>
<p class="sh-note">Il grafico mostra lo stesso valore mese per mese (su 3 mesi): la riga tratteggiata è 1.</p>`,
},
"sm.cover": {
t: "Lavoro in portafoglio",
b: `<p>Per quante <b>settimane di lavoro</b> basta quello che abbiamo da consegnare, al ritmo di fatturato degli ultimi 3 mesi.</p>
<p>🟢 almeno 8 settimane · 🟡 da 4 a 8 · 🔴 meno di 4.</p>`,
},
"sm.late": {
t: "Consegne in ritardo",
b: `<p>Quanta parte del portafoglio è già <b>oltre la settimana ZIBO</b> comunicata al cliente.</p>
<p>🟢 fino al 10% · 🟡 dal 10 al 25% · 🔴 oltre il 25%.</p>
<p class="sh-note">Cosa fare: apri Consegne e parti dalle righe scadute.</p>`,
},
"sm.risk": {
t: "Clienti a rischio",
b: `<p>Clienti abituali <b>dormienti</b> o <b>probabilmente persi</b> e quanto valevano in un anno, rispetto al giro d'affari totale.</p>
<p>🟢 fino al 3% · 🟡 dal 3 all'8% · 🔴 oltre l'8%.</p>
<p class="sh-note">Cosa fare: lista "Da richiamare subito" qui sotto, o quella completa in Confronto anni.</p>`,
},
"sm.top5": {
t: "Peso dei primi 5 clienti",
b: `<p>Quanto del fatturato degli ultimi 12 mesi viene dai 5 clienti più grandi. Più è alto, più dipendiamo da pochi nomi.</p>
<p>🟢 fino al 40% · 🟡 dal 40 al 60% · 🔴 oltre il 60%.</p>`,
},
"sm.customers": {
t: "Clienti attivi",
b: `<p>Clienti che hanno ordinato negli ultimi 12 mesi, confrontati con i 12 mesi prima. "Nuovi" = primo ordine nell'ultimo anno.</p>
<p>🟢 stabili o in crescita · 🟡 fino a −5% · 🔴 oltre −5%.</p>`,
},
"sm.cn": {
t: "Note di credito",
b: `<p>Note di credito degli ultimi 12 mesi in percentuale sul fatturato: misura resi, sconti e contestazioni.</p>
<p>🟢 fino all'1,5% · 🟡 dall'1,5 al 3% · 🔴 oltre il 3%.</p>`,
},
"sm.up": {
t: "Clienti che crescono",
b: `<p>I clienti che hanno aumentato di più (in euro) negli ultimi 12 mesi rispetto ai 12 precedenti. Da coltivare.</p>`,
},
"sm.down": {
t: "Clienti che calano",
b: `<p>I clienti che sono diminuiti di più (in euro) negli ultimi 12 mesi rispetto ai 12 precedenti.</p>
<p class="sh-note">Cosa fare: capire il motivo (concorrenza, prezzi, problemi di consegna) con una telefonata.</p>`,
},
"sm.call": {
t: "Da richiamare subito",
b: `<p>I clienti abituali più importanti che si sono fermati (dormienti o probabilmente persi), ordinati per valore.</p>`,
},
/* ===================== ANDAMENTO ORDINI ===================== */
"st.orders": {
t: "Ordini",
b: `<p>Numero di ordini del periodo e dei filtri scelti. Sotto: confronto con lo <b>stesso periodo dell'anno prima</b>.</p>
<p class="sh-note">Clic sul box: toglie il filtro di stato e mostra tutti gli ordini.</p>`,
},
"st.value": {
t: "Valore ordinato",
b: `<p>Somma dell'<b>imponibile</b> degli ordini del periodo (annullati esclusi), con il confronto con lo stesso periodo dell'anno prima.</p>`,
},
"st.toship": {
t: "Da evadere",
b: `<p>Valore degli ordini <b>ancora aperti</b> (non consegnati del tutto). In rosso la parte <b>già in ritardo</b>.</p>
<p class="sh-note">Cosa fare: se la quota in ritardo cresce, guarda la pagina Consegne.</p>`,
},
"st.open": {
t: "Aperti",
b: `<p>Ordini non ancora consegnati del tutto e non annullati. Clic per vederli.</p>`,
},
"st.late": {
t: "In ritardo",
b: `<p>Ordini con almeno <b>una riga aperta oltre la data ZIBO</b> (la settimana comunicata è finita).</p>
<ul>
<li><b>Righe in ritardo</b>: quante righe sono scadute; <b>parziali</b> = ordini dove è in ritardo solo una parte delle righe.</li>
<li><b>Oltre data cliente</b> (arancione): superata la data desiderata dal cliente, ma non ancora la nostra.</li>
<li>Striscia gialla <b>in consegna questa settimana</b>: ordini con righe da consegnare entro domenica, non ancora in ritardo. Cliccala per vederli.</li>
</ul>
<p class="sh-note">Cosa fare: clic sul box per la lista, poi apri gli ordini per vedere quali righe mancano.</p>`,
},
"st.done": {
t: "Evasi",
b: `<p>Ordini completamente consegnati nel periodo scelto (per data ordine).</p>`,
},
"st.toinvoice": {
t: "Da fatturare",
b: `<p>Ordini <b>consegnati ma non ancora fatturati</b>.</p>
<p class="sh-note">Cosa fare: segnalali all'amministrazione se restano qui a lungo.</p>`,
},
"st.customers": {
t: "Clienti attivi",
b: `<p>Quanti clienti diversi hanno ordinato nel periodo. Sotto: in media dopo quanti giorni dall'ordine è prevista la consegna.</p>`,
},
"st.monthly": {
t: "Andamento mensile",
b: `<p>Ordini (o valore) mese per mese nel periodo scelto. Clic su un mese per filtrare solo quel mese.</p>`,
},
"st.status": {
t: "Ripartizione per stato",
b: `<p>Come si dividono gli ordini: aperti, evasi, bloccati, annullati. Clic su una fetta per filtrare.</p>`,
},
"st.topcust": {
t: "Top 10 clienti",
b: `<p>I 10 clienti più importanti del periodo (per numero ordini o valore). Le barre sono divise tra ordini aperti e altri (evasi/annullati).</p>
<p class="sh-note">Clic su un cliente per vedere solo i suoi ordini.</p>`,
},
"st.due": {
t: "Scadenze ordini aperti",
b: `<p>Gli ordini aperti divisi per <b>quando vanno consegnati</b>: già scaduti, questa settimana, la prossima, entro 30 giorni, oltre, senza data.</p>`,
},
"st.items": {
t: "Top 10 articoli",
b: `<p>Gli articoli più ordinati nel periodo, calcolati dalle righe d'ordine. Passa sopra una barra per quantità e valore.</p>`,
},
"st.area": {
t: "Per area",
b: `<p>Ordini (o valore) divisi per area commerciale.</p>`,
},
"st.agent": {
t: "Per agente",
b: `<p>Ordini (o valore) divisi per agente.</p>`,
},
"st.list": {
t: "Elenco ordini",
b: `<p>Tutti gli ordini dei filtri scelti. Clic su una riga per il <b>dettaglio con le righe</b>, le date e cosa resta da consegnare.</p>
<ul>
<li><span class="sh-chip sh-red">IN RITARDO</span> data ZIBO superata · <span class="sh-chip sh-amber">PARZIALE</span> solo alcune righe in ritardo · <span class="sh-chip sh-orange">OLTRE DATA CLIENTE</span> superata solo la data del cliente.</li>
<li>Il pulsante Excel scarica l'elenco come lo vedi.</li>
</ul>`,
},
/* ===================== CONFRONTO ANNI ===================== */
"yr.dash": {
t: "Situazione ad oggi",
b: `<p>Una fotografia di <b>oggi</b>, che non cambia con gli anni scelti. Segue solo i filtri cliente, agente e area (così puoi vederla anche per un agente o un cliente).</p>`,
},
"yr.backlog": {
t: "Portafoglio da consegnare",
b: `<p>Valore di tutte le righe d'ordine <b>ancora da consegnare</b>.</p>
<ul>
<li><b>Settimane</b>: per quante settimane di lavoro basta, al ritmo medio di fatturato degli ultimi 3 mesi.</li>
<li>In rosso la parte <b>già oltre la data ZIBO</b>.</li>
</ul>
<p class="sh-note">Poche settimane = servono ordini nuovi. Tante settimane con molto in ritardo = c'è un problema di capacità o di consegne.</p>`,
},
"yr.b2b": {
t: "Book-to-bill",
b: `<p>Confronta <b>il lavoro che entra</b> (ordini) con <b>quello che esce</b> (fatture) negli ultimi 90 giorni.</p>
<ul>
<li><b>1,0</b> = equilibrio.</li>
<li><b>Sopra 1</b> (es. 1,20 → per ogni 100 € fatturati entrano 120 € di ordini): il portafoglio cresce 🟢</li>
<li><b>Sotto 1</b> (es. 0,80): stiamo consumando il portafoglio, tra qualche mese il fatturato rischia di calare 🔴</li>
</ul>
<p class="sh-note">È un segnale che arriva <b>prima</b> del calo di fatturato.</p>`,
},
"yr.fcInv": {
t: "Previsione fatturato",
b: `<p>Stima di come chiuderà l'anno. Si prende il fatturato <b>ad oggi</b> e lo si proietta con la stagionalità degli ultimi 3 anni (es. se negli anni scorsi a questa data eravamo al 78% dell'anno, oggi siamo probabilmente al 78%).</p>
<p class="sh-note">La <b>forbice</b> va dall'anno più favorevole a quello meno favorevole. Diventa più precisa man mano che l'anno avanza.</p>`,
},
"yr.fcOrd": {
t: "Previsione ordinato",
b: `<p>Come la previsione del fatturato, ma sugli <b>ordini ricevuti</b>: quanto ordinato porteremo a casa entro fine anno se si continua così.</p>`,
},
"yr.b2bchart": {
t: "Ordinato vs fatturato · 24 mesi",
b: `<p>Barre viola = ordini ricevuti nel mese · barre verdi = fatturato del mese.</p>
<p>La <b>linea arancione</b> è il book-to-bill su 3 mesi: sopra la riga tratteggiata dell'1 il portafoglio cresce, sotto si consuma.</p>
<p class="sh-note">Se la linea resta sotto 1 per diversi mesi, è il momento di spingere sugli ordini.</p>`,
},
"yr.cards": {
t: "Anni a confronto",
b: `<p>Una carta per ogni anno scelto: valore ordinato (numero grande), numero ordini, ordine medio, clienti, fatturato e variazione rispetto all'anno prima.</p>
<p class="sh-note">Con <b>A pari data</b> acceso ogni anno è contato fino a oggi: il confronto con l'anno in corso è corretto.</p>`,
},
"yr.monthly": {
t: "Ordinato per mese",
b: `<p>Una linea per anno, mese per mese: mostra la <b>stagionalità</b> e in quali mesi quest'anno va meglio o peggio.</p>`,
},
"yr.cumul": {
t: "Progressivo dell'anno",
b: `<p>Somma da gennaio a ogni mese. Se la linea dell'anno in corso è <b>sopra</b> quelle degli anni scorsi, siamo avanti; se è sotto, siamo indietro.</p>`,
},
"yr.invMonthly": {
t: "Fatturato per mese",
b: `<p>Fatturato vero per <b>data della fattura</b>: fatture + fatture d'acconto − note di credito (imponibile).</p>
<p class="sh-note">È sempre in €, anche se in alto è selezionato "N° ordini".</p>`,
},
"yr.invCumul": {
t: "Fatturato progressivo",
b: `<p>Fatturato sommato da gennaio, anno su anno: dice se stiamo fatturando più o meno degli anni scorsi alla stessa data.</p>`,
},
"yr.invTable": {
t: "Tabella dati fatturato",
b: `<p>Gli stessi numeri dei grafici in tabella: <b>per mese</b> (con progressivo e variazione) oppure <b>l'elenco delle fatture</b> e note di credito.</p>
<p class="sh-note">Pulsante Excel per scaricarli: il titolo del file riporta i filtri usati.</p>`,
},
"yr.dormant": {
t: "Clienti da richiamare",
b: `<p>Clienti che ordinavano <b>con regolarità</b> (almeno 4 volte negli ultimi 3 anni) e che ora <b>tardano</b> rispetto al loro solito.</p>
<ul>
<li><b>Ritmo abituale</b>: ogni quanti giorni ordina di solito.</li>
<li><b>Ritardo</b>: giorni dall'ultimo ordine ÷ ritmo. Es. ordina ogni 30 giorni e sono passati 60 → 2×.</li>
<li><span class="sh-chip sh-yellow">Attenzione</span> da 1,5× · <span class="sh-chip sh-orange">Dormiente</span> da 2× · <span class="sh-chip sh-red">Probabilmente perso</span> da 4× o oltre un anno.</li>
<li>In cima quelli che <b>valgono di più</b> (ordinato dei 12 mesi prima dell'ultimo ordine).</li>
</ul>
<p class="sh-note">Cosa fare: chiamare partendo dall'alto. Esporta in Excel per dividerli tra i commerciali.</p>`,
},
"yr.custcmp": {
t: "Clienti a confronto",
b: `<p>Ogni cliente con il suo valore (o numero ordini) negli anni scelti e la variazione tra gli ultimi due.</p>
<ul>
<li><b>Nuovi</b>: non c'erano l'anno prima · <b>Persi</b>: non ci sono quest'anno.</li>
<li><b>In crescita / in calo</b>: oltre ±10%.</li>
</ul>
<p class="sh-note">Clic su un cliente per filtrare la pagina; l'icona verde apre la sua scheda.</p>`,
},
"yr.ytd": {
t: "A pari data",
b: `<p><b>Acceso</b>: ogni anno è contato solo fino al giorno di oggi (es. 1 gennaio – 15 ottobre). È il modo giusto per confrontare l'anno in corso con i precedenti.</p>
<p><b>Spento</b>: anni interi (l'anno in corso sembrerà sempre più basso finché non finisce).</p>`,
},
/* ===================== CONSEGNE ===================== */
"dl.horizon": {
t: "Scadenza",
b: `<p>Filtra le righe per quando vanno consegnate: scadute (data ZIBO o data cliente), questa settimana, la prossima, entro 30 giorni, senza data.</p>`,
},
"dl.total": {
t: "Da consegnare",
b: `<p>Tutte le righe ancora da consegnare (con i filtri scelti) e il loro <b>valore residuo</b> (solo la parte non ancora consegnata).</p>`,
},
"dl.lateZibo": {
t: "Scadute (data ZIBO)",
b: `<p>Righe la cui <b>settimana ZIBO è finita</b> senza consegna: sono i ritardi veri verso il cliente.</p>
<p class="sh-note">Cosa fare: sono la priorità. Clic sul box per vederle tutte.</p>`,
},
"dl.lateClient": {
t: "Oltre data cliente",
b: `<p>Righe dove è superata la <b>data desiderata dal cliente</b>. Non sono necessariamente in ritardo per noi, ma il cliente potrebbe sollecitare.</p>`,
},
"dl.next7": {
t: "Prossimi 7 giorni",
b: `<p>Righe da consegnare da oggi ai prossimi 7 giorni. Clic per vederle.</p>`,
},
"dl.nodate": {
t: "Senza data",
b: `<p>Righe senza nessuna data di consegna in Mago.</p>
<p class="sh-note">Cosa fare: vanno completate in Mago, altrimenti non si possono pianificare.</p>`,
},
"dl.weekly": {
t: "Carico consegne per settimana",
b: `<p>Quanto c'è da consegnare settimana per settimana (per data ZIBO; se manca, data cliente). La prima barra rossa raccoglie tutto lo scaduto.</p>
<p class="sh-note">Serve a vedere le settimane troppo cariche. Clic su una barra per filtrare quella settimana.</p>`,
},
"dl.lateCust": {
t: "Clienti con più ritardo",
b: `<p>I clienti con più valore <b>scaduto</b> (data ZIBO superata). Clic per vedere solo le loro righe.</p>
<p class="sh-note">Utile per sapere chi avvisare per primo.</p>`,
},
"dl.rows": {
t: "Righe da consegnare",
b: `<p>Ogni riga: ordine, cliente, articolo, quantità ancora da consegnare, valore e date.</p>
<ul>
<li><b>ZIBO sett.</b> = settimana comunicata: rossa quando è finita, <span class="sh-chip sh-amber">IN SETTIMANA</span> mentre è in corso.</li>
<li><b>Cliente</b> = data desiderata dal cliente (arancione se superata).</li>
</ul>
<p class="sh-note">Pulsante Excel per scaricare l'elenco filtrato.</p>`,
},
/* ===================== SCHEDA CLIENTE ===================== */
"sc.status": {
t: "Stato del cliente",
b: `<p>Calcolato sul suo <b>ritmo d'ordine</b> degli ultimi 3 anni:</p>
<ul>
<li><span class="sh-chip sh-green">Cliente attivo</span> ordina con il suo ritmo normale.</li>
<li><span class="sh-chip sh-yellow">Attenzione</span> sta tardando (1,5 volte il suo solito).</li>
<li><span class="sh-chip sh-orange">Dormiente</span> 2 volte il suo solito: da chiamare.</li>
<li><span class="sh-chip sh-red">Probabilmente perso</span> 4 volte o più di un anno senza ordini.</li>
<li><span class="sh-chip sh-grey">Ordini occasionali</span> troppo pochi ordini per stimare un ritmo.</li>
</ul>`,
},
"sc.inv": {
t: "Fatturato dell'anno",
b: `<p>Fatturato del cliente da gennaio <b>ad oggi</b>, confrontato con lo stesso periodo dell'anno scorso. Sotto: l'anno scorso intero.</p>`,
},
"sc.ord": {
t: "Ordinato dell'anno",
b: `<p>Ordini ricevuti dal cliente da gennaio <b>ad oggi</b>, confrontati con lo stesso periodo dell'anno scorso.</p>
<p class="sh-note">Ordinato in calo e fatturato ancora alto = il fatturato calerà nei prossimi mesi.</p>`,
},
"sc.open": {
t: "Da consegnare",
b: `<p>Valore di quello che gli dobbiamo ancora consegnare e quante righe sono <b>in ritardo</b> (data ZIBO superata).</p>
<p class="sh-note">Prima di chiamarlo, guarda la scheda "Da consegnare" qui sotto.</p>`,
},
"sc.cn": {
t: "Note di credito",
b: `<p>Note di credito degli ultimi 12 mesi e quanto pesano sul fatturato. Diventa rosso dal 3%.</p>
<p class="sh-note">Una percentuale alta indica resi, contestazioni o problemi di qualità ricorrenti.</p>`,
},
"sc.years": {
t: "Ordinato e fatturato per anno",
b: `<p>Come è cresciuto (o calato) il cliente negli anni. L'anno in corso è <b>ad oggi</b>, quindi più basso finché l'anno non finisce.</p>`,
},
"sc.months": {
t: "Ultimi 24 mesi",
b: `<p>Ordini (viola) e fatture (verde) mese per mese: mostra se il cliente ordina con regolarità o a picchi, e se si sta fermando.</p>`,
},
"sc.tables": {
t: "Le tabelle",
b: `<ul>
<li><b>Da consegnare</b>: righe aperte con quantità mancante e date (ZIBO e cliente). Righe molto vecchie spesso sono da chiudere in Mago.</li>
<li><b>Ordini</b>: gli ordini del cliente; clic sul numero per aprirlo.</li>
<li><b>Articoli</b>: cosa compra, quanto, e il <b>prezzo medio</b> degli ultimi 12 mesi rispetto ai 12 precedenti: utile per verificare gli aumenti di listino.</li>
<li><b>Fatture</b>: fatture, acconti e note di credito degli ultimi 3 anni.</li>
</ul>
<p class="sh-note">Ogni tabella ha il suo pulsante Excel.</p>`,
},
};
/* ===================== STILE ===================== */
const CSS = `
.sh-btn{border:0;background:transparent;color:#94a3b8;padding:0 3px;margin-left:4px;font-size:.92em;line-height:1;cursor:pointer;vertical-align:baseline;text-transform:none;letter-spacing:0}
.sh-btn:hover,.sh-btn.open{color:#198754}
.sh-page{border:1px solid #d1fae5;background:#f0fdf4;color:#166534;border-radius:999px;padding:6px 14px;font-weight:700;font-size:.88rem;cursor:pointer;white-space:nowrap}
.sh-page:hover{background:#dcfce7}
.sh-pop{position:absolute;z-index:2000;width:340px;max-width:calc(100vw - 24px);background:#fff;border:1px solid #e2e8f0;border-radius:14px;
box-shadow:0 18px 40px rgba(15,23,42,.18);padding:14px 16px 12px;font-size:.9rem;color:#1f2d3d;line-height:1.45;text-transform:none;letter-spacing:0;font-weight:400}
.sh-pop.wide{width:460px}
.sh-pop h6{font-weight:800;font-size:.98rem;margin:0 26px 8px 0;display:flex;align-items:center;gap:8px}
.sh-pop h6 i{color:#198754}
.sh-pop p{margin:0 0 8px}
.sh-pop ul{margin:0 0 8px;padding-left:18px}
.sh-pop li{margin-bottom:4px}
.sh-pop .sh-note{background:#f0fdf4;border-left:3px solid #22c55e;padding:6px 10px;border-radius:6px;color:#14532d;margin:8px 0 0}
.sh-pop .sh-x{position:absolute;right:8px;top:8px;border:0;background:transparent;color:#94a3b8;font-size:1.1rem;cursor:pointer;line-height:1;padding:4px}
.sh-pop .sh-x:hover{color:#1f2d3d}
.sh-chip{display:inline-block;font-size:.72rem;font-weight:800;border-radius:999px;padding:1px 8px;white-space:nowrap}
.sh-red{background:#fee2e2;color:#991b1b}.sh-orange{background:#ffedd5;color:#9a3412}.sh-amber{background:#fef3c7;color:#b45309}
.sh-yellow{background:#fef9c3;color:#854d0e}.sh-green{background:#dcfce7;color:#166534}.sh-grey{background:#e2e8f0;color:#334155}`;
function injectCss() {
if (document.getElementById("sales-help-css")) return;
const st = document.createElement("style");
st.id = "sales-help-css";
st.textContent = CSS;
document.head.appendChild(st);
}
/* ===================== POPOVER ===================== */
let pop = null,
popBtn = null;
function close() {
if (pop) pop.remove();
if (popBtn) popBtn.classList.remove("open");
pop = null;
popBtn = null;
}
function open(btn, key, wide) {
const h = SALES_HELP[key];
if (!h) return;
if (popBtn === btn) {
close();
return;
}
close();
pop = document.createElement("div");
pop.className = "sh-pop" + (wide ? " wide" : "");
pop.setAttribute("role", "dialog");
pop.innerHTML = `<button type="button" class="sh-x" aria-label="Chiudi">&times;</button>
<h6><i class="fa-solid fa-circle-info"></i>${h.t}</h6>${h.b}`;
document.body.appendChild(pop);
popBtn = btn;
btn.classList.add("open");
// posizione: sotto l'icona, dentro lo schermo
const r = btn.getBoundingClientRect();
const pw = pop.offsetWidth,
ph = pop.offsetHeight;
let left = r.left + window.scrollX - 12;
left = Math.max(
window.scrollX + 12,
Math.min(
left,
window.scrollX + document.documentElement.clientWidth - pw - 12,
),
);
let top = r.bottom + window.scrollY + 8;
if (r.bottom + ph + 16 > window.innerHeight && r.top - ph - 8 > 0)
top = r.top + window.scrollY - ph - 8;
pop.style.left = left + "px";
pop.style.top = top + "px";
pop.querySelector(".sh-x").addEventListener("click", close);
}
/* ===================== ICONE ⓘ ===================== */
function decorate(root) {
// controllo il figlio (non un attributo): se la pagina riscrive il titolo con .text() l'icona viene rimessa
(root || document).querySelectorAll("[data-help]").forEach((el) => {
if (el.querySelector(":scope > .sh-btn")) return;
const b = document.createElement("button");
b.type = "button";
b.className = "sh-btn";
b.title = "Cosa vedo qui?";
b.setAttribute("aria-label", "Aiuto");
b.dataset.k = el.getAttribute("data-help");
b.innerHTML = '<i class="fa-solid fa-circle-info"></i>';
el.appendChild(b);
});
}
document.addEventListener(
"click",
function (e) {
const b = e.target.closest(".sh-btn");
if (b) {
// non far scattare il click del box/riga (filtri, ordinamento...)
e.preventDefault();
e.stopPropagation();
open(b, b.dataset.k, false);
return;
}
const p = e.target.closest("[data-help-open]");
if (p) {
e.preventDefault();
open(p, p.getAttribute("data-help-open"), true);
return;
}
if (pop && !e.target.closest(".sh-pop")) close();
},
true,
);
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") close();
});
window.addEventListener("resize", close);
function start() {
injectCss();
decorate(document);
// elementi disegnati dopo dal JavaScript della pagina
new MutationObserver((muts) => {
for (const m of muts) {
if (m.addedNodes.length) {
decorate(document);
break;
}
}
}).observe(document.body, {
childList: true,
subtree: true,
});
}
if (document.readyState === "loading")
document.addEventListener("DOMContentLoaded", start);
else start();
window.SALES_HELP = SALES_HELP;
})();