38815-vm/inventory.php
2026-02-28 22:33:39 +00:00

267 lines
10 KiB
PHP

<?php
session_start();
require 'db/config.php';
$db = db();
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
header('Location: index.php');
exit;
}
$userId = $_SESSION['user_id'];
// Handle Inventory Update
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_stock'])) {
$itemId = $_POST['item_id'];
$qty = $_POST['quantity'];
$type = $_POST['type']; // in or out
try {
$db->beginTransaction();
// Record transaction
$stmt = $db->prepare("INSERT INTO inventory_transactions (inventory_id, type, quantity, user_id) VALUES (?, ?, ?, ?)");
$stmt->execute([$itemId, $type, $qty, $userId]);
// Update stock
$mod = ($type === 'in' ? '+' : '-');
$db->exec("UPDATE inventory SET stock_level = stock_level $mod $qty WHERE id = $itemId");
$db->commit();
header("Location: inventory.php?success=1");
exit;
} catch (Exception $e) {
$db->rollBack();
$error = "Error: " . $e->getMessage();
}
}
// Handle New Item
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['new_item'])) {
$name = $_POST['name'];
$cat = $_POST['category'];
$stock = $_POST['stock_level'];
$reorder = $_POST['reorder_level'];
$unit = $_POST['unit'];
$stmt = $db->prepare("INSERT INTO inventory (name, category, stock_level, reorder_level, unit) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$name, $cat, $stock, $reorder, $unit]);
header("Location: inventory.php?item_added=1");
exit;
}
$inventory = $db->query("SELECT * FROM inventory ORDER BY name ASC")->fetchAll();
$lowStock = array_filter($inventory, fn($i) => $i['stock_level'] <= $i['reorder_level']);
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>M-TRACK | Inventory</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--sidebar-width: 240px;
--bg: #f8fafc;
--primary: #1e293b;
--accent: #3b82f6;
--text: #334155;
--border: #e2e8f0;
--danger: #ef4444;
}
body {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
background-color: var(--bg);
color: var(--text);
}
.sidebar {
width: var(--sidebar-width);
position: fixed;
top: 0;
bottom: 0;
left: 0;
background-color: var(--primary);
color: white;
z-index: 1000;
padding: 1.5rem 1rem;
}
.main-content {
margin-left: var(--sidebar-width);
padding: 2.5rem;
}
.card {
background: white;
border: 1px solid var(--border);
border-radius: 4px;
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
margin-bottom: 1.5rem;
}
.alert-low {
border-left: 4px solid var(--danger);
}
</style>
</head>
<body>
<div class="sidebar">
<h2>M-TRACK</h2>
<nav class="nav nav-pills flex-column">
<a class="nav-link" href="dashboard.php"><i class="bi bi-grid-fill me-2"></i> Dashboard</a>
<a class="nav-link" href="jobs.php"><i class="bi bi-briefcase me-2"></i> Jobs</a>
<a class="nav-link active" href="inventory.php"><i class="bi bi-boxes me-2"></i> Inventory</a>
<a class="nav-link" href="users.php"><i class="bi bi-people me-2"></i> Users</a>
<a class="nav-link" href="time_study.php"><i class="bi bi-clock-history me-2"></i> Time Study</a>
<a class="nav-link" href="scan.php"><i class="bi bi-upc-scan me-2"></i> Scan</a>
<hr class="my-4 border-secondary opacity-25">
<a class="nav-link text-danger" href="logout.php"><i class="bi bi-box-arrow-right me-2"></i> Logout</a>
</nav>
</div>
<div class="main-content">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1>Inventory Management</h1>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#newItemModal">
<i class="bi bi-plus-lg me-1"></i> New Item
</button>
</div>
<?php if (!empty($lowStock)): ?>
<div class="alert alert-danger d-flex align-items-center mb-4">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div><strong>Low Stock Warning:</strong> <?= count($lowStock) ?> items are below reorder level.</div>
</div>
<?php endif; ?>
<div class="card">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0 align-middle">
<thead class="table-light">
<tr>
<th>Item Name</th>
<th>Category</th>
<th>Current Stock</th>
<th>Reorder Level</th>
<th class="text-end">Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($inventory)): ?>
<tr><td colspan="5" class="p-5 text-center text-muted">No inventory items found.</td></tr>
<?php else: ?>
<?php foreach ($inventory as $item): ?>
<tr class="<?= $item['stock_level'] <= $item['reorder_level'] ? 'table-danger alert-low' : '' ?>">
<td>
<div class="fw-bold"><?= htmlspecialchars($item['name']) ?></div>
<div class="small text-muted"><?= $item['unit'] ?></div>
</td>
<td><span class="badge bg-light text-dark border"><?= strtoupper($item['category']) ?></span></td>
<td>
<span class="fw-bold <?= $item['stock_level'] <= $item['reorder_level'] ? 'text-danger' : '' ?>">
<?= $item['stock_level'] ?>
</span>
</td>
<td><?= $item['reorder_level'] ?></td>
<td class="text-end">
<button class="btn btn-sm btn-outline-primary" onclick="setUpdateItem(<?= $item['id'] ?>, '<?= htmlspecialchars($item['name']) ?>')" data-bs-toggle="modal" data-bs-target="#updateModal">
Update Stock
</button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- New Item Modal -->
<div class="modal fade" id="newItemModal" tabindex="-1">
<div class="modal-dialog">
<form method="POST" class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add Inventory Item</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Item Name</label>
<input type="text" name="name" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Category</label>
<select name="category" class="form-select">
<option value="material">Raw Material</option>
<option value="consumable">Consumable</option>
<option value="hardware">Hardware</option>
</select>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Initial Stock</label>
<input type="number" step="0.01" name="stock_level" class="form-control" value="0">
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Reorder Level</label>
<input type="number" step="0.01" name="reorder_level" class="form-control" value="0">
</div>
</div>
<div class="mb-3">
<label class="form-label">Unit</label>
<input type="text" name="unit" class="form-control" placeholder="pcs, kg, meters, etc.">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" name="new_item" class="btn btn-primary">Add Item</button>
</div>
</form>
</div>
</div>
<!-- Update Stock Modal -->
<div class="modal fade" id="updateModal" tabindex="-1">
<div class="modal-dialog">
<form method="POST" class="modal-content">
<input type="hidden" name="item_id" id="update_item_id">
<div class="modal-header">
<h5 class="modal-title">Update Stock: <span id="update_item_name"></span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Transaction Type</label>
<select name="type" class="form-select">
<option value="in">Stock In (Receive)</option>
<option value="out">Stock Out (Consume)</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Quantity</label>
<input type="number" step="0.01" name="quantity" class="form-control" required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" name="update_stock" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
function setUpdateItem(id, name) {
document.getElementById('update_item_id').value = id;
document.getElementById('update_item_name').innerText = name;
}
</script>
</body>
</html>