38808-vm/charity_plans.php
Flatlogic Bot 6ae92a7546 update ai
2026-04-14 06:44:14 +00:00

431 lines
25 KiB
PHP

<?php
require_once 'includes/header.php';
// Auto-fix existing records that have NULL created_by/updated_by
try {
if (db()->query("SELECT COUNT(*) FROM charity_plans WHERE created_by IS NULL OR updated_by IS NULL")->fetchColumn() > 0) {
db()->query("UPDATE charity_plans SET created_by = 1 WHERE created_by IS NULL");
db()->query("UPDATE charity_plans SET updated_by = 1 WHERE updated_by IS NULL");
}
} catch (Exception $e) {}
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('charity_plans'))) {
$title = $_POST['title'];
$description = $_POST['description'] ?? '';
$start_date = $_POST['start_date'] ?? date('Y-m-d');
$end_date = $_POST['end_date'] ?? date('Y-m-d', strtotime('+1 month'));
$target_value = (int)$_POST['target_value'];
$achieved_value = (int)($_POST['achieved_value'] ?? 0);
$status = $_POST['status'] ?? 'pending';
$stmt = db()->prepare("INSERT INTO charity_plans (title, description, start_date, end_date, target_value, achieved_value, status, created_by, updated_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$title, $description, $start_date, $end_date, $target_value, $achieved_value, $status, $_SESSION['user_id'], $_SESSION['user_id']]);
$_SESSION['success'] = "تمت إضافة الخطة بنجاح.";
redirect('charity_plans.php');
} elseif (isset($_POST['edit_plan']) && (isAdmin() || canEdit('charity_plans'))) {
$id = $_POST['id'];
$title = $_POST['title'];
$description = $_POST['description'] ?? '';
$start_date = $_POST['start_date'] ?? date('Y-m-d');
$end_date = $_POST['end_date'] ?? date('Y-m-d');
$target_value = (int)$_POST['target_value'];
$achieved_value = (int)($_POST['achieved_value'] ?? 0);
$status = $_POST['status'] ?? 'pending';
$stmt = db()->prepare("UPDATE charity_plans SET title = ?, description = ?, start_date = ?, end_date = ?, target_value = ?, achieved_value = ?, status = ?, updated_by = ? WHERE id = ?");
$stmt->execute([$title, $description, $start_date, $end_date, $target_value, $achieved_value, $status, $_SESSION['user_id'], $id]);
$_SESSION['success'] = "تم تحديث الخطة بنجاح.";
redirect('charity_plans.php');
} elseif (isset($_POST['delete_plan']) && (isAdmin() || canDelete('charity_plans'))) {
$id = $_POST['id'];
$stmt = db()->prepare("DELETE FROM charity_plans WHERE id = ?");
$stmt->execute([$id]);
$_SESSION['success'] = "تم حذف الخطة بنجاح.";
redirect('charity_plans.php');
}
}
$stmt = db()->query("SELECT * FROM charity_plans ORDER BY created_at DESC");
$plans = $stmt->fetchAll();
$total_plans = count($plans);
$completed_plans = 0;
$total_target = 0;
$total_achieved = 0;
foreach ($plans as $plan) {
if ($plan['status'] === 'completed') {
$completed_plans++;
}
$total_target += $plan['target_value'];
$total_achieved += $plan['achieved_value'];
}
$completion_rate = $total_plans > 0 ? round(($completed_plans / $total_plans) * 100) : 0;
$kpi_score = $total_target > 0 ? min(100, round(($total_achieved / $total_target) * 100)) : 0;
$overall_score = round(($completion_rate * 0.4) + ($kpi_score * 0.6));
$status_colors = [
'pending' => 'secondary',
'in_progress' => 'warning',
'completed' => 'success',
'cancelled' => 'danger'
];
$status_labels = [
'pending' => 'قيد الانتظار',
'in_progress' => 'قيد التنفيذ',
'completed' => 'مكتمل',
'cancelled' => 'ملغي'
];
?>
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="h4 mb-0"><i class="fas fa-chart-line text-success me-2"></i> خطط وتقييم الجمعية (KPI)</h2>
<div>
<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('charity_plans')): ?>
<button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#addPlanModal">
<i class="fas fa-plus me-2"></i> إضافة خطة/هدف جديد
</button>
<?php endif; ?>
</div>
</div>
<?php if (isset($_SESSION['success'])): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<?= htmlspecialchars($_SESSION['success'] ?? '') ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php unset($_SESSION['success']); ?>
<?php endif; ?>
<!-- KPI Dashboard -->
<div class="row mb-4">
<div class="col-md-4 mb-3 mb-md-0">
<div class="card border-0 shadow-sm h-100 bg-primary text-white text-center p-4">
<h5 class="opacity-75">التقييم العام للجمعية</h5>
<h1 class="display-3 fw-bold mb-0"><?= $overall_score ?>%</h1>
<div class="mt-3">
<?php if ($overall_score >= 85): ?>
<i class="fas fa-medal fa-2x text-warning"></i> <span class="ms-2">أداء متميز</span>
<?php elseif ($overall_score >= 60): ?>
<i class="fas fa-thumbs-up fa-2x text-info"></i> <span class="ms-2">أداء جيد</span>
<?php else: ?>
<i class="fas fa-exclamation-circle fa-2x text-danger"></i> <span class="ms-2">بحاجة لتحسين</span>
<?php endif; ?>
</div>
</div>
</div>
<div class="col-md-4 mb-3 mb-md-0">
<div class="card border-0 shadow-sm h-100 text-center p-4">
<h5 class="text-muted">معدل الإنجاز (المستهدف)</h5>
<div class="position-relative mx-auto mt-3" style="width: 120px; height: 120px;">
<svg viewBox="0 0 36 36" class="circular-chart text-success" style="width: 100%; height: 100%;">
<path class="circle-bg" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="#eee" stroke-width="3"/>
<path class="circle" stroke-dasharray="<?= $kpi_score ?>, 100" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="currentColor" stroke-width="3" />
<text x="18" y="20.35" class="percentage" font-size="8" text-anchor="middle" fill="currentColor"><?= $kpi_score ?>%</text>
</svg>
</div>
<p class="small text-muted mt-2">إجمالي المحقق: <?= $total_achieved ?> من <?= $total_target ?></p>
</div>
</div>
<div class="col-md-4">
<div class="card border-0 shadow-sm h-100 text-center p-4">
<h5 class="text-muted">إنجاز الخطط (الحالة)</h5>
<div class="position-relative mx-auto mt-3" style="width: 120px; height: 120px;">
<svg viewBox="0 0 36 36" class="circular-chart text-info" style="width: 100%; height: 100%;">
<path class="circle-bg" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="#eee" stroke-width="3"/>
<path class="circle" stroke-dasharray="<?= $completion_rate ?>, 100" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="currentColor" stroke-width="3" />
<text x="18" y="20.35" class="percentage" font-size="8" text-anchor="middle" fill="currentColor"><?= $completion_rate ?>%</text>
</svg>
</div>
<p class="small text-muted mt-2">خطط مكتملة: <?= $completed_plans ?> من <?= $total_plans ?></p>
</div>
</div>
</div>
<!-- Plans List -->
<div class="card border-0 shadow-sm">
<div class="card-header bg-white border-bottom-0 pt-4 pb-0">
<h5 class="mb-0">سجل الخطط والأهداف</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover align-middle">
<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 class="text-end">الإجراءات</th>
</tr>
</thead>
<tbody>
<?php foreach ($plans as $plan):
$plan_rate = $plan['target_value'] > 0 ? min(100, round(($plan['achieved_value'] / $plan['target_value']) * 100)) : 0;
?>
<tr>
<td>
<div class="fw-bold"><?= htmlspecialchars($plan['title'] ?? '') ?></div>
<div class="small text-muted text-truncate" style="max-width: 250px;"><?= htmlspecialchars($plan['description'] ?? '') ?></div>
</td>
<td>
<div class="small"><i class="fas fa-calendar-alt text-muted me-1"></i> من: <?= $plan['start_date'] ?></div>
<div class="small"><i class="fas fa-flag-checkered text-muted me-1"></i> إلى: <?= $plan['end_date'] ?></div>
</td>
<td class="fw-bold"><?= number_format($plan['target_value']) ?></td>
<td class="fw-bold text-success"><?= number_format($plan['achieved_value']) ?></td>
<td>
<div class="progress" style="height: 8px; width: 80px;" title="<?= $plan_rate ?>%">
<div class="progress-bar bg-success" role="progressbar" style="width: <?= $plan_rate ?>%"></div>
</div>
<div class="small text-muted mt-1"><?= $plan_rate ?>%</div>
</td>
<td>
<span class="badge bg-<?= $status_colors[$plan['status']] ?> bg-opacity-10 text-<?= $status_colors[$plan['status']] ?> px-3 py-2 rounded-pill">
<?= $status_labels[$plan['status']] ?>
</span>
</td>
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($plan['created_by'] ?? $plan['updated_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('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>
<?php endif; ?>
</td>
</tr>
<!-- Edit Modal -->
<div class="modal fade" id="editPlanModal<?= $plan['id'] ?>" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content border-0 shadow">
<div class="modal-header bg-light">
<h5 class="modal-title">تحديث الخطة والهدف</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form method="POST">
<div class="modal-body">
<input type="hidden" name="id" value="<?= $plan['id'] ?>">
<input type="hidden" name="edit_plan" value="1">
<div class="mb-3">
<label class="form-label">العنوان</label>
<input type="text" class="form-control" name="title" id="title_edit_<?= $plan['id'] ?>" value="<?= htmlspecialchars($plan['title'] ?? '') ?>" required>
</div>
<div class="mb-3">
<div class="d-flex justify-content-between align-items-center mb-1">
<label class="form-label fw-bold mb-0">الوصف</label>
<button type="button" class="btn btn-sm btn-outline-primary" id="btn_desc_edit_<?= $plan['id'] ?>" onclick="generatePlanDesc('edit', <?= $plan['id'] ?>)">
<i class="fas fa-magic"></i> توليد الوصف بـ AI
</button>
</div>
<textarea class="form-control" name="description" id="desc_edit_<?= $plan['id'] ?>" rows="2"><?= htmlspecialchars($plan['description'] ?? '') ?></textarea>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">تاريخ البداية</label>
<input type="date" class="form-control" name="start_date" value="<?= $plan['start_date'] ?>" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">تاريخ النهاية المتوقع</label>
<input type="date" class="form-control" name="end_date" value="<?= $plan['end_date'] ?>" required>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">الرقم المستهدف (KPI)</label>
<input type="number" class="form-control" name="target_value" value="<?= $plan['target_value'] ?>" required min="1">
</div>
<div class="col-md-6 mb-3">
<label class="form-label">الرقم المحقق الفعلي</label>
<input type="number" class="form-control" name="achieved_value" value="<?= $plan['achieved_value'] ?>" required min="0">
</div>
</div>
<div class="mb-3">
<label class="form-label">الحالة</label>
<select class="form-select" name="status">
<?php foreach ($status_labels as $k => $v): ?>
<option value="<?= $k ?>" <?= $plan['status'] == $k ? 'selected' : '' ?>><?= $v ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">إلغاء</button>
<button type="submit" class="btn btn-primary">حفظ التحديث</button>
</div>
</form>
</div>
</div>
</div>
<!-- Delete Modal -->
<div class="modal fade" id="deletePlanModal<?= $plan['id'] ?>" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content border-0 shadow">
<div class="modal-header bg-light">
<h5 class="modal-title">تأكيد الحذف</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body text-center p-4">
<i class="fas fa-exclamation-triangle text-danger fa-3x mb-3"></i>
<h4 class="mb-3">هل أنت متأكد؟</h4>
<p class="text-muted">لن تتمكن من استعادة هذه الخطة بعد حذفها.</p>
</div>
<div class="modal-footer justify-content-center border-0">
<form method="POST">
<input type="hidden" name="id" value="<?= $plan['id'] ?>">
<input type="hidden" name="delete_plan" value="1">
<button type="button" class="btn btn-light px-4" data-bs-dismiss="modal">إلغاء</button>
<button type="submit" class="btn btn-danger px-4">نعم، احذف</button>
</form>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
<?php if (empty($plans)): ?>
<tr>
<td colspan="9" class="text-center text-muted py-4">لا توجد خطط مضافة حتى الآن</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- Add Modal -->
<div class="modal fade" id="addPlanModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content border-0 shadow">
<div class="modal-header bg-light">
<h5 class="modal-title">إضافة خطة/هدف جديد</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form method="POST">
<div class="modal-body">
<input type="hidden" name="add_plan" value="1">
<div class="mb-3">
<label class="form-label">العنوان</label>
<input type="text" class="form-control" name="title" id="title_add" required placeholder="مثال: كفالة 100 يتيم خلال العام">
</div>
<div class="mb-3">
<div class="d-flex justify-content-between align-items-center mb-1">
<label class="form-label fw-bold mb-0">الوصف</label>
<button type="button" class="btn btn-sm btn-outline-primary" id="btn_desc_add" onclick="generatePlanDesc('add', null)">
<i class="fas fa-magic"></i> توليد الوصف بـ AI
</button>
</div>
<textarea class="form-control" name="description" id="desc_add" rows="2"></textarea>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">تاريخ البداية</label>
<input type="date" class="form-control" name="start_date" value="<?= date('Y-m-d') ?>" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">تاريخ النهاية المتوقع</label>
<input type="date" class="form-control" name="end_date" value="<?= date('Y-m-d', strtotime('+1 year')) ?>" required>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">الرقم المستهدف (KPI)</label>
<input type="number" class="form-control" name="target_value" value="100" required min="1">
<div class="form-text">مثال: 100 (للتعبير عن 100 يتيم أو 100%)</div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">الرقم المحقق الفعلي</label>
<input type="number" class="form-control" name="achieved_value" value="0" required min="0">
</div>
</div>
<div class="mb-3">
<label class="form-label">الحالة</label>
<select class="form-select" name="status">
<option value="pending">قيد الانتظار</option>
<option value="in_progress">قيد التنفيذ</option>
<option value="completed">مكتمل</option>
<option value="cancelled">ملغي</option>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">إلغاء</button>
<button type="submit" class="btn btn-primary">إضافة الخطة</button>
</div>
</form>
</div>
</div>
</div>
<!-- AI Generation Script -->
<script>
async function generatePlanDesc(type, id) {
const titleInputId = type === 'add' ? 'title_add' : 'title_edit_' + id;
const descFieldId = type === 'add' ? 'desc_add' : 'desc_edit_' + id;
const btnId = type === 'add' ? 'btn_desc_add' : 'btn_desc_edit_' + id;
const titleInput = document.getElementById(titleInputId);
const title = titleInput.value.trim();
if (!title) {
alert("يرجى إدخال عنوان الخطة أولاً لتوليد الوصف.");
titleInput.focus();
return;
}
const btn = document.getElementById(btnId);
const descField = document.getElementById(descFieldId);
const originalText = btn.innerHTML;
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> جاري التوليد...';
btn.disabled = true;
try {
const response = await fetch("api/generate_plan_details.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: title })
});
const data = await response.json();
if (data.success) {
descField.value = data.description;
} else {
alert(data.error || "حدث خطأ أثناء توليد الوصف.");
}
} catch (error) {
console.error("Error:", error);
alert("حدث خطأ في الاتصال بالخادم.");
} finally {
btn.innerHTML = originalText;
btn.disabled = false;
}
}
</script>
<?php require_once 'includes/footer.php'; ?>