diff --git a/admin/includes/header.php b/admin/includes/header.php
index cb8e907..66e8ad5 100644
--- a/admin/includes/header.php
+++ b/admin/includes/header.php
@@ -401,7 +401,7 @@ function can_view($module) {
@@ -415,7 +415,7 @@ function can_view($module) {
diff --git a/admin/profile.php b/admin/profile.php
index c464fee..772aae7 100644
--- a/admin/profile.php
+++ b/admin/profile.php
@@ -7,17 +7,21 @@ $pdo = db();
$currentUser = get_logged_user();
$id = $currentUser['id'];
-// Always fetch fresh data from DB
-$stmt = $pdo->prepare("SELECT u.*, g.name as group_name, g.permissions
- FROM users u
- LEFT JOIN user_groups g ON u.group_id = g.id
- WHERE u.id = ?");
-$stmt->execute([$id]);
-$user = $stmt->fetch(PDO::FETCH_ASSOC);
+// Helper for fresh data
+function fetch_user_data($pdo, $id) {
+ $stmt = $pdo->prepare("SELECT u.*, g.name as group_name, g.permissions
+ FROM users u
+ LEFT JOIN user_groups g ON u.group_id = g.id
+ WHERE u.id = ?");
+ $stmt->execute([$id]);
+ return $stmt->fetch(PDO::FETCH_ASSOC);
+}
+
+$user = fetch_user_data($pdo, $id);
if (!$user) {
logout_user();
- header('Location: /login.php');
+ header('Location: ' . get_base_url() . 'login.php');
exit;
}
@@ -25,12 +29,13 @@ $message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$full_name = $_POST['full_name'];
+ $full_name_ar = $_POST['full_name_ar'] ?? '';
$email = $_POST['email'];
$pdo->beginTransaction();
try {
- $sql = "UPDATE users SET full_name = ?, email = ? WHERE id = ?";
- $params = [$full_name, $email, $id];
+ $sql = "UPDATE users SET full_name = ?, full_name_ar = ?, email = ? WHERE id = ?";
+ $params = [$full_name, $full_name_ar, $email, $id];
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
@@ -73,13 +78,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$message = 'Profile updated successfully!
';
// Refresh user data and update session
- $stmt->execute([$id]);
- $user = $stmt->fetch(PDO::FETCH_ASSOC);
+ $user = fetch_user_data($pdo, $id);
$_SESSION['user'] = $user;
unset($_SESSION['user']['password']);
} catch (Exception $e) {
- $pdo->rollBack();
+ if ($pdo->inTransaction()) {
+ $pdo->rollBack();
+ }
$message = 'Error updating profile: ' . $e->getMessage() . '
';
}
}
@@ -101,24 +107,38 @@ include 'includes/header.php';
-
-
-
-
-
-
\ No newline at end of file
diff --git a/admin/purchases.php b/admin/purchases.php
index 0853222..4b07aa6 100644
--- a/admin/purchases.php
+++ b/admin/purchases.php
@@ -6,18 +6,95 @@ $pdo = db();
$message = '';
+// Handle SAVE (Add/Edit) Purchase via POST
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'save_purchase') {
+ $id = $_POST['id'] ?: null;
+ $supplier_id = $_POST['supplier_id'] ?: null;
+ $purchase_date = $_POST['purchase_date'];
+ $status = $_POST['status'];
+ $notes = $_POST['notes'];
+ $product_ids = $_POST['product_id'] ?? [];
+ $quantities = $_POST['quantity'] ?? [];
+ $cost_prices = $_POST['cost_price'] ?? [];
+
+ try {
+ $pdo->beginTransaction();
+
+ $total_amount = 0;
+ foreach ($product_ids as $index => $pid) {
+ $total_amount += $quantities[$index] * $cost_prices[$index];
+ }
+
+ $purchase = null;
+ if ($id) {
+ $stmt = $pdo->prepare("SELECT * FROM purchases WHERE id = ?");
+ $stmt->execute([$id]);
+ $purchase = $stmt->fetch();
+
+ if ($purchase) {
+ $old_status = $purchase['status'];
+ $stmt = $pdo->prepare("UPDATE purchases SET supplier_id = ?, purchase_date = ?, status = ?, notes = ?, total_amount = ? WHERE id = ?");
+ $stmt->execute([$supplier_id, $purchase_date, $status, $notes, $total_amount, $id]);
+
+ $stmt = $pdo->prepare("SELECT * FROM purchase_items WHERE purchase_id = ?");
+ $stmt->execute([$id]);
+ $old_items = $stmt->fetchAll();
+
+ if ($old_status === 'completed') {
+ foreach ($old_items as $oi) {
+ $pdo->prepare("UPDATE products SET stock_quantity = stock_quantity - ? WHERE id = ?")
+ ->execute([$oi['quantity'], $oi['product_id']]);
+ }
+ }
+ $pdo->prepare("DELETE FROM purchase_items WHERE purchase_id = ?")->execute([$id]);
+ }
+ } else {
+ $stmt = $pdo->prepare("INSERT INTO purchases (supplier_id, purchase_date, status, notes, total_amount) VALUES (?, ?, ?, ?, ?)");
+ $stmt->execute([$supplier_id, $purchase_date, $status, $notes, $total_amount]);
+ $id = $pdo->lastInsertId();
+ }
+
+ foreach ($product_ids as $index => $pid) {
+ $qty = $quantities[$index];
+ $cost = $cost_prices[$index];
+ $total_item_price = $qty * $cost;
+
+ $stmt = $pdo->prepare("INSERT INTO purchase_items (purchase_id, product_id, quantity, cost_price, total_price) VALUES (?, ?, ?, ?, ?)");
+ $stmt->execute([$id, $pid, $qty, $cost, $total_item_price]);
+
+ if ($status === 'completed') {
+ $pdo->prepare("UPDATE products SET stock_quantity = stock_quantity + ?, cost_price = ? WHERE id = ?")
+ ->execute([$qty, $cost, $pid]);
+ }
+ }
+
+ $pdo->commit();
+ $message = 'Purchase saved successfully!
';
+ } catch (Exception $e) {
+ $pdo->rollBack();
+ $message = 'Error: ' . $e->getMessage() . '
';
+ }
+}
+
+// Handle Delete
if (isset($_GET['delete'])) {
if (!has_permission('purchases_del')) {
$message = 'Access Denied: You do not have permission to delete purchases.
';
} else {
$id = $_GET['delete'];
$pdo->prepare("DELETE FROM purchases WHERE id = ?")->execute([$id]);
- header("Location: purchases.php");
+ header("Location: purchases.php?msg=deleted");
exit;
}
}
+if (isset($_GET['msg']) && $_GET['msg'] === 'deleted') {
+ $message = 'Purchase record deleted successfully!
';
+}
+
$suppliers = $pdo->query("SELECT * FROM suppliers ORDER BY name")->fetchAll();
+$products = $pdo->query("SELECT id, name, cost_price FROM products ORDER BY name")->fetchAll();
+$products_json = json_encode($products);
$search = $_GET['search'] ?? '';
$supplier_filter = $_GET['supplier_filter'] ?? '';
@@ -63,9 +140,9 @@ include 'includes/header.php';
Manage restocks, supplier invoices and inventory tracking
-
+
+
@@ -143,9 +220,9 @@ include 'includes/header.php';
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/api/purchase_details.php b/api/purchase_details.php
new file mode 100644
index 0000000..1e01031
--- /dev/null
+++ b/api/purchase_details.php
@@ -0,0 +1,31 @@
+ false, 'error' => 'Missing ID']);
+ exit;
+}
+
+$stmt = $pdo->prepare("SELECT * FROM purchases WHERE id = ?");
+$stmt->execute([$id]);
+$purchase = $stmt->fetch(PDO::FETCH_ASSOC);
+
+if (!$purchase) {
+ echo json_encode(['success' => false, 'error' => 'Purchase not found']);
+ exit;
+}
+
+$stmt = $pdo->prepare("SELECT pi.*, p.name as product_name FROM purchase_items pi JOIN products p ON pi.product_id = p.id WHERE pi.purchase_id = ?");
+$stmt->execute([$id]);
+$items = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+echo json_encode([
+ 'success' => true,
+ 'purchase' => $purchase,
+ 'items' => $items
+]);
diff --git a/assets/images/users/user_1_699d76ecd9c95.jpg b/assets/images/users/user_1_699d76ecd9c95.jpg
new file mode 100644
index 0000000..9e8f8a2
Binary files /dev/null and b/assets/images/users/user_1_699d76ecd9c95.jpg differ
diff --git a/includes/functions.php b/includes/functions.php
index aef82bd..3933664 100644
--- a/includes/functions.php
+++ b/includes/functions.php
@@ -264,7 +264,7 @@ function get_logged_user() {
function require_login() {
if (!get_logged_user()) {
- header('Location: /login.php');
+ header('Location: ' . get_base_url() . 'login.php');
exit;
}
}
diff --git a/login.php b/login.php
index a66e114..e404608 100644
--- a/login.php
+++ b/login.php
@@ -4,9 +4,11 @@ require_once __DIR__ . '/includes/functions.php';
init_session();
+$baseUrl = get_base_url();
+
// Redirect if already logged in
if (get_logged_user()) {
- header('Location: /admin/index.php');
+ header('Location: ' . $baseUrl . 'admin/index.php');
exit;
}
@@ -17,7 +19,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$password = $_POST['password'] ?? '';
if (login_user($username, $password)) {
- header('Location: /admin/index.php');
+ header('Location: ' . $baseUrl . 'admin/index.php');
exit;
} else {
$error = 'Invalid username or password.';
@@ -34,7 +36,7 @@ $settings = get_company_settings();
Login - = htmlspecialchars($settings['company_name']) ?>
-
+
|