update charity all
This commit is contained in:
parent
cbc388177e
commit
f1fb1b1949
@ -237,10 +237,12 @@ $ledger = get_ledger_paginated($search, $date_from, $date_to, $limit, $offset);
|
||||
<h3 class="text-right">دفتر الأستاذ (General Ledger)</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-bordered text-right align-middle table-sm">
|
||||
<thead class="table-light"><tr><th>التاريخ</th><th>الوصف</th><th>المرجع</th><th>الحساب</th><th>مدين</th><th>دائن</th><th>الإجراءات</th></tr></thead>
|
||||
<thead class="table-light"><tr><th>التاريخ</th><th>الوصف</th><th>المرجع</th><th>الحساب</th><th>مدين</th><th>دائن</th><th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th>الإجراءات</th></tr></thead>
|
||||
<tbody>
|
||||
<?php if(empty($ledger)): ?>
|
||||
<tr><td colspan="7" class="text-center">لا توجد قيود.</td></tr>
|
||||
<tr><td colspan="9" class="text-center">لا توجد قيود.</td></tr>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($ledger as $row): ?>
|
||||
<tr>
|
||||
@ -250,6 +252,8 @@ $ledger = get_ledger_paginated($search, $date_from, $date_to, $limit, $offset);
|
||||
<td><?= htmlspecialchars($row['account_name']) ?></td>
|
||||
<td><?= number_format($row['debit'], 2) ?></td>
|
||||
<td><?= number_format($row['credit'], 2) ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-link text-warning p-0 me-2" title="تعديل" onclick="openEditModal(<?= $row['id'] ?>)"><i class="fas fa-edit"></i></button>
|
||||
|
||||
|
||||
@ -129,7 +129,9 @@ $typeMap = [
|
||||
<tr>
|
||||
<th>الاسم</th>
|
||||
<th>النوع</th>
|
||||
<th style="width: 120px; text-align: center;">إجراءات</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th style="width: 120px; text-align: center;">إجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -141,6 +143,8 @@ $typeMap = [
|
||||
<?= htmlspecialchars($typeMap[$account['type']] ?? $account['type']) ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($account['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($account['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center">
|
||||
<button class="btn btn-warning text-white btn-sm shadow-sm mx-1" onclick="editAccount(<?= $account['id'] ?>, '<?= htmlspecialchars($account['name'], ENT_QUOTES) ?>', '<?= htmlspecialchars($account['type'], ENT_QUOTES) ?>')" title="تعديل">
|
||||
<i class="fas fa-pencil-alt"></i>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
|
||||
if (!isAdmin() && !canView('committees')) {
|
||||
if (!isAdmin() && !canView('charity_members')) {
|
||||
echo "<div class='alert alert-danger'>غير مصرح لك بالوصول لهذه الصفحة.</div>";
|
||||
require_once 'includes/footer.php';
|
||||
exit;
|
||||
@ -10,7 +10,7 @@ if (!isAdmin() && !canView('committees')) {
|
||||
$action = $_GET['action'] ?? 'list';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_POST['add_member']) && (isAdmin() || canAdd('committees'))) {
|
||||
if (isset($_POST['add_member']) && (isAdmin() || canAdd('charity_members'))) {
|
||||
$name = $_POST['name'] ?? '';
|
||||
$role = $_POST['role'] ?? '';
|
||||
$phone = $_POST['phone'] ?? '';
|
||||
@ -23,7 +23,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
$_SESSION['success'] = "تمت إضافة العضو بنجاح.";
|
||||
redirect('charity_members.php');
|
||||
} elseif (isset($_POST['edit_member']) && (isAdmin() || canEdit('committees'))) {
|
||||
} elseif (isset($_POST['edit_member']) && (isAdmin() || canEdit('charity_members'))) {
|
||||
$id = $_POST['id'];
|
||||
$name = $_POST['name'] ?? '';
|
||||
$role = $_POST['role'] ?? '';
|
||||
@ -37,7 +37,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
$_SESSION['success'] = "تم تحديث العضو بنجاح.";
|
||||
redirect('charity_members.php');
|
||||
} elseif (isset($_POST['delete_member']) && (isAdmin() || canDelete('committees'))) {
|
||||
} elseif (isset($_POST['delete_member']) && (isAdmin() || canDelete('charity_members'))) {
|
||||
$id = $_POST['id'];
|
||||
$stmt = db()->prepare("DELETE FROM charity_members WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
@ -58,7 +58,7 @@ $members = $stmt->fetchAll();
|
||||
<a href="print_charity_report.php" target="_blank" class="btn btn-secondary me-2">
|
||||
<i class="fas fa-print me-2"></i> طباعة تقرير الجمعية
|
||||
</a>
|
||||
<?php if (isAdmin() || canAdd('committees')): ?>
|
||||
<?php if (isAdmin() || canAdd('charity_members')): ?>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addMemberModal">
|
||||
<i class="fas fa-plus me-2"></i> إضافة عضو جديد
|
||||
</button>
|
||||
@ -86,6 +86,8 @@ $members = $stmt->fetchAll();
|
||||
<th>البريد الإلكتروني</th>
|
||||
<th>تاريخ الانضمام</th>
|
||||
<th>الحالة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="text-end">الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -113,13 +115,15 @@ $members = $stmt->fetchAll();
|
||||
<span class="badge bg-secondary bg-opacity-10 text-secondary px-3 py-2 rounded-pill">غير نشط</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<?php if (isAdmin() || canEdit('committees')): ?>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($member['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($member['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-end">
|
||||
<?php if (isAdmin() || canEdit('charity_members')): ?>
|
||||
<button class="btn btn-sm btn-outline-primary me-2" data-bs-toggle="modal" data-bs-target="#editMemberModal<?= $member['id'] ?>">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if (isAdmin() || canDelete('committees')): ?>
|
||||
<?php if (isAdmin() || canDelete('charity_members')): ?>
|
||||
<button class="btn btn-sm btn-outline-danger" data-bs-toggle="modal" data-bs-target="#deleteMemberModal<?= $member['id'] ?>">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
@ -204,7 +208,7 @@ $members = $stmt->fetchAll();
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($members)): ?>
|
||||
<tr>
|
||||
<td colspan="7" class="text-center text-muted py-4">لا يوجد أعضاء مضافين حتى الآن</td>
|
||||
<td colspan="9" class="text-center text-muted py-4">لا يوجد أعضاء مضافين حتى الآن</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
|
||||
if (!isAdmin() && !canView('committees')) {
|
||||
if (!isAdmin() && !canView('charity_plans')) {
|
||||
echo "<div class='alert alert-danger'>غير مصرح لك بالوصول لهذه الصفحة.</div>";
|
||||
require_once 'includes/footer.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_POST['add_plan']) && (isAdmin() || canAdd('committees'))) {
|
||||
if (isset($_POST['add_plan']) && (isAdmin() || canAdd('charity_plans'))) {
|
||||
$title = $_POST['title'];
|
||||
$description = $_POST['description'] ?? '';
|
||||
$start_date = $_POST['start_date'] ?? date('Y-m-d');
|
||||
@ -21,7 +21,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$stmt->execute([$title, $description, $start_date, $end_date, $target_value, $achieved_value, $status]);
|
||||
$_SESSION['success'] = "تمت إضافة الخطة بنجاح.";
|
||||
redirect('charity_plans.php');
|
||||
} elseif (isset($_POST['edit_plan']) && (isAdmin() || canEdit('committees'))) {
|
||||
} elseif (isset($_POST['edit_plan']) && (isAdmin() || canEdit('charity_plans'))) {
|
||||
$id = $_POST['id'];
|
||||
$title = $_POST['title'];
|
||||
$description = $_POST['description'] ?? '';
|
||||
@ -35,7 +35,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$stmt->execute([$title, $description, $start_date, $end_date, $target_value, $achieved_value, $status, $id]);
|
||||
$_SESSION['success'] = "تم تحديث الخطة بنجاح.";
|
||||
redirect('charity_plans.php');
|
||||
} elseif (isset($_POST['delete_plan']) && (isAdmin() || canDelete('committees'))) {
|
||||
} elseif (isset($_POST['delete_plan']) && (isAdmin() || canDelete('charity_plans'))) {
|
||||
$id = $_POST['id'];
|
||||
$stmt = db()->prepare("DELETE FROM charity_plans WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
@ -84,7 +84,7 @@ $status_labels = [
|
||||
<a href="print_charity_report.php" target="_blank" class="btn btn-secondary me-2">
|
||||
<i class="fas fa-print me-2"></i> طباعة تقرير الجمعية
|
||||
</a>
|
||||
<?php if (isAdmin() || canAdd('committees')): ?>
|
||||
<?php if (isAdmin() || canAdd('charity_plans')): ?>
|
||||
<button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#addPlanModal">
|
||||
<i class="fas fa-plus me-2"></i> إضافة خطة/هدف جديد
|
||||
</button>
|
||||
@ -161,6 +161,8 @@ $status_labels = [
|
||||
<th>المحقق</th>
|
||||
<th>النسبة</th>
|
||||
<th>الحالة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="text-end">الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -190,13 +192,15 @@ $status_labels = [
|
||||
<?= $status_labels[$plan['status']] ?>
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<?php if (isAdmin() || canEdit('committees')): ?>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($plan['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($plan['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-end">
|
||||
<?php if (isAdmin() || canEdit('charity_plans')): ?>
|
||||
<button class="btn btn-sm btn-outline-primary me-2" data-bs-toggle="modal" data-bs-target="#editPlanModal<?= $plan['id'] ?>">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if (isAdmin() || canDelete('committees')): ?>
|
||||
<?php if (isAdmin() || canDelete('charity_plans')): ?>
|
||||
<button class="btn btn-sm btn-outline-danger" data-bs-toggle="modal" data-bs-target="#deletePlanModal<?= $plan['id'] ?>">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
@ -290,7 +294,7 @@ $status_labels = [
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($plans)): ?>
|
||||
<tr>
|
||||
<td colspan="7" class="text-center text-muted py-4">لا توجد خطط مضافة حتى الآن</td>
|
||||
<td colspan="9" class="text-center text-muted py-4">لا توجد خطط مضافة حتى الآن</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
|
||||
@ -8,17 +8,37 @@ if (!canView('committees')) {
|
||||
}
|
||||
|
||||
// Fetch all committees and calculate stats
|
||||
$stmt = db()->query("
|
||||
SELECT
|
||||
c.id, c.name,
|
||||
(SELECT COUNT(*) FROM committee_members WHERE committee_id = c.id) as members_count,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id) as total_plans,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id AND status = 'completed') as completed_plans,
|
||||
(SELECT COUNT(*) FROM committee_activities WHERE committee_id = c.id) as activities_count
|
||||
FROM committees c
|
||||
ORDER BY c.name ASC
|
||||
");
|
||||
$committees = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (isAdmin()) {
|
||||
$stmt = db()->query("
|
||||
SELECT
|
||||
c.id, c.name,
|
||||
(SELECT COUNT(*) FROM committee_members WHERE committee_id = c.id) as members_count,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id) as total_plans,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id AND status = 'completed') as completed_plans,
|
||||
(SELECT COUNT(*) FROM committee_activities WHERE committee_id = c.id) as activities_count
|
||||
FROM committees c
|
||||
ORDER BY c.name ASC
|
||||
");
|
||||
$committees = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} else {
|
||||
$stmt = db()->prepare("
|
||||
SELECT
|
||||
c.id, c.name,
|
||||
(SELECT COUNT(*) FROM committee_members WHERE committee_id = c.id) as members_count,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id) as total_plans,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id AND status = 'completed') as completed_plans,
|
||||
(SELECT COUNT(*) FROM committee_activities WHERE committee_id = c.id) as activities_count
|
||||
FROM committees c
|
||||
JOIN committee_members m ON c.id = m.committee_id
|
||||
JOIN charity_members cm ON m.charity_member_id = cm.id
|
||||
JOIN users u ON (u.id = cm.user_id) OR (cm.email != '' AND cm.email = u.email) OR (cm.name = u.full_name) OR (cm.name = u.username)
|
||||
WHERE u.id = ?
|
||||
GROUP BY c.id
|
||||
ORDER BY c.name ASC
|
||||
");
|
||||
$stmt->execute([$_SESSION['user_id']]);
|
||||
$committees = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
// Overall stats
|
||||
$total_committees = count($committees);
|
||||
|
||||
@ -99,6 +99,8 @@ if (isset($_SESSION['error'])) {
|
||||
<th class="ps-4" style="width: 80px;">الرقم</th>
|
||||
<th>اسم اللجنة</th>
|
||||
<th>الوصف</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="text-center">الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -109,7 +111,9 @@ if (isset($_SESSION['error'])) {
|
||||
<td class="ps-4"><?= htmlspecialchars($committee['id']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($committee['name']) ?></td>
|
||||
<td><?= htmlspecialchars($committee['description'] ?? '') ?></td>
|
||||
<td class="text-center">
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($committee['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($committee['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center">
|
||||
<a href="view_committee.php?id=<?= $committee['id'] ?>" class="btn btn-sm btn-outline-info me-1" title="إدارة اللجنة"><i class="fas fa-cog"></i> إدارة</a>
|
||||
<?php if (canEdit('committees')): ?>
|
||||
<button class="btn btn-sm btn-outline-primary me-1" onclick='openModal("edit", <?= json_encode($committee, JSON_HEX_APOS | JSON_HEX_QUOT) ?>)'>
|
||||
@ -126,7 +130,7 @@ if (isset($_SESSION['error'])) {
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="4" class="text-center py-4 text-muted">لا توجد لجان مضافة حتى الآن.</td>
|
||||
<td colspan="6" class="text-center py-4 text-muted">لا توجد لجان مضافة حتى الآن.</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
|
||||
@ -12,6 +12,13 @@ function db() {
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]);
|
||||
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
@session_start();
|
||||
}
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
$pdo->exec("SET @app_user_id = " . (int)$_SESSION['user_id']);
|
||||
}
|
||||
}
|
||||
return $pdo;
|
||||
}
|
||||
@ -48,4 +55,4 @@ function generateRefNo($type) {
|
||||
}
|
||||
|
||||
return $prefix . '-' . $year . '-' . str_pad($serial, 3, '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
17
db/migrations/033_add_user_id_to_charity_members.php
Normal file
17
db/migrations/033_add_user_id_to_charity_members.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../config.php';
|
||||
|
||||
$db = db();
|
||||
|
||||
try {
|
||||
$db->exec("ALTER TABLE charity_members ADD COLUMN user_id INT NULL");
|
||||
$db->exec("ALTER TABLE charity_members ADD CONSTRAINT fk_charity_members_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL");
|
||||
echo "Migration 033 completed successfully.\n";
|
||||
} catch (PDOException $e) {
|
||||
if (strpos($e->getMessage(), 'Duplicate column name') !== false) {
|
||||
echo "Column user_id already exists.\n";
|
||||
} else {
|
||||
echo "Error: " . $e->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
82
db/migrations/034_add_audit_columns.sql
Normal file
82
db/migrations/034_add_audit_columns.sql
Normal file
@ -0,0 +1,82 @@
|
||||
ALTER TABLE `committees` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `committees` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `committee_plans` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `committee_plans` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `committee_plans` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `committee_plans` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `charity_members` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `charity_members` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `charity_members` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `charity_members` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `charity_plans` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `charity_plans` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `charity_plans` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `charity_plans` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `expenses` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `expenses` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `expenses` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `expenses` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `expense_categories` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `expense_categories` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `expense_categories` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `expense_categories` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `accounting_accounts` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `accounting_accounts` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `accounting_accounts` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `accounting_accounts` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `accounting_journal` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `accounting_journal` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `accounting_journal` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `accounting_journal` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `hr_employees` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `hr_employees` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `hr_employees` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `hr_employees` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `hr_attendance` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `hr_attendance` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `hr_attendance` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `hr_attendance` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `hr_holidays` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `hr_holidays` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `hr_holidays` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `hr_holidays` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `hr_leaves` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `hr_leaves` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `hr_leaves` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `hr_leaves` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `hr_payroll` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `hr_payroll` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `hr_payroll` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `hr_payroll` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `stock_items` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `stock_items` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `stock_items` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `stock_items` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `stock_categories` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `stock_categories` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `stock_categories` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `stock_categories` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `stock_stores` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `stock_stores` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `stock_stores` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `stock_stores` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `stock_transactions` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `stock_transactions` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `stock_transactions` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `stock_transactions` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `stock_lending` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `stock_lending` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `stock_lending` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `stock_lending` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `users` ADD COLUMN `created_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `users` ADD FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `users` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `users` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `inbound_mail` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `inbound_mail` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `outbound_mail` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `outbound_mail` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `internal_mail` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `internal_mail` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
ALTER TABLE `meetings` ADD COLUMN `updated_by` INT DEFAULT NULL;
|
||||
ALTER TABLE `meetings` ADD FOREIGN KEY (`updated_by`) REFERENCES `users`(`id`) ON DELETE SET NULL;
|
||||
@ -101,6 +101,8 @@ if (isset($_SESSION['error'])) {
|
||||
<th class="ps-4">اسم التصنيف</th>
|
||||
<th>الحساب المحاسبي المرتبط</th>
|
||||
<th>الوصف</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="text-center">الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -116,6 +118,8 @@ if (isset($_SESSION['error'])) {
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($cat['description']) ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($cat['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($cat['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center">
|
||||
<?php if (canEdit('expense_settings')): ?>
|
||||
<button class="btn btn-sm btn-outline-primary" onclick='openModal("edit", <?= json_encode($cat, JSON_HEX_APOS | JSON_HEX_QUOT) ?>)'>
|
||||
|
||||
12
expenses.php
12
expenses.php
@ -283,13 +283,15 @@ if (isset($_SESSION['success'])) {
|
||||
<th>المبلغ</th>
|
||||
<th>طريقة الدفع</th>
|
||||
<th>الإيصال</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="text-center">الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($expenses)): ?>
|
||||
<tr>
|
||||
<td colspan="8" class="text-center py-5 text-muted">لا توجد سجلات مطابقة</td>
|
||||
<td colspan="10" class="text-center py-5 text-muted">لا توجد سجلات مطابقة</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($expenses as $exp): ?>
|
||||
@ -305,7 +307,9 @@ if (isset($_SESSION['success'])) {
|
||||
<td><?= htmlspecialchars($exp['vendor'] ?: '-') ?></td>
|
||||
<td class="fw-bold text-danger"><?= number_format($exp['amount'], 2) ?></td>
|
||||
<td><?= htmlspecialchars($exp['payment_method']) ?></td>
|
||||
<td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($exp['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($exp['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<?php if ($exp['receipt_file']): ?>
|
||||
<a href="<?= htmlspecialchars($exp['receipt_file']) ?>" target="_blank" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="fas fa-paperclip"></i>
|
||||
@ -330,13 +334,13 @@ if (isset($_SESSION['success'])) {
|
||||
<?php endforeach; ?>
|
||||
<!-- Page Total -->
|
||||
<tr class="bg-light">
|
||||
<td colspan="4" class="text-end fw-bold">إجمالي الصفحة:</td>
|
||||
<td colspan="6" class="text-end fw-bold">إجمالي الصفحة:</td>
|
||||
<td class="text-danger fw-bold"><?= number_format(array_sum(array_column($expenses, 'amount')), 2) ?></td>
|
||||
<td colspan="3"></td>
|
||||
</tr>
|
||||
<!-- Grand Total -->
|
||||
<tr class="bg-light border-top-0">
|
||||
<td colspan="4" class="text-end fw-bold">الإجمالي الكلي (للبحث الحالي):</td>
|
||||
<td colspan="6" class="text-end fw-bold">الإجمالي الكلي (للبحث الحالي):</td>
|
||||
<td class="text-danger fw-bold"><?= number_format($grandTotalAmount, 2) ?></td>
|
||||
<td colspan="3"></td>
|
||||
</tr>
|
||||
|
||||
@ -99,13 +99,15 @@ $records = $stmt->fetchAll();
|
||||
<th>وقت الحضور</th>
|
||||
<th>وقت الانصراف</th>
|
||||
<th>ملاحظات</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th>إجراء</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($records)): ?>
|
||||
<tr>
|
||||
<td colspan="7" class="text-center py-4 text-muted">لا يوجد موظفين نشطين.</td>
|
||||
<td colspan="9" class="text-center py-4 text-muted">لا يوجد موظفين نشطين.</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($records as $row): ?>
|
||||
@ -140,7 +142,9 @@ $records = $stmt->fetchAll();
|
||||
<td><?= $row['check_in'] ? date('h:i A', strtotime($row['check_in'])) : '-' ?></td>
|
||||
<td><?= $row['check_out'] ? date('h:i A', strtotime($row['check_out'])) : '-' ?></td>
|
||||
<td class="text-truncate" style="max-width: 150px;"><?= htmlspecialchars($row['notes'] ?? '') ?></td>
|
||||
<td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<?php if (canEdit('hr_attendance')): ?>
|
||||
<?php if ($row['att_id']): ?>
|
||||
<button class="btn btn-sm btn-outline-primary"
|
||||
|
||||
@ -258,6 +258,8 @@ $pagination = getPagination($page, $totalEmployees, $perPage);
|
||||
<th>تاريخ التعيين</th>
|
||||
<th>الحالة</th>
|
||||
<th>بصمة (UID)</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th>الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -303,7 +305,9 @@ $pagination = getPagination($page, $totalEmployees, $perPage);
|
||||
<span class="badge bg-<?= $status_cls ?>"><?= htmlspecialchars($row['status']) ?></span>
|
||||
</td>
|
||||
<td><span class="badge bg-light text-dark border"><?= htmlspecialchars($row['zkteco_uid'] ?: '-') ?></span></td>
|
||||
<td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($emp['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($emp['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<?php if (canEdit('hr_employees')): ?>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary"
|
||||
|
||||
@ -75,12 +75,14 @@ $holidays = db()->query("SELECT * FROM hr_holidays ORDER BY date_from DESC")->fe
|
||||
<th>من تاريخ</th>
|
||||
<th>إلى تاريخ</th>
|
||||
<th>الحالة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th>إجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($holidays)): ?>
|
||||
<tr><td colspan="5" class="text-center py-4 text-muted">لا توجد عطلات مسجلة.</td></tr>
|
||||
<tr><td colspan="7" class="text-center py-4 text-muted">لا توجد عطلات مسجلة.</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($holidays as $row):
|
||||
$today = date('Y-m-d');
|
||||
@ -100,6 +102,8 @@ $holidays = db()->query("SELECT * FROM hr_holidays ORDER BY date_from DESC")->fe
|
||||
<td><?= $row['date_from'] ?></td>
|
||||
<td><?= $row['date_to'] ?></td>
|
||||
<td><span class="badge bg-<?= $status_cls ?>"><?= $status_txt ?></span></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<?php if (canEdit('hr_attendance')): ?>
|
||||
<button class="btn btn-sm btn-outline-primary"
|
||||
|
||||
@ -205,12 +205,14 @@ $requests = $stmt->fetchAll();
|
||||
<th>السبب</th>
|
||||
<th>الحالة</th>
|
||||
<?php if ($tab === 'all'): ?><th>المعتمد</th><?php endif; ?>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th>إجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($requests)): ?>
|
||||
<tr><td colspan="8" class="text-center py-4 text-muted">لا توجد طلبات.</td></tr>
|
||||
<tr><td colspan="10" class="text-center py-4 text-muted">لا توجد طلبات.</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($requests as $req): ?>
|
||||
<tr>
|
||||
@ -251,6 +253,8 @@ $requests = $stmt->fetchAll();
|
||||
<?php if ($tab === 'all'): ?>
|
||||
<td class="small"><?= htmlspecialchars($req['approver_name'] ?? '-') ?></td>
|
||||
<?php endif; ?>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($req['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($req['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<?php if ($req['status'] === 'pending' && canEdit('hr_leaves')): ?>
|
||||
<button class="btn btn-sm btn-outline-primary"
|
||||
|
||||
@ -204,12 +204,14 @@ $total_salaries = $sumStmt->fetchColumn() ?: 0;
|
||||
<th>خصومات</th>
|
||||
<th>الصافي</th>
|
||||
<th>الحالة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th>إجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($payrolls)): ?>
|
||||
<tr><td colspan="7" class="text-center py-4 text-muted">لا توجد بيانات لهذا الشهر. اضغط على "توليد الرواتب" للبدء.</td></tr>
|
||||
<tr><td colspan="9" class="text-center py-4 text-muted">لا توجد بيانات لهذا الشهر. اضغط على "توليد الرواتب" للبدء.</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($payrolls as $row): ?>
|
||||
<tr>
|
||||
@ -229,6 +231,8 @@ $total_salaries = $sumStmt->fetchColumn() ?: 0;
|
||||
<span class="badge bg-info text-dark" title="مرحل للمحاسبة"><i class="fas fa-check-circle"></i></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<?php if (canEdit('hr_payroll')): ?>
|
||||
<button class="btn btn-sm btn-outline-primary"
|
||||
|
||||
@ -237,13 +237,15 @@ if (isset($_GET['id'])) {
|
||||
<th>الجهة المرسلة</th>
|
||||
<th>الحالة</th>
|
||||
<th>المسؤول</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="text-center pe-4">الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($mails)): ?>
|
||||
<tr>
|
||||
<td colspan="7" class="text-center py-5 text-muted">
|
||||
<td colspan="9" class="text-center py-5 text-muted">
|
||||
<i class="fas fa-inbox fa-3x mb-3 opacity-20"></i>
|
||||
<p>لا يوجد بريد وارد حالياً.</p>
|
||||
</td>
|
||||
@ -275,6 +277,8 @@ if (isset($_GET['id'])) {
|
||||
<span class="small"><?= htmlspecialchars($mail['assigned_to_name'] ?: 'غير محدد') ?></span>
|
||||
</div>
|
||||
</td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($mail['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($mail['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center pe-4">
|
||||
<div class="btn-group shadow-sm rounded">
|
||||
<a href="view_mail.php?id=<?= $mail['id'] ?>&type=inbound" class="btn btn-sm btn-white text-primary border" title="عرض">
|
||||
|
||||
@ -62,3 +62,19 @@ function canDelete($page = null) {
|
||||
function canViewInternal() {
|
||||
return canView('internal');
|
||||
}
|
||||
|
||||
// Added for auditing display
|
||||
function getAuditUserName($user_id) {
|
||||
if (!$user_id) return '-';
|
||||
static $userCache = null;
|
||||
if ($userCache === null) {
|
||||
$userCache = [];
|
||||
try {
|
||||
$stmt = db()->query("SELECT id, username, full_name FROM users");
|
||||
while ($u = $stmt->fetch()) {
|
||||
$userCache[$u['id']] = $u['full_name'] ?: $u['username'];
|
||||
}
|
||||
} catch(Exception $e) {}
|
||||
}
|
||||
return $userCache[$user_id] ?? '-';
|
||||
}
|
||||
|
||||
@ -104,6 +104,8 @@ function getStatusBadgeInternal($mail) {
|
||||
<th>المرفقات</th>
|
||||
<th>التاريخ</th>
|
||||
<th>الحالة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="pe-4 text-center">الإجراء</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -140,14 +142,16 @@ function getStatusBadgeInternal($mail) {
|
||||
<small class="text-muted"><?= date('Y-m-d H:i', strtotime($msg['created_at'])) ?></small>
|
||||
</td>
|
||||
<td><?= getStatusBadgeInternal($msg) ?></td>
|
||||
<td class="pe-4 text-center">
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($msg['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($msg['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="pe-4 text-center">
|
||||
<a href="view_mail.php?id=<?= $msg['id'] ?>&type=internal" class="btn btn-sm btn-light rounded-pill px-3">عرض</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-5 text-muted">
|
||||
<td colspan="8" class="text-center py-5 text-muted">
|
||||
<i class="fas fa-envelope-open fa-3x mb-3 opacity-25"></i>
|
||||
<p>لا توجد رسائل واردة حالياً</p>
|
||||
</td>
|
||||
|
||||
@ -206,6 +206,8 @@ function getStatusBadgeInternal($mail) {
|
||||
<th>المرفقات</th>
|
||||
<th>التاريخ</th>
|
||||
<th>الحالة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="pe-4 text-center">الإجراء</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -242,14 +244,16 @@ function getStatusBadgeInternal($mail) {
|
||||
<small class="text-muted"><?= date('Y-m-d H:i', strtotime($msg['created_at'])) ?></small>
|
||||
</td>
|
||||
<td><?= getStatusBadgeInternal($msg) ?></td>
|
||||
<td class="pe-4 text-center">
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($msg['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($msg['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="pe-4 text-center">
|
||||
<a href="view_mail.php?id=<?= $msg['id'] ?>&type=internal" class="btn btn-sm btn-light rounded-pill px-3">عرض</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-5 text-muted">
|
||||
<td colspan="8" class="text-center py-5 text-muted">
|
||||
<i class="fas fa-paper-plane fa-3x mb-3 opacity-25"></i>
|
||||
<p>لم يتم إرسال أي رسائل حالياً</p>
|
||||
</td>
|
||||
|
||||
@ -210,13 +210,15 @@ if (isset($_SESSION['success'])) {
|
||||
<th>المكان</th>
|
||||
<th>المنظم</th>
|
||||
<th>الحالة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="text-center">الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($meetings)): ?>
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-5 text-muted">لا توجد اجتماعات مطابقة</td>
|
||||
<td colspan="8" class="text-center py-5 text-muted">لا توجد اجتماعات مطابقة</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($meetings as $meeting): ?>
|
||||
@ -256,7 +258,9 @@ if (isset($_SESSION['success'])) {
|
||||
</td>
|
||||
<td><?= htmlspecialchars($meeting['created_by_name']) ?></td>
|
||||
<td><span class="badge <?= $status_class ?>"><?= $status_text ?></span></td>
|
||||
<td class="text-center">
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($meeting['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($meeting['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center">
|
||||
<?php if (canEdit('meetings')): ?>
|
||||
<button class="btn btn-sm btn-outline-primary" onclick='openModal("edit", <?= json_encode($meeting, JSON_HEX_APOS | JSON_HEX_QUOT) ?>)'>
|
||||
<i class="fas fa-edit"></i>
|
||||
|
||||
@ -226,13 +226,15 @@ if (isset($_GET['id'])) {
|
||||
<th>الموضوع</th>
|
||||
<th>الجهة المستلمة</th>
|
||||
<th>الحالة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="text-center pe-4">الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($mails)): ?>
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-5 text-muted">
|
||||
<td colspan="8" class="text-center py-5 text-muted">
|
||||
<i class="fas fa-paper-plane fa-3x mb-3 opacity-20"></i>
|
||||
<p>لا يوجد بريد صادر حالياً.</p>
|
||||
</td>
|
||||
@ -256,6 +258,8 @@ if (isset($_GET['id'])) {
|
||||
<i class="fas fa-circle me-1 small"></i> <?= htmlspecialchars($mail['status_name']) ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($mail['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($mail['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center pe-4">
|
||||
<div class="btn-group shadow-sm rounded">
|
||||
<a href="view_mail.php?id=<?= $mail['id'] ?>&type=outbound" class="btn btn-sm btn-white text-primary border" title="عرض">
|
||||
|
||||
@ -4,7 +4,7 @@ require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/includes/permissions.php';
|
||||
require_once __DIR__ . '/includes/settings.php';
|
||||
|
||||
if (!isLoggedIn() || !canView('committees')) {
|
||||
if (!isLoggedIn() || (!canView('charity_members') && !canView('charity_plans'))) {
|
||||
exit("لا توجد صلاحية للوصول لهذه الصفحة.");
|
||||
}
|
||||
|
||||
@ -61,10 +61,25 @@ $status_labels = [
|
||||
th, td { border: 1px solid #dee2e6; padding: 8px; text-align: right; }
|
||||
th { background-color: #f1f3f5; }
|
||||
@media print {
|
||||
body { margin: 0; padding: 0; }
|
||||
body { margin: 0; padding: 0; font-size: 10pt; }
|
||||
.btn-print { display: none !important; }
|
||||
@page { margin: 1cm; }
|
||||
.page-break { page-break-before: always; }
|
||||
@page { margin: 1cm; size: A4; }
|
||||
.container { width: 100% !important; max-width: none !important; padding: 0 !important; }
|
||||
.print-header { padding-bottom: 10px; margin-bottom: 15px; }
|
||||
.print-logo { max-height: 60px; }
|
||||
h2.fw-bold { font-size: 16pt; }
|
||||
p.fs-5 { font-size: 12pt !important; }
|
||||
h3.text-decoration-underline { font-size: 14pt; margin-bottom: 15px !important; }
|
||||
.section-title { margin-top: 15px; margin-bottom: 10px; padding: 5px 10px; font-size: 11pt; }
|
||||
.kpi-box { padding: 10px; }
|
||||
.kpi-box h2 { font-size: 14pt; margin: 0; }
|
||||
.kpi-box h5 { font-size: 10pt; margin-bottom: 2px; }
|
||||
table { margin-top: 10px; margin-bottom: 10px; }
|
||||
th, td { padding: 4px 6px; font-size: 9pt; }
|
||||
.page-break { page-break-before: auto; } /* Removed forced page break */
|
||||
.mb-5 { margin-bottom: 15px !important; }
|
||||
.py-4 { padding-top: 10px !important; padding-bottom: 10px !important; }
|
||||
.mt-5 { margin-top: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -157,11 +172,8 @@ $status_labels = [
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Page Break before Members -->
|
||||
<div class="page-break"></div>
|
||||
|
||||
<!-- Members Table -->
|
||||
<div class="section-title mt-0">2. أعضاء الجمعية</div>
|
||||
<div class="section-title">2. أعضاء الجمعية</div>
|
||||
<?php if (empty($members)): ?>
|
||||
<div class="text-muted text-center fst-italic py-3 border">لا يوجد أعضاء مسجلين.</div>
|
||||
<?php else: ?>
|
||||
|
||||
@ -12,16 +12,35 @@ $settings = get_settings();
|
||||
$db = db();
|
||||
|
||||
// Fetch committees and members
|
||||
$committees_query = $db->query("
|
||||
SELECT
|
||||
c.id, c.name, c.description,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id) as total_plans,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id AND status = 'completed') as completed_plans,
|
||||
(SELECT COUNT(*) FROM committee_activities WHERE committee_id = c.id) as activities_count
|
||||
FROM committees c
|
||||
ORDER BY c.name ASC
|
||||
");
|
||||
$committees = $committees_query->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (isAdmin()) {
|
||||
$committees_query = $db->query("
|
||||
SELECT
|
||||
c.id, c.name, c.description,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id) as total_plans,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id AND status = 'completed') as completed_plans,
|
||||
(SELECT COUNT(*) FROM committee_activities WHERE committee_id = c.id) as activities_count
|
||||
FROM committees c
|
||||
ORDER BY c.name ASC
|
||||
");
|
||||
$committees = $committees_query->fetchAll(PDO::FETCH_ASSOC);
|
||||
} else {
|
||||
$committees_query = $db->prepare("
|
||||
SELECT
|
||||
c.id, c.name, c.description,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id) as total_plans,
|
||||
(SELECT COUNT(*) FROM committee_plans WHERE committee_id = c.id AND status = 'completed') as completed_plans,
|
||||
(SELECT COUNT(*) FROM committee_activities WHERE committee_id = c.id) as activities_count
|
||||
FROM committees c
|
||||
JOIN committee_members m ON c.id = m.committee_id
|
||||
JOIN charity_members cm ON m.charity_member_id = cm.id
|
||||
JOIN users u ON (u.id = cm.user_id) OR (cm.email != '' AND cm.email = u.email) OR (cm.name = u.full_name) OR (cm.name = u.username)
|
||||
WHERE u.id = ?
|
||||
GROUP BY c.id
|
||||
ORDER BY c.name ASC
|
||||
");
|
||||
$committees_query->execute([$_SESSION['user_id']]);
|
||||
$committees = $committees_query->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
foreach ($committees as &$c) {
|
||||
// Calculate performance score
|
||||
|
||||
@ -157,13 +157,15 @@ $categories = db()->query("SELECT * FROM stock_categories ORDER BY name ASC")->f
|
||||
<th>الكمية الحالية</th>
|
||||
<th>الحد الأدنى</th>
|
||||
<th>الوحدة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="text-center">الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($items)): ?>
|
||||
<tr>
|
||||
<td colspan="7" class="text-center py-5 text-muted">
|
||||
<td colspan="9" class="text-center py-5 text-muted">
|
||||
<i class="fas fa-boxes fa-3x mb-3 opacity-20"></i>
|
||||
<p>لا يوجد أصناف مطابقة.</p>
|
||||
</td>
|
||||
@ -183,6 +185,8 @@ $categories = db()->query("SELECT * FROM stock_categories ORDER BY name ASC")->f
|
||||
</td>
|
||||
<td><?= number_format($item['min_quantity']) ?></td>
|
||||
<td><?= htmlspecialchars($item['unit']) ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($item['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($item['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center">
|
||||
<?php if (canEdit('stock_items')): ?>
|
||||
<button class="btn btn-sm btn-outline-primary" onclick='openItemModal("edit", <?= json_encode($item) ?>)'>
|
||||
|
||||
@ -144,13 +144,15 @@ $items = db()->query("SELECT * FROM stock_items ORDER BY name ASC")->fetchAll();
|
||||
<th>تاريخ الإعارة</th>
|
||||
<th>تاريخ الإرجاع المتوقع</th>
|
||||
<th>الحالة</th>
|
||||
<th>الإجراءات</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th>الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($loans)): ?>
|
||||
<tr>
|
||||
<td colspan="7" class="text-center py-4 text-muted">لا توجد إعارات نشطة حالياً</td>
|
||||
<td colspan="9" class="text-center py-4 text-muted">لا توجد إعارات نشطة حالياً</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($loans as $loan): ?>
|
||||
@ -170,6 +172,8 @@ $items = db()->query("SELECT * FROM stock_items ORDER BY name ASC")->fetchAll();
|
||||
<span class="<?= $cls ?>"><?= date('Y-m-d', $due) ?></span>
|
||||
</td>
|
||||
<td><span class="badge bg-warning text-dark">نشط</span></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($loan['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($loan['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<form method="POST" onsubmit="return confirm('هل استلمت المواد المرجعة؟ سيتم إضافتها للمخزون.')">
|
||||
<input type="hidden" name="action" value="return">
|
||||
|
||||
@ -33,7 +33,9 @@ $modules = [
|
||||
'expenses' => 'المصروفات',
|
||||
'expense_settings' => 'المصروفات - الإعدادات',
|
||||
'meetings' => 'الاجتماعات',
|
||||
'committees' => 'اللجان'
|
||||
'committees' => 'اللجان',
|
||||
'charity_members' => 'أعضاء الجمعية',
|
||||
'charity_plans' => 'الخطط والأهداف'
|
||||
];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
@ -242,6 +244,8 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id']))
|
||||
<th>البريد الإلكتروني</th>
|
||||
<th>الدور</th>
|
||||
<th>تاريخ الإنشاء</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-plus me-1"></i>أضيف بواسطة</th>
|
||||
<th class="text-secondary text-nowrap" style="font-size: 0.85rem;"><i class="fas fa-user-edit me-1"></i>عُدل بواسطة</th>
|
||||
<th class="pe-4 text-center">الإجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -270,6 +274,8 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id']))
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= $user['created_at'] ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($user['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($user['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="pe-4 text-center">
|
||||
<?php if (canEdit('users')): ?>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary"
|
||||
|
||||
@ -19,6 +19,22 @@ if (!$committee) {
|
||||
redirect('committees.php');
|
||||
}
|
||||
|
||||
// Check membership for non-admins
|
||||
if (!isAdmin()) {
|
||||
$check_stmt = $db->prepare("
|
||||
SELECT 1
|
||||
FROM committee_members m
|
||||
JOIN charity_members cm ON m.charity_member_id = cm.id
|
||||
JOIN users u ON (u.id = cm.user_id) OR (cm.email != '' AND cm.email = u.email) OR (cm.name = u.full_name) OR (cm.name = u.username)
|
||||
WHERE m.committee_id = ? AND u.id = ?
|
||||
");
|
||||
$check_stmt->execute([$id, $_SESSION['user_id']]);
|
||||
if (!$check_stmt->fetchColumn()) {
|
||||
$_SESSION['error'] = 'غير مصرح لك بعرض هذه اللجنة';
|
||||
redirect('committees.php');
|
||||
}
|
||||
}
|
||||
|
||||
$tab = $_GET['tab'] ?? 'members';
|
||||
$allowed_tabs = ['members', 'plans', 'activities'];
|
||||
if (!in_array($tab, $allowed_tabs)) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user