This commit is contained in:
admin 2025-10-24 10:07:22 +00:00
parent 3404f5328d
commit 75599b6a0f

381
index.php
View File

@ -1,160 +1,249 @@
<?php
require_once 'db/config.php';
session_start();
$pdo = db();
// İstatistikleri çek
$stats = [
'total_revenue' => 0,
'total_profit' => 0,
'product_count' => 0,
'low_stock_count' => 0
];
/* ========== VERİTABANI BAĞLANTISI ========== */
$host = 'localhost';
$db = 'store_db'; // veritabanı adını değiştir
$user = 'root'; // veritabanı kullanıcı adı
$pass = ''; // veritabanı şifre
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
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);
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
} catch (PDOException $e) {
$_SESSION['error'] = "Dashboard verileri çekilirken bir hata oluştu: " . $e->getMessage();
die("Veritabanına bağlanılamadı: " . $e->getMessage());
}
require_once 'partials/header.php';
/* ========== TABLOLARIN OLUŞTURULMASI (İLK SEFERDE YAP) ========== */
$pdo->exec("
CREATE TABLE IF NOT EXISTS products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
price DECIMAL(10,2) NOT NULL,
stock_quantity INT DEFAULT 0,
low_stock_threshold INT DEFAULT 5
);
CREATE TABLE IF NOT EXISTS sales (
id INT AUTO_INCREMENT PRIMARY KEY,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS sale_items (
id INT AUTO_INCREMENT PRIMARY KEY,
sale_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL,
total_price DECIMAL(10,2) NOT NULL,
profit_amount DECIMAL(10,2) NOT NULL,
FOREIGN KEY (sale_id) REFERENCES sales(id) ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE
);
");
/* ========== İŞLEMLER (GET/POST) ========== */
// Ürün ekleme
if(isset($_POST['add_product'])){
$stmt = $pdo->prepare("INSERT INTO products (name, price, stock_quantity, low_stock_threshold) VALUES (?,?,?,?)");
$stmt->execute([$_POST['name'], $_POST['price'], $_POST['stock_quantity'], $_POST['low_stock_threshold']]);
$_SESSION['success'] = "Ürün eklendi.";
}
// Ürün silme
if(isset($_GET['delete_product'])){
$stmt = $pdo->prepare("DELETE FROM products WHERE id=?");
$stmt->execute([$_GET['delete_product']]);
$_SESSION['success'] = "Ürün silindi.";
}
// Satış ekleme
if(isset($_POST['add_sale'])){
$product_ids = $_POST['product_id'];
$quantities = $_POST['quantity'];
try {
$pdo->beginTransaction();
$pdo->exec("INSERT INTO sales (created_at) VALUES (NOW())");
$sale_id = $pdo->lastInsertId();
foreach($product_ids as $i => $pid){
$qty = intval($quantities[$i]);
if($qty <= 0) continue;
$product = $pdo->prepare("SELECT price, stock_quantity FROM products WHERE id=?");
$product->execute([$pid]);
$p = $product->fetch();
if(!$p || $p['stock_quantity'] < $qty) continue;
$total_price = $p['price'] * $qty;
$profit_amount = $total_price * 0.2;
$stmt = $pdo->prepare("INSERT INTO sale_items (sale_id, product_id, quantity, total_price, profit_amount) VALUES (?,?,?,?,?)");
$stmt->execute([$sale_id, $pid, $qty, $total_price, $profit_amount]);
$pdo->prepare("UPDATE products SET stock_quantity = stock_quantity - ? WHERE id=?")->execute([$qty, $pid]);
}
$pdo->commit();
$_SESSION['success'] = "Satış eklendi.";
} catch(PDOException $e){
$pdo->rollBack();
$_SESSION['error'] = "Satış eklenirken hata: ".$e->getMessage();
}
}
/* ========== VERİLERİN ÇEKİLMESİ ========== */
// Dashboard istatistikleri
$stats = [
'total_revenue' => $pdo->query("SELECT SUM(total_price) FROM sale_items")->fetchColumn() ?: 0,
'total_profit' => $pdo->query("SELECT SUM(profit_amount) FROM sale_items")->fetchColumn() ?: 0,
'product_count' => $pdo->query("SELECT COUNT(*) FROM products")->fetchColumn(),
'low_stock_count' => $pdo->query("SELECT COUNT(*) FROM products WHERE stock_quantity <= low_stock_threshold")->fetchColumn()
];
// Son 5 satış
$recent_sales = $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
")->fetchAll(PDO::FETCH_ASSOC);
// Ürün listesi
$products = $pdo->query("SELECT * FROM products ORDER BY name ASC")->fetchAll(PDO::FETCH_ASSOC);
// Stoğu azalan ürünler
$low_stock_products = $pdo->query("SELECT * FROM products WHERE stock_quantity <= low_stock_threshold ORDER BY stock_quantity ASC")->fetchAll(PDO::FETCH_ASSOC);
?>
<h1 class="mb-4">Ana Panel</h1>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stok & Satış Takip</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4">
<div class="container-fluid">
<a class="navbar-brand" href="#">Elit Lastik</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" href="#">Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="#products">Ürünler</a></li>
<li class="nav-item"><a class="nav-link" href="#sales">Satışlar</a></li>
</ul>
</div>
</div>
</nav>
<div class="container">
<!-- İ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; ?>
<?php if(isset($_SESSION['success'])) { echo "<div class='alert alert-success'>".$_SESSION['success']."</div>"; unset($_SESSION['success']); } ?>
<?php if(isset($_SESSION['error'])) { echo "<div class='alert alert-danger'>".$_SESSION['error']."</div>"; unset($_SESSION['error']); } ?>
<h1 class="mb-4">Dashboard</h1>
<div class="row mb-4">
<div class="col-md-3">
<div class="card text-white bg-primary mb-3">
<div class="card-body">
<h5 class="card-title">Toplam Gelir</h5>
<p class="card-text"><?php echo number_format($stats['total_revenue'],2); ?> TL</p>
</div></div></div>
<div class="col-md-3">
<div class="card text-white bg-success mb-3">
<div class="card-body">
<h5 class="card-title">Toplam Kâr</h5>
<p class="card-text"><?php echo number_format($stats['total_profit'],2); ?> TL</p>
</div></div></div>
<div class="col-md-3">
<div class="card text-white bg-info mb-3">
<div class="card-body">
<h5 class="card-title">Ürün Çeşidi</h5>
<p class="card-text"><?php echo $stats['product_count']; ?></p>
</div></div></div>
<div class="col-md-3">
<div class="card text-white bg-warning mb-3">
<div class="card-body">
<h5 class="card-title">Düşük Stok</h5>
<p class="card-text"><?php echo $stats['low_stock_count']; ?> Ürün</p>
</div></div></div>
</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 &rarr;</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 &rarr;</a>
</div>
</div>
</div>
<h2 id="products" class="mb-3">Ürünler</h2>
<form method="POST" class="mb-3">
<div class="row g-2">
<div class="col-md-3"><input type="text" name="name" class="form-control" placeholder="Ürün Adı" required></div>
<div class="col-md-2"><input type="number" step="0.01" name="price" class="form-control" placeholder="Fiyat" required></div>
<div class="col-md-2"><input type="number" name="stock_quantity" class="form-control" placeholder="Stok" required></div>
<div class="col-md-2"><input type="number" name="low_stock_threshold" class="form-control" placeholder="Düşük Stok" required></div>
<div class="col-md-3"><button type="submit" name="add_product" class="btn btn-success w-100">Ürün Ekle</button></div>
</div>
</form>
<?php require_once 'partials/footer.php'; ?>
<table class="table table-striped table-hover mb-5">
<thead>
<tr><th>Ad</th><th>Fiyat</th><th>Stok</th><th>Düşük Stok</th><th>İşlemler</th></tr>
</thead>
<tbody>
<?php foreach($products as $p): ?>
<tr>
<td><?php echo htmlspecialchars($p['name']); ?></td>
<td><?php echo number_format($p['price'],2); ?> TL</td>
<td><?php echo $p['stock_quantity']; ?></td>
<td><?php echo $p['low_stock_threshold']; ?></td>
<td><a href="?delete_product=<?php echo $p['id']; ?>" class="btn btn-danger btn-sm" onclick="return confirm('Silmek istediğine emin misin?')">Sil</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<h2 id="sales" class="mb-3">Satışlar</h2>
<form method="POST" class="mb-3">
<table class="table table-bordered">
<tr><th>Ürün</th><th>Adet</th></tr>
<?php foreach($products as $p): ?>
<tr>
<td><?php echo htmlspecialchars($p['name']); ?> (Stok: <?php echo $p['stock_quantity']; ?>)</td>
<td>
<input type="number" name="quantity[]" value="0" min="0" max="<?php echo $p['stock_quantity']; ?>" class="form-control">
<input type="hidden" name="product_id[]" value="<?php echo $p['id']; ?>">
</td>
</tr>
<?php endforeach; ?>
</table>
<button type="submit" name="add_sale" class="btn btn-success mb-5">Satışı Kaydet</button>
</form>
<h3 class="mb-3">Son 5 Satış</h3>
<table class="table table-striped table-hover mb-5">
<thead>
<tr><th>Ürün</th><th>Adet</th><th>Toplam</th><th>Tarih</th></tr>
</thead>
<tbody>
<?php foreach($recent_sales as $s): ?>
<tr>
<td><?php echo htmlspecialchars($s['product_name']); ?></td>
<td><?php echo $s['quantity']; ?></td>
<td><?php echo number_format($s['total_price'],2); ?> TL</td>
<td><?php echo date('d/m/Y H:i', strtotime($s['created_at'])); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<h3>Düşük Stok Ürünler</h3>
<ul>
<?php foreach($low_stock_products as $lp): ?>
<li><?php echo htmlspecialchars($lp['name']); ?> - Stok: <?php echo $lp['stock_quantity']; ?></li>
<?php endforeach; ?>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>