332 lines
15 KiB
PHP

<?php
include('include/headscript.php');
if (!isset($iduserlogin)) die("Errore: utente non loggato.");
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
$stmt = $pdo->prepare("SELECT id, name FROM schools WHERE owner_id = ?");
$stmt->execute([$iduserlogin]);
$school = $stmt->fetch();
if (!$school) die("Scuola non trovata.");
$school_id = $school['id'];
// === FILTRI ===
$year = $_GET['year'] ?? date('Y');
$month = $_GET['month'] ?? null;
$start_date = $month ? "$year-$month-01" : "$year-01-01";
$end_date = $month ? date('Y-m-t', strtotime($start_date)) : "$year-12-31";
$where_date = "AND o.created_at BETWEEN ? AND ?";
$params = [$school_id, $start_date . ' 00:00:00', $end_date . ' 23:59:59'];
// === STATISTICHE FILTRATE ===
$stmt = $pdo->prepare("
SELECT
COUNT(*) as total_orders,
SUM(price) as total_revenue,
SUM(CASE WHEN payment_method = 'stripe' THEN price ELSE 0 END) as stripe_revenue,
SUM(CASE WHEN payment_method = 'paypal' THEN price ELSE 0 END) as paypal_revenue,
SUM(CASE WHEN payment_method = 'manual' THEN price ELSE 0 END) as manual_revenue
FROM orders o
WHERE o.school_id = ? AND o.status = 'completed' $where_date
");
$stmt->execute($params);
$stats = $stmt->fetch();
// === RICAVI MENSILI (per grafico) ===
$monthly = [];
$start = new DateTime($month ? $start_date : "$year-01-01");
$end = new DateTime($end_date);
$interval = new DateInterval('P1M');
$period = new DatePeriod($start, $interval, $end->modify('+1 month'));
foreach ($period as $dt) {
$m = $dt->format('Y-m');
$label = $dt->format('M Y');
$stmt = $pdo->prepare("
SELECT COALESCE(SUM(price), 0) as revenue
FROM orders
WHERE school_id = ? AND status = 'completed'
AND DATE_FORMAT(created_at, '%Y-%m') = ?
");
$stmt->execute([$school_id, $m]);
$monthly[] = ['label' => $label, 'revenue' => (float)$stmt->fetchColumn()];
}
// === DISTRIBUZIONE METODI PAGAMENTO (per torta) ===
$payment_data = [
'Stripe' => $stats['stripe_revenue'] ?? 0,
'PayPal' => $stats['paypal_revenue'] ?? 0,
'Manuale' => $stats['manual_revenue'] ?? 0
];
// === TOP 5 PRODOTTI ===
$stmt = $pdo->prepare("
SELECT p.name, pv.name as variation, COUNT(*) as vendite, SUM(o.price) as incasso
FROM orders o
JOIN products p ON o.product_id = p.id
LEFT JOIN product_variations pv ON o.variation_id = pv.id
WHERE o.school_id = ? AND o.status = 'completed' $where_date
GROUP BY o.product_id, o.variation_id
ORDER BY incasso DESC LIMIT 5
");
$stmt->execute($params);
$top_products = $stmt->fetchAll();
// === ULTIMI ORDINI ===
$stmt = $pdo->prepare("
SELECT o.*, u.first_name, u.last_name, u.email, p.name as product_name, pv.name as variation_name
FROM orders o
JOIN auth_users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id
LEFT JOIN product_variations pv ON o.variation_id = pv.id
WHERE o.school_id = ? $where_date
ORDER BY o.created_at DESC
");
$stmt->execute($params);
$recent_orders = $stmt->fetchAll();
?>
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Finanze - <?php echo htmlspecialchars($school['name']); ?></title>
<?php include('cssinclude.php'); ?>
<?php include('siteinfo.php'); ?>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.7/css/dataTables.bootstrap5.min.css">
</head>
<body>
<div class="wrapper">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<div class="container-fluid px-4">
<!-- FILTRO -->
<div class="card radius-15 shadow mb-4">
<div class="card-body">
<form method="GET" class="row g-3 align-items-end">
<div class="col-md-3">
<label>Anno</label>
<select name="year" class="form-select" onchange="this.form.submit()">
<?php for ($y = date('Y'); $y >= date('Y') - 5; $y--): ?>
<option value="<?php echo $y; ?>" <?php echo $y == $year ? 'selected' : ''; ?>><?php echo $y; ?></option>
<?php endfor; ?>
</select>
</div>
<div class="col-md-3">
<label>Mese (opzionale)</label>
<select name="month" class="form-select" onchange="this.form.submit()">
<option value="">Tutti i mesi</option>
<?php for ($m = 1; $m <= 12; $m++):
$mm = str_pad($m, 2, '0', STR_PAD_LEFT);
$name = date('F', mktime(0, 0, 0, $m, 1));
?>
<option value="<?php echo $mm; ?>" <?php echo $mm == $month ? 'selected' : ''; ?>>
<?php echo ucfirst($name); ?>
</option>
<?php endfor; ?>
</select>
</div>
<div class="col-md-3">
<button type="button" class="btn btn-outline-secondary" onclick="window.location='finances.php'">Reset</button>
</div>
</form>
</div>
</div>
<!-- TOTALE FILTRATO -->
<div class="text-center mb-5">
<h2 class="text-primary">Finanze <?php echo $month ? date('F Y', strtotime("$year-$month-01")) : "Anno $year"; ?></h2>
<h1 class="display-3 fw-bold text-success">
€<?php echo number_format($stats['total_revenue'] ?? 0, 2); ?>
</h1>
</div>
<div class="row g-4 mb-5">
<div class="col-lg-4">
<div class="card h-100 shadow-sm border-0">
<div class="card-body text-center">
<h5 class="text-primary">Ordini</h5>
<h3 class="fw-bold"><?php echo $stats['total_orders'] ?? 0; ?></h3>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card h-100 shadow-sm border-0">
<div class="card-header bg-primary text-white">
<h5 class="mb-0">Distribuzione Pagamenti</h5>
</div>
<div class="card-body">
<canvas id="paymentChart"></canvas>
</div>
</div>
</div>
</div>
<div class="row g-4">
<div class="col-lg-8">
<div class="card shadow">
<div class="card-header bg-primary text-white">
<h5 class="mb-0">Andamento Ricavi</h5>
</div>
<div class="card-body">
<canvas id="revenueChart" height="120"></canvas>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card shadow h-100">
<div class="card-header bg-success text-white">
<h5 class="mb-0">Top 5 Prodotti</h5>
</div>
<div class="card-body">
<table class="table table-sm">
<tbody>
<?php foreach ($top_products as $tp): ?>
<tr>
<td>
<strong><?php echo htmlspecialchars($tp['name']); ?></strong>
<?php if ($tp['variation']): ?><br><small><?php echo htmlspecialchars($tp['variation']); ?></small><?php endif; ?>
</td>
<td class="text-end text-success fw-bold">
€<?php echo number_format($tp['incasso'], 2); ?>
</td>
</tr>
<?php endforeach; ?>
<?php if (empty($top_products)): ?>
<tr>
<td class="text-center text-muted">Nessun dato</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- TABELLA ORDINI -->
<div class="card shadow mt-5">
<div class="card-header bg-dark text-white">
<h5 class="mb-0">Tutti gli ordini del periodo</h5>
</div>
<div class="card-body p-0">
<table id="ordersTable" class="table table-striped table-hover mb-0">
<thead class="table-dark">
<tr>
<th>Data</th>
<th>Ordine</th>
<th>Cliente</th>
<th>Prodotto</th>
<th class="text-end">Importo</th>
<th>Metodo</th>
</tr>
</thead>
<tbody>
<?php foreach ($recent_orders as $o): ?>
<tr>
<td><?php echo date('d/m/Y H:i', strtotime($o['created_at'])); ?></td>
<td>#<?php echo $o['order_number']; ?></td>
<td><?php echo htmlspecialchars($o['first_name'] . ' ' . $o['last_name']); ?></td>
<td><?php echo htmlspecialchars($o['product_name'] . ($o['variation_name'] ? ' - ' . $o['variation_name'] : '')); ?></td>
<td class="text-end text-success fw-bold">€<?php echo number_format($o['price'], 2); ?></td>
<td>
<span class="badge bg-<?php echo $o['payment_method'] == 'stripe' ? 'primary' : ($o['payment_method'] == 'paypal' ? 'info' : 'secondary'); ?>">
<?php echo strtoupper($o['payment_method']); ?>
</span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<?php include('include/footer.php'); ?>
</div>
<?php include('jsinclude.php'); ?>
<script src="https://cdn.datatables.net/1.13.7/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.7/js/dataTables.bootstrap5.min.js"></script>
<script>
// Grafico a barre ricavi
new Chart(document.getElementById('revenueChart'), {
type: 'bar',
data: {
labels: [<?php echo "'" . implode("','", array_column($monthly, 'label')) . "'"; ?>],
datasets: [{
label: 'Ricavi',
data: [<?php echo implode(',', array_column($monthly, 'revenue')); ?>],
backgroundColor: 'rgba(0, 123, 255, 0.7)',
borderRadius: 6
}]
},
options: {
responsive: true,
plugins: {
legend: {
display: false
}
},
scales: {
y: {
ticks: {
callback: v => '€' + v
}
}
}
}
});
// Grafico a torta pagamenti
new Chart(document.getElementById('paymentChart'), {
type: 'doughnut',
data: {
labels: ['Stripe', 'PayPal', 'Manuale'],
datasets: [{
data: [<?php echo ($stats['stripe_revenue'] ?? 0) . ',' . ($stats['paypal_revenue'] ?? 0) . ',' . ($stats['manual_revenue'] ?? 0); ?>],
backgroundColor: ['#0d6efd', '#0dcaf0', '#ffc107']
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom'
}
}
}
});
// DataTable
$('#ordersTable').DataTable({
language: {
url: "//cdn.datatables.net/plug-ins/1.10.25/i18n/Italian.json"
},
pageLength: 25,
order: [
[0, 'desc']
],
responsive: true
});
</script>
</body>
</html>