aaa
This commit is contained in:
parent
3404f5328d
commit
75599b6a0f
381
index.php
381
index.php
@ -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 →</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>
|
||||
<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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user