diff --git a/api/inventory.php b/api/inventory.php index 8e0f531..be45850 100644 --- a/api/inventory.php +++ b/api/inventory.php @@ -5,12 +5,20 @@ require_once __DIR__ . '/../includes/auth.php'; header('Content-Type: application/json'); -if (!is_logged_in()) { - http_response_code(403); +// Check if user is logged in +if (!isset($_SESSION['user_id'])) { + http_response_code(401); echo json_encode(['error' => 'Unauthorized']); exit; } +// Check permission +if (!has_permission('inventory')) { + http_response_code(403); + echo json_encode(['error' => 'Forbidden: Stock Management permission required']); + exit; +} + $action = $_GET['action'] ?? ''; $db = db(); @@ -29,4 +37,4 @@ if ($action === 'get_batches') { exit; } -echo json_encode(['error' => 'Invalid action']); +echo json_encode(['error' => 'Invalid action']); \ No newline at end of file diff --git a/db/migrations/20260321_add_department_to_inventory_transactions.sql b/db/migrations/20260321_add_department_to_inventory_transactions.sql new file mode 100644 index 0000000..76d7bc6 --- /dev/null +++ b/db/migrations/20260321_add_department_to_inventory_transactions.sql @@ -0,0 +1,2 @@ +ALTER TABLE inventory_transactions ADD COLUMN IF NOT EXISTS department_id INT NULL; +ALTER TABLE inventory_transactions ADD CONSTRAINT fk_inventory_dept FOREIGN KEY (department_id) REFERENCES departments(id) ON DELETE SET NULL; diff --git a/includes/auth.php b/includes/auth.php index 2137e1a..1930cbc 100644 --- a/includes/auth.php +++ b/includes/auth.php @@ -77,3 +77,10 @@ function require_role($role_slug) { die("Access Denied: You do not have the required role."); } } + +function require_permission($permission) { + if (!has_permission($permission)) { + http_response_code(403); + die("Access Denied: You do not have the required permission: " . htmlspecialchars($permission)); + } +} \ No newline at end of file diff --git a/includes/pages/inventory_reports.php b/includes/pages/inventory_reports.php index d9e5c41..3433dc1 100644 --- a/includes/pages/inventory_reports.php +++ b/includes/pages/inventory_reports.php @@ -4,6 +4,7 @@ $report_type = $_GET['report'] ?? 'low_stock'; // Data Fetching based on report type $data = []; $columns = []; +$departments = $db->query("SELECT id, name_en FROM departments ORDER BY name_en ASC")->fetchAll(PDO::FETCH_ASSOC); if ($report_type === 'low_stock') { $title = __('low_stock_report'); @@ -41,6 +42,56 @@ if ($report_type === 'low_stock') { GROUP BY i.id ORDER BY total_value DESC ")->fetchAll(PDO::FETCH_ASSOC); +} elseif ($report_type === 'consumption') { + $title = __('consumption_report'); + $columns = ['department', 'item_name', 'total_quantity', 'total_cost']; + + // Filters + $filter_department = $_GET['department_id'] ?? ''; + $filter_start = $_GET['start_date'] ?? ''; + $filter_end = $_GET['end_date'] ?? ''; + + $where = "WHERE t.transaction_type = 'out'"; + $params = []; + + if ($filter_department) { + $where .= " AND t.department_id = ?"; + $params[] = $filter_department; + } + if ($filter_start) { + $where .= " AND DATE(t.transaction_date) >= ?"; + $params[] = $filter_start; + } + if ($filter_end) { + $where .= " AND DATE(t.transaction_date) <= ?"; + $params[] = $filter_end; + } + + $sql = " + SELECT d.name_en as department, + i.name_en as item_name, + SUM(t.quantity) as total_quantity, + SUM(t.quantity * COALESCE(b.cost_price, 0)) as total_cost + FROM inventory_transactions t + JOIN departments d ON t.department_id = d.id + JOIN inventory_items i ON t.item_id = i.id + LEFT JOIN inventory_batches b ON t.batch_id = b.id + $where + GROUP BY d.id, i.id + ORDER BY d.name_en ASC, total_cost DESC + "; + + $stmt = $db->prepare($sql); + $stmt->execute($params); + $data = $stmt->fetchAll(PDO::FETCH_ASSOC); + + // Calculate totals + $grand_total_qty = 0; + $grand_total_cost = 0; + foreach ($data as $row) { + $grand_total_qty += $row['total_quantity']; + $grand_total_cost += $row['total_cost']; + } } ?> @@ -51,6 +102,7 @@ if ($report_type === 'low_stock') { + @@ -59,12 +111,47 @@ if ($report_type === 'low_stock') {
| + | |||
|---|---|---|---|
| : | ++ | + | |