added tips to statistics

This commit is contained in:
2026-10-15 12:03:40 +02:00
parent abd09769f2
commit b52e7191cf
5 changed files with 549 additions and 59 deletions
+32 -22
View File
@@ -757,6 +757,7 @@ if ($action === 'data') {
background: none;
border: 0;
padding: 0;
cursor: pointer;
font-weight: 800;
color: var(--c-ink);
text-align: left;
@@ -979,6 +980,7 @@ if ($action === 'data') {
<?php if (userCan('sales.deliveries.view')) : ?>
<a href="sales_orders_deliveries.php"><i class="fa-solid fa-truck-fast me-1"></i> Consegne</a>
<?php endif; ?>
<button type="button" class="sh-page ms-auto align-self-center mb-1" data-help-open="page.years"><i class="fa-regular fa-circle-question me-1"></i> Come si legge</button>
</div>
<!-- FILTRI -->
@@ -991,7 +993,7 @@ if ($action === 'data') {
<div class="col-12 col-xl-6 d-flex gap-2 flex-wrap justify-content-xl-end">
<label class="ytd-switch" for="ytdToggle" title="Ogni anno viene considerato solo fino al giorno di oggi, per confronti equi con l'anno in corso">
<input class="form-check-input" type="checkbox" role="switch" id="ytdToggle" checked>
<span id="ytdLabel">A pari data</span>
<span id="ytdLabel" data-help="yr.ytd">A pari data</span>
</label>
<div class="metric-switch" id="metricSwitch">
<button type="button" data-metric="value" class="active">€ Valore</button>
@@ -1033,30 +1035,31 @@ if ($action === 'data') {
<!-- RIEPILOGO ANNI -->
<!-- CRUSCOTTO DIREZIONE: situazione ad oggi -->
<div class="dash-head">
<span><i class="fa-solid fa-gauge-high me-2"></i>Situazione ad oggi</span>
<span data-help="yr.dash"><i class="fa-solid fa-gauge-high me-2"></i>Situazione ad oggi</span>
<small>non dipende dagli anni scelti · segue i filtri cliente, agente e area</small>
</div>
<div class="dash-grid mb-3" id="dashCards"></div>
<div class="chart-card mb-4">
<div class="chart-title">Ordinato vs fatturato · ultimi 24 mesi</div>
<div class="chart-title" data-help="yr.b2bchart">Ordinato vs fatturato · ultimi 24 mesi</div>
<div class="chart-hint">Barre: valori del mese · linea: book-to-bill su 3 mesi (ordinato ÷ fatturato: sopra 1 il portafoglio cresce, sotto 1 si consuma)</div>
<div id="chB2B" style="min-height:320px;"></div>
</div>
<div class="dash-head"><span data-help="yr.cards"><i class="fa-solid fa-layer-group me-2"></i>Anni a confronto</span></div>
<div class="year-grid mb-4" id="yearCards"></div>
<!-- GRAFICI -->
<div class="row g-3 mb-3">
<div class="col-xl-6">
<div class="chart-card">
<div class="chart-title" id="ttlMonthly">Andamento mensile</div>
<div class="chart-title" id="ttlMonthly" data-help="yr.monthly">Andamento mensile</div>
<div class="chart-hint">Stagionalità: un colore per anno</div>
<div id="chMonthly" style="min-height:340px;"></div>
</div>
</div>
<div class="col-xl-6">
<div class="chart-card">
<div class="chart-title" id="ttlCumul">Progressivo dell'anno</div>
<div class="chart-title" id="ttlCumul" data-help="yr.cumul">Progressivo dell'anno</div>
<div class="chart-hint">Somma da gennaio: dice se si è avanti o indietro rispetto agli anni scorsi</div>
<div id="chCumul" style="min-height:340px;"></div>
</div>
@@ -1067,14 +1070,14 @@ if ($action === 'data') {
<div class="row g-3 mb-3" id="invRow">
<div class="col-xl-6">
<div class="chart-card">
<div class="chart-title">Fatturato per mese</div>
<div class="chart-title" data-help="yr.invMonthly">Fatturato per mese</div>
<div class="chart-hint">Imponibile fatture + acconti − note di credito, per data fattura</div>
<div id="chInvMonthly" style="min-height:340px;"></div>
</div>
</div>
<div class="col-xl-6">
<div class="chart-card">
<div class="chart-title">Fatturato progressivo dell'anno</div>
<div class="chart-title" data-help="yr.invCumul">Fatturato progressivo dell'anno</div>
<div class="chart-hint">Somma da gennaio del fatturato, anno su anno</div>
<div id="chInvCumul" style="min-height:340px;"></div>
</div>
@@ -1083,11 +1086,11 @@ if ($action === 'data') {
<div class="warn-strip mb-3" id="invMissing" style="display:none;"></div>
<div class="chart-card mb-3" id="invTableCard">
<button type="button" class="inv-toggle" id="invToggle" aria-expanded="false">
<span><i class="fa-solid fa-table me-2"></i>Tabella dati fatturato</span>
<div class="inv-toggle" id="invToggle" role="button" tabindex="0" aria-expanded="false">
<span data-help="yr.invTable"><i class="fa-solid fa-table me-2"></i>Tabella dati fatturato</span>
<span class="small text-muted d-none d-md-inline">per mese e documenti · esportabile in Excel</span>
<i class="fa-solid fa-chevron-down inv-chev"></i>
</button>
</div>
<div id="invTableBody" style="display:none;">
<div class="metric-switch my-3" id="invTabs">
<button type="button" data-tab="months" class="active"><i class="fa-regular fa-calendar me-1"></i> Per mese</button>
@@ -1110,7 +1113,7 @@ if ($action === 'data') {
<div class="chart-card mb-3" id="dormCard">
<div class="d-flex justify-content-between align-items-start flex-wrap gap-2 mb-2">
<div>
<div class="chart-title"><i class="fa-solid fa-phone-volume me-2" style="color:#c2410c;"></i>Clienti da richiamare</div>
<div class="chart-title" data-help="yr.dormant"><i class="fa-solid fa-phone-volume me-2" style="color:#c2410c;"></i>Clienti da richiamare</div>
<div class="chart-hint" id="dormHint">&nbsp;</div>
</div>
<div class="chip-row" id="dormChips">
@@ -1130,7 +1133,7 @@ if ($action === 'data') {
<div class="chart-card">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-2">
<div>
<div class="chart-title" id="ttlCust">Clienti a confronto</div>
<div class="chart-title" id="ttlCust" data-help="yr.custcmp">Clienti a confronto</div>
<div class="chart-hint" id="custHint">Clicca un cliente per filtrare tutta la pagina</div>
</div>
<div class="chip-row" id="trendChips">
@@ -1564,7 +1567,7 @@ if ($action === 'data') {
cards.push(`
<div class="dash-card" style="--k:#1d4ed8;" title="Valore residuo delle righe d'ordine ancora da consegnare">
<div class="ico"><i class="fa-solid fa-boxes-stacked"></i></div>
<div class="lbl">Portafoglio da consegnare</div>
<div class="lbl" data-help="yr.backlog">Portafoglio da consegnare</div>
<div class="big">${fmtEurShort(+b.v || 0)}</div>
<div class="sub">${fmtNum(b.n_lines || 0)} righe · ${fmtNum(b.n_orders || 0)} ordini${weeks !== null ? `<br>≈ <b>${fmtNum(Math.round(weeks))} settimane</b> di ${invOk ? 'fatturato' : 'ordinato'} medio` : ''}${+b.late_v > 0 ? `<br><span class="delta-down">${fmtEurShort(+b.late_v)}</span> già oltre data ZIBO` : ''}</div>
</div>`);
@@ -1577,36 +1580,36 @@ if ($action === 'data') {
cards.push(`
<div class="dash-card" style="--k:${cls === 'up' ? '#15803d' : (cls === 'down' ? '#b02a37' : '#b45309')};" title="Ordinato ÷ fatturato negli ultimi 90 giorni">
<div class="ico"><i class="fa-solid fa-scale-balanced"></i></div>
<div class="lbl">Book-to-bill · 90 gg</div>
<div class="lbl" data-help="yr.b2b">Book-to-bill · 90 gg</div>
<div class="big">${r.toLocaleString('it-IT', {minimumFractionDigits: 2, maximumFractionDigits: 2})}<span class="b2b-pill ${cls}">${lbl}</span></div>
<div class="sub">Ordinato <b>${fmtEurShort(x.ordered_90)}</b> · fatturato <b>${fmtEurShort(x.invoiced_90)}</b></div>
</div>`);
} else {
cards.push(dashNa('Book-to-bill · 90 gg', 'fa-scale-balanced', invOk ? 'nessun fatturato negli ultimi 90 giorni' : 'serve la sincronizzazione delle fatture'));
cards.push(dashNa('Book-to-bill · 90 gg', 'fa-scale-balanced', 'yr.b2b', invOk ? 'nessun fatturato negli ultimi 90 giorni' : 'serve la sincronizzazione delle fatture'));
}
// 3-4) previsioni di fine anno
cards.push(forecastCard('Previsione fatturato ' + CUR_Y, 'fa-file-invoice-dollar', '#0f766e', invOk ? x.invoiced_forecast : null, invOk ? '' : 'serve la sincronizzazione delle fatture'));
cards.push(forecastCard('Previsione ordinato ' + CUR_Y, 'fa-chart-line', '#6f42c1', x.ordered_forecast, ''));
cards.push(forecastCard('Previsione fatturato ' + CUR_Y, 'fa-file-invoice-dollar', '#0f766e', 'yr.fcInv', invOk ? x.invoiced_forecast : null, invOk ? '' : 'serve la sincronizzazione delle fatture'));
cards.push(forecastCard('Previsione ordinato ' + CUR_Y, 'fa-chart-line', '#6f42c1', 'yr.fcOrd', x.ordered_forecast, ''));
$('#dashCards').html(cards.join(''));
renderB2BChart(x);
}
function dashNa(label, icon, msg) {
function dashNa(label, icon, help, msg) {
return `<div class="dash-card" style="--k:#64748b;"><div class="ico"><i class="fa-solid ${icon}"></i></div>
<div class="lbl">${label}</div><div class="big">—</div><div class="sub">${esc(msg)}</div></div>`;
<div class="lbl" data-help="${help}">${label}</div><div class="big">—</div><div class="sub">${esc(msg)}</div></div>`;
}
function forecastCard(label, icon, color, f, naMsg) {
function forecastCard(label, icon, color, help, f, naMsg) {
if (!f || f.forecast === null || f.forecast === undefined) {
return dashNa(label, icon, naMsg || 'servono dati degli anni precedenti');
return dashNa(label, icon, help, naMsg || 'servono dati degli anni precedenti');
}
const vsPrev = f.prev_full ? pct(f.forecast, f.prev_full) : null;
return `
<div class="dash-card" style="--k:${color};" title="Ad oggi ${esc(fmtEur(f.ytd))}: negli anni ${f.years.join(', ')} a questa data si era in media al ${String(f.share).replace('.', ',')}% dell'anno">
<div class="ico"><i class="fa-solid ${icon}"></i></div>
<div class="lbl">${label}</div>
<div class="lbl" data-help="${help}">${label}</div>
<div class="big">${fmtEurShort(f.forecast)}</div>
<div class="sub">forbice ${fmtEurShort(f.low)} – ${fmtEurShort(f.high)}<br>
${f.prev_full ? `${CUR_Y - 1}: ${fmtEurShort(f.prev_full)} ${deltaSpan(vsPrev, '')}` : ''}<br>
@@ -2320,6 +2323,12 @@ if ($action === 'data') {
}));
} catch (e) {}
});
$('#invToggle').on('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
$(this).trigger('click');
}
});
$('#invTabs').on('click', 'button', function() {
invTab = $(this).data('tab');
$('#invTabs button').removeClass('active');
@@ -2378,6 +2387,7 @@ if ($action === 'data') {
});
})();
</script>
<script src="sales_help.js?v=1"></script>
</body>
</html>