161 lines
7.0 KiB
PHP
161 lines
7.0 KiB
PHP
<?php
|
||
require_once 'db/config.php';
|
||
|
||
$pdo = db();
|
||
|
||
// İstatistikleri çek
|
||
$stats = [
|
||
'total_revenue' => 0,
|
||
'total_profit' => 0,
|
||
'product_count' => 0,
|
||
'low_stock_count' => 0
|
||
];
|
||
|
||
try {
|
||
// Toplam Gelir ve Kâr
|
||
$stmt = $pdo->query("SELECT SUM(total_amount) as total_revenue, SUM(profit_amount) as total_profit FROM sales");
|
||
$sales_stats = $stmt->fetch(PDO::FETCH_ASSOC);
|
||
if ($sales_stats) {
|
||
$stats['total_revenue'] = $sales_stats['total_revenue'] ?? 0;
|
||
$stats['total_profit'] = $sales_stats['total_profit'] ?? 0;
|
||
}
|
||
|
||
// Toplam Ürün Sayısı
|
||
$stats['product_count'] = $pdo->query("SELECT count(*) FROM products")->fetchColumn();
|
||
|
||
// Düşük Stoktaki Ürün Sayısı
|
||
$stats['low_stock_count'] = $pdo->query("SELECT count(*) FROM products WHERE stock_quantity <= low_stock_threshold")->fetchColumn();
|
||
|
||
// Son Satışlar (Son 5)
|
||
$recent_sales_stmt = $pdo->query("
|
||
SELECT p.name AS product_name, si.quantity, si.total_price, s.created_at
|
||
FROM sale_items si
|
||
JOIN sales s ON si.sale_id = s.id
|
||
JOIN products p ON si.product_id = p.id
|
||
ORDER BY s.created_at DESC
|
||
LIMIT 5
|
||
");
|
||
$recent_sales = $recent_sales_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||
|
||
// Düşük Stoktaki Ürünler
|
||
$low_stock_products_stmt = $pdo->query("SELECT id, name, stock_quantity, low_stock_threshold FROM products WHERE stock_quantity <= low_stock_threshold ORDER BY stock_quantity ASC");
|
||
$low_stock_products = $low_stock_products_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||
|
||
} catch (PDOException $e) {
|
||
$_SESSION['error'] = "Dashboard verileri çekilirken bir hata oluştu: " . $e->getMessage();
|
||
}
|
||
|
||
require_once 'partials/header.php';
|
||
?>
|
||
|
||
<h1 class="mb-4">Ana Panel</h1>
|
||
|
||
<!-- İstatistik Kartları -->
|
||
<div class="row">
|
||
<?php
|
||
$cards = [
|
||
['title' => 'Toplam Gelir', 'value' => number_format($stats['total_revenue'],2).' TL', 'color' => 'primary', 'icon' => 'bi-cash-coin'],
|
||
['title' => 'Toplam Kâr', 'value' => number_format($stats['total_profit'],2).' TL', 'color' => 'success', 'icon' => 'bi-graph-up-arrow'],
|
||
['title' => 'Toplam Ürün Çeşidi', 'value' => $stats['product_count'], 'color' => 'info', 'icon' => 'bi-box-seam'],
|
||
['title' => 'Düşük Stok Uyarısı', 'value' => $stats['low_stock_count'].' Ürün', 'color' => 'warning', 'icon' => 'bi-exclamation-triangle-fill']
|
||
];
|
||
foreach($cards as $c): ?>
|
||
<div class="col-xl-3 col-md-6 mb-4">
|
||
<div class="card border-left-<?php echo $c['color']; ?> shadow h-100 py-2">
|
||
<div class="card-body">
|
||
<div class="row no-gutters align-items-center">
|
||
<div class="col mr-2">
|
||
<div class="text-xs font-weight-bold text-<?php echo $c['color']; ?> text-uppercase mb-1"><?php echo $c['title']; ?></div>
|
||
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $c['value']; ?></div>
|
||
</div>
|
||
<div class="col-auto">
|
||
<i class="bi <?php echo $c['icon']; ?> fs-2 text-gray-300"></i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<!-- İçerik Alanı -->
|
||
<div class="row">
|
||
<!-- Son Satışlar -->
|
||
<div class="col-lg-7 mb-4">
|
||
<div class="card shadow">
|
||
<div class="card-header py-3">
|
||
<h6 class="m-0 font-weight-bold text-primary">Son Satışlar</h6>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="table-responsive">
|
||
<table class="table table-sm table-striped">
|
||
<thead>
|
||
<tr>
|
||
<th>Ürün</th>
|
||
<th>Adet</th>
|
||
<th>Tutar</th>
|
||
<th>Tarih</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php if (empty($recent_sales)): ?>
|
||
<tr><td colspan="4" class="text-center">Henüz satış yok.</td></tr>
|
||
<?php else: ?>
|
||
<?php foreach ($recent_sales as $sale): ?>
|
||
<tr>
|
||
<td><?php echo htmlspecialchars($sale['product_name']); ?></td>
|
||
<td><?php echo htmlspecialchars($sale['quantity']); ?></td>
|
||
<td><?php echo number_format($sale['total_price'], 2); ?> TL</td>
|
||
<td><?php echo date('d/m/Y', strtotime($sale['created_at'])); ?></td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
<?php endif; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<a href="sales.php" class="btn btn-primary btn-sm">Tüm Satışları Gör →</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Düşük Stoktaki Ürünler -->
|
||
<div class="col-lg-5 mb-4">
|
||
<div class="card shadow">
|
||
<div class="card-header py-3">
|
||
<h6 class="m-0 font-weight-bold text-warning">Stoğu Azalan Ürünler</h6>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="table-responsive">
|
||
<table class="table table-sm table-hover">
|
||
<thead>
|
||
<tr>
|
||
<th>Ürün</th>
|
||
<th>Kalan Stok</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php if (empty($low_stock_products)): ?>
|
||
<tr><td colspan="2" class="text-center">Stoğu azalan ürün yok.</td></tr>
|
||
<?php else: ?>
|
||
<?php foreach ($low_stock_products as $product): ?>
|
||
<tr class="table-warning">
|
||
<td>
|
||
<a href="edit-product.php?id=<?php echo $product['id']; ?>">
|
||
<?php echo htmlspecialchars($product['name']); ?>
|
||
</a>
|
||
</td>
|
||
<td><strong><?php echo htmlspecialchars($product['stock_quantity']); ?></strong> / <?php echo htmlspecialchars($product['low_stock_threshold']); ?></td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
<?php endif; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<a href="products.php" class="btn btn-primary btn-sm">Ürünleri Yönet →</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<?php require_once 'partials/footer.php'; ?>
|