diff --git a/public/sommario.php b/public/sommario.php index 915f31b..07e011f 100644 --- a/public/sommario.php +++ b/public/sommario.php @@ -254,6 +254,27 @@ function abbonati(PDO $pdo, string $data): int WHERE iduser IS NOT NULL AND order_date_created <= ? AND expireon >= ?", [$data, $data]); } $abbOggi = abbonati($pdo, date('Y-m-d')); + +// Numeri di andamento (senza giudizio) +$ultimoAnno = q($pdo, "SELECT COALESCE(SUM(nticket), 0) AS lezioni, COUNT(*) AS ordini + FROM orderbook WHERE order_date_created > DATE_SUB(CURDATE(), INTERVAL 12 MONTH)")[0]; +$nuoviAnno = (int) q1($pdo, "SELECT COUNT(*) FROM (SELECT iduser, MIN(order_date_created) AS primo FROM orderbook + WHERE iduser IS NOT NULL GROUP BY iduser) t WHERE t.primo > DATE_SUB(CURDATE(), INTERVAL 12 MONTH)"); +$mesiDati = max(1, min(12, (int) ceil((time() - strtotime((string) (q1($pdo, "SELECT MIN(order_date_created) FROM orderbook") ?: date('Y-m-d')))) / (86400 * 30.4)))); +$mesiPeriodo = $giorni / 30.4; + +// Lezioni ancora da fare nei pacchetti validi oggi = riempimento "già venduto" delle prossime settimane +$portafoglio = (int) q1($pdo, "SELECT COALESCE(SUM(GREATEST(o.nticket - (SELECT COUNT(*) FROM bookingclass bc + WHERE bc.idorder = o.idorderbook AND bc.status NOT IN ('cancelled', 'waiting') + AND bc.bookingstart <= NOW()), 0)), 0) + FROM orderbook o WHERE o.expireon >= CURDATE() AND o.nticket > 0"); + +$info = [ + ['fa-ticket-alt', 'Lezioni vendute', n0($A['vendute']), n0($A['ordini']) . ' ordini · media ultimo anno: ' . n0((int) $ultimoAnno['lezioni'] / $mesiDati * $mesiPeriodo) . ' in un periodo così'], + ['fa-user-plus', 'Nuovi clienti', n0($A['nuovi']), 'media ultimo anno: ' . number_format($nuoviAnno / $mesiDati, 1, ',', '.') . ' al mese'], + ['fa-users', 'Persone in sala', n0($A['persone']), 'almeno una lezione frequentata nel periodo'], + ['fa-layer-group', 'Lezioni già vendute da fare', n0($portafoglio), 'nei pacchetti validi oggi: è il riempimento delle prossime settimane'], +]; $abbPrima = $haAnnoPrima ? abbonati($pdo, date('Y-m-d', strtotime('-1 year'))) : abbonati($pdo, substr($d1, 0, 10)); // --- Certificati (situazione di oggi) @@ -333,50 +354,14 @@ $add( 'con un pacchetto valido oggi' ); -// 3. Lezioni vendute -$add( - 'Lezioni vendute', - 'fa-ticket-alt', - n0($A['vendute']), - $trendStato($A['vendute'], $Y['vendute']), - $conf($A['vendute'], $Y['vendute'], '', false, $etichettaY), - [ - 'Le vendite tengono o crescono rispetto al ' . $etichettaY . '.', - 'Vendite in calo: una comunicazione o un\'offerta a chi ha il pacchetto in scadenza può aiutare.', - 'Vendite in forte calo: serve un\'azione commerciale (promozione, evento, newsletter).', - ], - n0($A['ordini']) . ' ordini da ' . n0($A['clienti']) . ' clienti' -); - -// 3. Nuovi clienti -$add( - 'Nuovi clienti', - 'fa-user-plus', - n0($A['nuovi']), - $trendStato($A['nuovi'], $Y['nuovi']), - $conf($A['nuovi'], $Y['nuovi'], '', false, $etichettaY), - [ - 'Arrivano persone nuove: la scuola si fa conoscere.', - 'Meno nuovi ingressi del solito: spingi lezioni di prova e passaparola.', - 'Pochi nuovi clienti: punta su prova gratuita, social ed eventi aperti.', - ], - 'primo acquisto nel periodo' -); - -// 4. Persone attive -$add( - 'Persone che praticano', - 'fa-users', - n0($A['persone']), - $trendStato($A['persone'], $Y['persone']), - $conf($A['persone'], $Y['persone'], '', false, $etichettaY), - [ - 'La comunità che pratica è stabile o in crescita.', - 'Meno persone in sala rispetto al ' . $etichettaY . ': contatta chi non viene da un po\'.', - 'Calo forte di persone attive: verifica abbandoni e pacchetti non rinnovati.', - ], - 'almeno una lezione frequentata' -); +/* + * Vendite, nuovi clienti e persone in sala NON hanno il semaforo: + * con pacchetti da 12 lezioni (circa 3 mesi) chi compra non riordina per mesi, + * quindi le vendite di un periodo salgono e scendono a ondate anche se la scuola va bene, + * e in un bacino di paese i nuovi clienti sono pochi per natura. + * Li mostriamo come numeri di andamento (con la media mensile dell'ultimo anno come riferimento). + * Lo stato di salute lo danno "Abbonati attivi" e "Clienti che rinnovano". + */ // 5. Riacquisto $add( @@ -919,6 +904,38 @@ $prevTxt = $inizioP->format('d/m/Y') . ' – ' . (clone $inizio)->modify('-1 color: var(--ink); } + .sm-info-head { + font-size: 15px; + font-weight: 800; + color: #1f2937; + margin: 4px 0 12px; + } + + .sm-info-head small { + display: block; + font-weight: 400; + font-size: 12px; + color: var(--muted); + margin-top: 2px; + } + + .sm-info { + padding: 14px 16px; + display: flex; + gap: 12px; + height: 100%; + --c: #2980b9; + --bg: #e8f1fa; + } + + .sm-info .sm-ind-val { + font-size: 22px; + } + + .sm-info .sm-ind-det { + margin-top: 2px; + } + .sm-foot { font-size: 12px; color: var(--muted); @@ -1042,6 +1059,23 @@ $prevTxt = $inizioP->format('d/m/Y') . ' – ' . (clone $inizio)->modify('-1 + +