Autosave: 20260220-093052

This commit is contained in:
Flatlogic Bot 2026-02-20 09:30:52 +00:00
parent 680e4a7098
commit deddf67d73
4 changed files with 109 additions and 21 deletions

View File

@ -1327,12 +1327,25 @@ DROP TABLE IF EXISTS `role_groups`;
CREATE TABLE `role_groups` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`permissions` text DEFAULT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `role_permissions`
--
DROP TABLE IF EXISTS `role_permissions`;
CREATE TABLE `role_permissions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_id` int(11) NOT NULL,
`permission` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `role_id` (`role_id`,`permission`),
CONSTRAINT `role_permissions_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `role_groups` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `role_groups`
--
@ -1340,13 +1353,27 @@ CREATE TABLE `role_groups` (
LOCK TABLES `role_groups` WRITE;
/*!40000 ALTER TABLE `role_groups` DISABLE KEYS */;
INSERT INTO `role_groups` VALUES
(1,'Administrator','all','2026-02-18 05:30:12'),
(4,'Cashier','[\"pos_view\",\"pos_add\",\"items_view\",\"items_add\"]','2026-02-18 09:32:14'),
(5,'Admin','[\"pos_view\",\"pos_add\",\"pos_edit\",\"quotations_view\",\"quotations_add\",\"quotations_edit\",\"customers_view\",\"customers_add\",\"customers_edit\",\"suppliers_view\",\"suppliers_add\",\"suppliers_edit\",\"sales_view\",\"sales_add\",\"sales_edit\",\"purchases_view\",\"purchases_add\",\"purchases_edit\",\"hr_view\",\"hr_add\",\"hr_edit\",\"hr_delete\",\"users_view\"]','2026-02-18 09:33:29'),
(6,'Accountant','[\"accounting_view\",\"accounting_add\",\"accounting_edit\"]','2026-02-18 09:34:03');
(1,'Administrator','2026-02-18 05:30:12'),
(4,'Cashier','2026-02-18 09:32:14'),
(5,'Admin','2026-02-18 09:33:29'),
(6,'Accountant','2026-02-18 09:34:03');
/*!40000 ALTER TABLE `role_groups` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping data for table `role_permissions`
--
LOCK TABLES `role_permissions` WRITE;
/*!40000 ALTER TABLE `role_permissions` DISABLE KEYS */;
INSERT INTO `role_permissions` (role_id, permission) VALUES
(1,'all'),
(4,'pos_view'),(4,'pos_add'),(4,'items_view'),(4,'items_add'),
(5,'pos_view'),(5,'pos_add'),(5,'pos_edit'),(5,'quotations_view'),(5,'quotations_add'),(5,'quotations_edit'),(5,'customers_view'),(5,'customers_add'),(5,'customers_edit'),(5,'suppliers_view'),(5,'suppliers_add'),(5,'suppliers_edit'),(5,'sales_view'),(5,'sales_add'),(5,'sales_edit'),(5,'purchases_view'),(5,'purchases_add'),(5,'purchases_edit'),(5,'hr_view'),(5,'hr_add'),(5,'hr_edit'),(5,'hr_delete'),(5,'users_view'),
(6,'accounting_view'),(6,'accounting_add'),(6,'accounting_edit');
/*!40000 ALTER TABLE `role_permissions` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `sales_return_items`
--

View File

@ -145,13 +145,18 @@ require_once 'includes/accounting_helper.php';
// Helper to check permissions
function can(string $permission): bool {
if (!isset($_SESSION['user_id'])) return false;
if (($_SESSION['user_role_name'] ?? '') === 'Administrator' || ($_SESSION['user_permissions'] ?? '') === 'all') return true;
$perms = json_decode($_SESSION['user_permissions'] ?? '[]', true);
return is_array($perms) && in_array($permission, $perms);
if (($_SESSION['user_role_name'] ?? '') === 'Administrator') return true;
$user_perms = $_SESSION['user_permissions'] ?? [];
if ($user_perms === 'all') return true;
if (is_array($user_perms)) {
return in_array('all', $user_perms) || in_array($permission, $user_perms);
}
$perms = json_decode((string)$user_perms, true);
return is_array($perms) && (in_array('all', $perms) || in_array($permission, $perms));
}
function getPurchaseAlerts() {
if (($_SESSION['user_role_name'] ?? '') !== 'Administrator' && ($_SESSION['user_permissions'] ?? '') !== 'all') return [];
if (!can('dashboard_view')) return [];
$db = db();
$stmt = $db->query("SELECT p.id, p.due_date, p.total_with_vat, s.name as supplier_name
FROM purchases p
@ -213,14 +218,20 @@ $login_error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['login'])) {
$user = $_POST['username'] ?? '';
$pass = $_POST['password'] ?? '';
$stmt = db()->prepare("SELECT u.*, g.permissions, g.name as role_name FROM users u LEFT JOIN role_groups g ON u.group_id = g.id WHERE u.username = ? AND u.status = 'active'");
$stmt = db()->prepare("SELECT u.*, g.name as role_name FROM users u LEFT JOIN role_groups g ON u.group_id = g.id WHERE u.username = ? AND u.status = 'active'");
$stmt->execute([$user]);
$u = $stmt->fetch();
if ($u && password_verify($pass, $u['password'])) {
$_SESSION['user_id'] = $u['id'];
$_SESSION['username'] = $u['username'];
$_SESSION['user_role_name'] = $u['role_name'];
$_SESSION['user_permissions'] = $u['permissions'];
// Fetch permissions from the new role_permissions table
$permStmt = db()->prepare("SELECT permission FROM role_permissions WHERE role_id = ?");
$permStmt->execute([$u['group_id']]);
$permissions = $permStmt->fetchAll(PDO::FETCH_COLUMN);
$_SESSION['user_permissions'] = $permissions;
$_SESSION['profile_pic'] = $u['profile_pic'];
$_SESSION['theme'] = $u['theme'] ?? 'default';
header("Location: index.php");
@ -1441,13 +1452,25 @@ if (isset($_POST['add_hr_department'])) {
// --- User & Role Groups Handlers ---
if (isset($_POST['add_role_group'])) {
$name = $_POST['name'] ?? '';
$permissions = isset($_POST['permissions']) ? json_encode($_POST['permissions']) : '[]';
$permissions = isset($_POST['permissions']) ? $_POST['permissions'] : [];
if ($name) {
try {
$stmt = db()->prepare("INSERT INTO role_groups (name, permissions) VALUES (?, ?)");
$stmt->execute([$name, $permissions]);
$db = db();
$db->beginTransaction();
$stmt = $db->prepare("INSERT INTO role_groups (name) VALUES (?)");
$stmt->execute([$name]);
$role_id = $db->lastInsertId();
if (!empty($permissions)) {
$stmtPerm = $db->prepare("INSERT INTO role_permissions (role_id, permission) VALUES (?, ?)");
foreach ($permissions as $p) {
$stmtPerm->execute([$role_id, $p]);
}
}
$db->commit();
$message = "Role Group added successfully!";
} catch (PDOException $e) {
if ($db->inTransaction()) $db->rollBack();
$message = "Error adding role group: " . $e->getMessage();
}
}
@ -1477,11 +1500,30 @@ if (isset($_POST['add_hr_department'])) {
if (isset($_POST['edit_role_group'])) {
$id = (int)$_POST['id'];
$name = $_POST['name'] ?? '';
$permissions = isset($_POST['permissions']) ? json_encode($_POST['permissions']) : '[]';
$permissions = isset($_POST['permissions']) ? $_POST['permissions'] : [];
if ($id && $name) {
$stmt = db()->prepare("UPDATE role_groups SET name = ?, permissions = ? WHERE id = ?");
$stmt->execute([$name, $permissions, $id]);
$message = "Role Group updated successfully!";
try {
$db = db();
$db->beginTransaction();
$stmt = $db->prepare("UPDATE role_groups SET name = ? WHERE id = ?");
$stmt->execute([$name, $id]);
// Refresh permissions
$stmtDel = $db->prepare("DELETE FROM role_permissions WHERE role_id = ?");
$stmtDel->execute([$id]);
if (!empty($permissions)) {
$stmtPerm = $db->prepare("INSERT INTO role_permissions (role_id, permission) VALUES (?, ?)");
foreach ($permissions as $p) {
$stmtPerm->execute([$id, $p]);
}
}
$db->commit();
$message = "Role Group updated successfully!";
} catch (PDOException $e) {
if ($db->inTransaction()) $db->rollBack();
$message = "Error updating role group: " . $e->getMessage();
}
}
}
if (isset($_POST['delete_role_group'])) {
@ -7421,7 +7463,9 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
</div>
<div class="row overflow-auto pe-2" style="max-height: 500px;">
<?php
$perms = json_decode($group['permissions'] ?? '[]', true);
$stmtP = db()->prepare("SELECT permission FROM role_permissions WHERE role_id = ?");
$stmtP->execute([$group['id']]);
$perms = $stmtP->fetchAll(PDO::FETCH_COLUMN);
foreach ($permission_groups as $group_name => $modules): ?>
<div class="permission-group-container col-12 mb-4">
<div class="mt-3 mb-2 bg-secondary bg-opacity-10 p-2 d-flex justify-content-between align-items-center rounded border-start border-primary border-3">

View File

@ -106,7 +106,15 @@ if ($step === 3 && $_SERVER['REQUEST_METHOD'] === 'POST') {
$pdo->exec("CREATE TABLE IF NOT EXISTS role_groups (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
permissions TEXT
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)");
$pdo->exec("CREATE TABLE IF NOT EXISTS role_permissions (
id INT AUTO_INCREMENT PRIMARY KEY,
role_id INT NOT NULL,
permission VARCHAR(255) NOT NULL,
UNIQUE KEY (role_id, permission),
FOREIGN KEY (role_id) REFERENCES role_groups(id) ON DELETE CASCADE
)");
$pdo->exec("CREATE TABLE IF NOT EXISTS users (
@ -127,10 +135,17 @@ if ($step === 3 && $_SERVER['REQUEST_METHOD'] === 'POST') {
$stmt->execute();
$role = $stmt->fetch();
if (!$role) {
$pdo->exec("INSERT INTO role_groups (name, permissions) VALUES ('Administrator', 'all')");
$pdo->exec("INSERT INTO role_groups (name) VALUES ('Administrator')");
$roleId = $pdo->lastInsertId();
$pdo->exec("INSERT INTO role_permissions (role_id, permission) VALUES ($roleId, 'all')");
} else {
$roleId = $role['id'];
// Also ensure 'all' permission exists for it
$stmt = $pdo->prepare("SELECT id FROM role_permissions WHERE role_id = ? AND permission = 'all'");
$stmt->execute([$roleId]);
if (!$stmt->fetch()) {
$pdo->exec("INSERT INTO role_permissions (role_id, permission) VALUES ($roleId, 'all')");
}
}
// Insert Admin User (Use ON DUPLICATE KEY UPDATE to handle existing user from schema)

View File

@ -131,3 +131,5 @@
2026-02-20 07:28:32 - POST: {"type":"customer","name":"Hamed Mohammed","email":"","phone":"","tax_id":"","balance":"0.000","add_customer":""}
2026-02-20 07:29:31 - POST: {"type":"sale","customer_id":"7","invoice_date":"2026-02-20","due_date":"","payment_type":"cash","status":"paid","paid_amount":"0.000","item_ids":["1"],"quantities":["1"],"prices":["0.450"],"add_invoice":""}
2026-02-20 07:30:15 - POST: {"type":"purchase","customer_id":"7","invoice_date":"2026-02-20","due_date":"","payment_type":"cash","status":"paid","paid_amount":"0.000","item_ids":["1"],"quantities":["150"],"prices":["0.400"],"add_invoice":""}
2026-02-20 09:27:36 - POST: {"invoice_id":"7","return_date":"2026-02-20","quantities":["5"],"item_ids":["1"],"prices":["0.400"],"notes":"","add_purchase_return":""}
2026-02-20 09:28:59 - POST: {"invoice_id":"7","return_date":"2026-02-20","quantities":["3"],"item_ids":["1"],"prices":["0.400"],"notes":"","add_purchase_return":""}