diff --git a/accounting.php b/accounting.php new file mode 100644 index 0000000..363ef2c --- /dev/null +++ b/accounting.php @@ -0,0 +1,146 @@ +prepare("SELECT * FROM user_permissions WHERE user_id = ? AND page = 'accounting' AND can_view = 1"); +$stmt->execute([$user_id]); +if (!$stmt->fetch()) { + echo "
لا تملك صلاحية الوصول لهذه الصفحة.
"; + require_once 'includes/footer.php'; + exit; +} + +// Handle form submission +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_entry'])) { + $date = $_POST['date']; + $description = $_POST['description']; + $reference = $_POST['reference']; + $account = $_POST['account']; + $debit = (float)$_POST['debit']; + $credit = (float)$_POST['credit']; + + $entries = [['account' => $account, 'debit' => $debit, 'credit' => $credit]]; + + if (add_journal_entry($date, $description, $reference, $entries)) { + $message = "تم إضافة القيد بنجاح."; + } else { + $error = "حدث خطأ أثناء إضافة القيد."; + } +} + +$ledger = get_full_ledger(); +$trial_balance = get_trial_balance(); +$balance_sheet = get_balance_sheet(); +?> + +
+

المحاسبة (Accounting)

+ + $message
"; ?> + $error"; ?> + +
+
+
+
+
الأصول
+

+
+
+
+
+
+
+
الخصوم
+

+
+
+
+
+
+
+
حقوق الملكية
+

+
+
+
+
+
+
+
صافي الربح/الخسارة
+

+
+
+
+
+ +
+
إضافة قيد محاسبي جديد
+
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+ +
+
+

دفتر الأستاذ (General Ledger)

+
+ + + + + + + + + + + + + + +
التاريخالوصفالمرجعالحسابمديندائن
+
+
+
+ + + \ No newline at end of file diff --git a/accounts.php b/accounts.php new file mode 100644 index 0000000..4e11663 --- /dev/null +++ b/accounts.php @@ -0,0 +1,74 @@ +prepare("SELECT * FROM user_permissions WHERE user_id = ? AND page = 'accounting' AND can_view = 1"); +$stmt->execute([$user_id]); +if (!$stmt->fetch()) { + echo "
لا تملك صلاحية الوصول لهذه الصفحة.
"; + require_once 'includes/footer.php'; + exit; +} + +// Handle form submission +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_account'])) { + $name = $_POST['name']; + $type = $_POST['type']; // Assets, Liabilities, Equity, Revenue, Expenses + $stmt = db()->prepare("INSERT INTO accounting_accounts (name, type) VALUES (?, ?)"); + $stmt->execute([$name, $type]); + $message = "تم إضافة الحساب بنجاح."; +} + +$accounts = db()->query("SELECT * FROM accounting_accounts ORDER BY type, name")->fetchAll(PDO::FETCH_ASSOC); +?> + +
+

دليل الحسابات (Chart of Accounts)

+ + $message
"; ?> + +
+
إضافة حساب جديد
+
+
+ +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+ + + + + + + + + + + +
الاسمالنوع
+ + + diff --git a/db/migrations/018_add_accounting_module.sql b/db/migrations/018_add_accounting_module.sql new file mode 100644 index 0000000..80896a1 --- /dev/null +++ b/db/migrations/018_add_accounting_module.sql @@ -0,0 +1,26 @@ +-- Accounting module tables +CREATE TABLE IF NOT EXISTS accounting_journal ( + id INT AUTO_INCREMENT PRIMARY KEY, + date DATE NOT NULL, + description TEXT, + reference VARCHAR(255), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE IF NOT EXISTS accounting_entries ( + id INT AUTO_INCREMENT PRIMARY KEY, + journal_id INT NOT NULL, + account_name VARCHAR(255) NOT NULL, + debit DECIMAL(15,2) DEFAULT 0.00, + credit DECIMAL(15,2) DEFAULT 0.00, + FOREIGN KEY (journal_id) REFERENCES accounting_journal(id) ON DELETE CASCADE +); + +-- Register accounting module in user permissions +INSERT IGNORE INTO user_permissions (user_id, page, can_view, can_add, can_edit, can_delete) +SELECT id, 'accounting', + IF(role = 'admin', 1, 0), + IF(role = 'admin', 1, 0), + IF(role = 'admin', 1, 0), + IF(role = 'admin', 1, 0) +FROM users; \ No newline at end of file diff --git a/db/migrations/019_add_accounts_table.sql b/db/migrations/019_add_accounts_table.sql new file mode 100644 index 0000000..d75b674 --- /dev/null +++ b/db/migrations/019_add_accounts_table.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS accounting_accounts ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + type ENUM('Assets', 'Liabilities', 'Equity', 'Revenue', 'Expenses') NOT NULL +); diff --git a/includes/accounting_functions.php b/includes/accounting_functions.php new file mode 100644 index 0000000..c1f3542 --- /dev/null +++ b/includes/accounting_functions.php @@ -0,0 +1,67 @@ +query("SELECT j.*, SUM(e.debit) as total_debit, SUM(e.credit) as total_credit + FROM accounting_journal j + LEFT JOIN accounting_entries e ON j.id = e.journal_id + GROUP BY j.id ORDER BY j.date DESC"); + return $stmt->fetchAll(PDO::FETCH_ASSOC); +} + +function get_full_ledger() { + $db = db(); + $stmt = $db->query("SELECT j.date, j.description, j.reference, e.account_name, e.debit, e.credit + FROM accounting_journal j + JOIN accounting_entries e ON j.id = e.journal_id + ORDER BY j.date DESC, j.id DESC"); + return $stmt->fetchAll(PDO::FETCH_ASSOC); +} + +function get_trial_balance() { + $db = db(); + $stmt = $db->query("SELECT account_name, SUM(debit) as total_debit, SUM(credit) as total_credit + FROM accounting_entries + GROUP BY account_name"); + return $stmt->fetchAll(PDO::FETCH_ASSOC); +} + +function get_balance_sheet() { + $db = db(); + $stmt = $db->query("SELECT a.name, a.type, SUM(e.debit - e.credit) as balance + FROM accounting_accounts a + LEFT JOIN accounting_entries e ON a.name = e.account_name + GROUP BY a.name, a.type"); + $data = $stmt->fetchAll(PDO::FETCH_ASSOC); + $sheet = ['Assets' => 0, 'Liabilities' => 0, 'Equity' => 0, 'Revenue' => 0, 'Expenses' => 0]; + foreach($data as $row) { + $sheet[$row['type']] += $row['balance']; + } + return $sheet; +} + +function get_all_accounts() { + return db()->query("SELECT * FROM accounting_accounts ORDER BY type, name")->fetchAll(PDO::FETCH_ASSOC); +} + +function add_journal_entry($date, $description, $reference, $entries) { + $db = db(); + $db->beginTransaction(); + try { + $stmt = $db->prepare("INSERT INTO accounting_journal (date, description, reference) VALUES (?, ?, ?)"); + $stmt->execute([$date, $description, $reference]); + $journal_id = $db->lastInsertId(); + + $stmt = $db->prepare("INSERT INTO accounting_entries (journal_id, account_name, debit, credit) VALUES (?, ?, ?, ?)"); + foreach ($entries as $entry) { + $stmt->execute([$journal_id, $entry['account'], $entry['debit'], $entry['credit']]); + } + $db->commit(); + return true; + } catch (Exception $e) { + $db->rollBack(); + return false; + } +} +?> \ No newline at end of file diff --git a/includes/header.php b/includes/header.php index dfb990d..a5cdf59 100644 --- a/includes/header.php +++ b/includes/header.php @@ -342,6 +342,20 @@ if (!isLoggedIn() && basename($_SERVER['PHP_SELF']) !== 'login.php' && basename( + + + + + +