getConnection(); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // --- Permessi: pagina visibile solo con 'sales.deliveries.view' --- $canStats = userCan('sales.stats.view'); // per i tab e il link al dettaglio ordine $canDeliveries = userCan('sales.deliveries.view'); if (!$canDeliveries) { if (isset($_GET['action']) || isset($_POST['action'])) { MagoSalesStats::jsonOut(['success' => false, 'ok' => false, 'message' => 'Non hai i permessi per questa pagina']); } while (ob_get_level()) ob_end_clean(); http_response_code(403); echo '

Accesso non consentito

Non hai i permessi per visualizzare questa pagina.

Torna alla Dashboard
'; exit; } /* ============================================================ * AJAX * ============================================================ */ /** Filtri della pagina Consegne applicati alla vista righe aperte (alias r). */ function deliveriesWhere() { // cliente / agente / area dalla classe comune (scritti su x.) → riportati su r. [$w, $p] = MagoSalesStats::buildWhere(['from' => '', 'to' => '']); $w = preg_replace('/\bx\./', 'r.', $w); $items = MagoSalesStats::arrParam('items'); if ($items) { $ph = []; foreach ($items as $i => $v) { $ph[] = ':it' . $i; $p['it' . $i] = $v; } $w .= ' AND r.item IN (' . implode(',', $ph) . ')'; } $horizons = [ 'late_zibo' => 'r.due_date < CURDATE()', 'late_client' => 'r.client_date < CURDATE()', 'week' => 'r.due_date >= CURDATE() AND YEARWEEK(r.due_date, 3) = YEARWEEK(CURDATE(), 3)', 'next_week' => 'YEARWEEK(r.due_date, 3) = YEARWEEK(CURDATE() + INTERVAL 7 DAY, 3)', '7d' => 'r.due_date >= CURDATE() AND r.due_date <= CURDATE() + INTERVAL 7 DAY', '30d' => 'r.due_date >= CURDATE() AND r.due_date <= CURDATE() + INTERVAL 30 DAY', 'nodate' => 'r.due_date IS NULL', ]; $h = $_GET['horizon'] ?? ''; if (isset($horizons[$h])) $w .= ' AND ' . $horizons[$h]; $q = trim((string)($_GET['search'] ?? '')); if ($q !== '') { $w .= ' AND (r.internal_ord_no LIKE :s1 OR r.company_name LIKE :s2 OR r.customer LIKE :s3 OR r.item LIKE :s4 OR r.description LIKE :s5 OR r.your_reference LIKE :s6)'; $like = '%' . $q . '%'; foreach (['s1', 's2', 's3', 's4', 's5', 's6'] as $k) $p[$k] = $like; } return [$w, $p]; } $action = $_GET['action'] ?? ''; if ($action === 'filters') { $opts = MagoSalesStats::filterOptions($pdo); try { $opts['items'] = $pdo->query(" SELECT item AS code, MAX(description) AS name, COUNT(*) AS n FROM mago_sale_ord_detail WHERE delivered = 0 AND cancelled = 0 AND item <> '' GROUP BY item ORDER BY item ")->fetchAll(PDO::FETCH_ASSOC); } catch (Throwable $e) { $opts['items'] = []; } MagoSalesStats::jsonOut($opts); } if ($action === 'data') { try { $from = MagoSalesStats::openLinesFrom(); [$where, $params] = deliveriesWhere(); $kpi = MagoSalesStats::fetchAllQ($pdo, " SELECT COUNT(*) AS n_lines, COUNT(DISTINCT r.sale_ord_id) AS orders, COALESCE(SUM(r.residual_value), 0) AS value, SUM(r.due_date < CURDATE()) AS late_lines, COALESCE(SUM(CASE WHEN r.due_date < CURDATE() THEN r.residual_value END), 0) AS late_value, SUM(r.client_date < CURDATE()) AS late_client_lines, COALESCE(SUM(CASE WHEN r.client_date < CURDATE() THEN r.residual_value END), 0) AS late_client_value, SUM(r.due_date >= CURDATE() AND r.due_date <= CURDATE() + INTERVAL 7 DAY) AS due7_lines, COALESCE(SUM(CASE WHEN r.due_date >= CURDATE() AND r.due_date <= CURDATE() + INTERVAL 7 DAY THEN r.residual_value END), 0) AS due7_value, SUM(r.due_date IS NULL) AS nodate_lines, AVG(CASE WHEN r.due_date < CURDATE() THEN DATEDIFF(CURDATE(), r.due_date) END) AS avg_late_days, SUM(r.zibo_date IS NULL) AS no_zibo_lines FROM $from WHERE $where ", $params)[0]; // Carico per settimana (data ZIBO, se manca data cliente): scaduto + prossime 12 settimane + oltre + senza data $weekly = MagoSalesStats::fetchAllQ($pdo, " SELECT CASE WHEN r.due_date IS NULL THEN 'nd' WHEN r.due_date < CURDATE() THEN 'late' WHEN r.due_date >= (CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY) + INTERVAL 12 WEEK THEN 'over' ELSE DATE_FORMAT(r.due_date - INTERVAL WEEKDAY(r.due_date) DAY, '%Y-%m-%d') END AS wk, COUNT(*) AS n, COALESCE(SUM(r.residual_value), 0) AS v FROM $from WHERE $where GROUP BY wk ", $params); // Clienti con più ritardo (data ZIBO) $lateCustomers = MagoSalesStats::fetchAllQ($pdo, " SELECT r.customer AS code, r.company_name AS name, COUNT(*) AS n, COALESCE(SUM(r.residual_value), 0) AS v FROM $from WHERE $where AND r.due_date < CURDATE() GROUP BY r.customer, r.company_name ORDER BY v DESC LIMIT 10 ", $params); $rows = MagoSalesStats::fetchAllQ($pdo, " SELECT r.sale_ord_id, r.internal_ord_no, r.order_date, r.customer, r.company_name, r.item, r.description, r.uom, r.qty, r.delivered_qty, r.residual_qty, r.residual_value, r.zibo_date, r.client_date, r.due_date, r.salesperson, r.status, CASE WHEN r.due_date < CURDATE() THEN DATEDIFF(CURDATE(), r.due_date) ELSE 0 END AS late_days, CASE WHEN r.due_date >= CURDATE() THEN DATEDIFF(r.due_date, CURDATE()) END AS days_left FROM $from WHERE $where ORDER BY (r.due_date IS NULL), r.due_date, r.internal_ord_no, r.line LIMIT 5000 ", $params); MagoSalesStats::jsonOut([ 'success' => true, 'today' => date('Y-m-d'), 'kpi' => $kpi, 'weekly' => $weekly, 'late_customers' => $lateCustomers, 'rows' => $rows, ]); } catch (Throwable $e) { MagoSalesStats::jsonOut(['success' => false, 'message' => $e->getMessage()]); } } ?> Consegne - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?>
Statistiche Ordini Cliente
Dati Mago4
Scadenza
Data ZIBO = settimana di consegna comunicata (rossa a settimana finita) Data cliente = desiderata (arancione se superata)
Da consegnare
—
 
Scadute (data ZIBO)
—
 
Oltre data cliente
—
 
Prossimi 7 giorni
—
 
Senza data
—
righe senza data di consegna
Carico consegne per settimana
Per data ZIBO (se manca: data cliente) · clicca una barra per filtrare
Clienti con più ritardo
Valore residuo scaduto (data ZIBO) · clicca per filtrare
Righe da consegnare
Ordinate per scadenza
Ordine Cliente Articolo Residuo Consegna (ZIBO / cliente) Ritardo Valore residuo Agente