252 lines
14 KiB
PHP
252 lines
14 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/includes/app.php';
|
|
|
|
function certificate_date_label(string $date): string
|
|
{
|
|
if ($date === '' || strtotime($date) === false) {
|
|
return '—';
|
|
}
|
|
|
|
return date('Y/m/d', strtotime($date));
|
|
}
|
|
|
|
function certificate_number_value(int $value): string
|
|
{
|
|
return number_format($value);
|
|
}
|
|
|
|
function certificate_decimal_value(float $value): string
|
|
{
|
|
return rtrim(rtrim(number_format($value, 2, '.', ''), '0'), '.');
|
|
}
|
|
|
|
$flash = consume_flash();
|
|
$applicationId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT) ?: 0;
|
|
$requestedCycleId = filter_input(INPUT_GET, 'cycle', FILTER_VALIDATE_INT) ?: 0;
|
|
$studentId = filter_input(INPUT_GET, 'student_id', FILTER_VALIDATE_INT) ?: 0;
|
|
$application = $applicationId > 0 ? get_application($applicationId) : null;
|
|
$isApprovedSchool = $application && (string) $application['status'] === 'approved';
|
|
$cycleContext = ['cycles' => [], 'selected' => null, 'active' => null, 'read_only' => false];
|
|
$selectedCycle = null;
|
|
$selectedCycleId = 0;
|
|
$cycleLabel = 'لا توجد دورة بعد';
|
|
|
|
if ($application && $isApprovedSchool) {
|
|
$cycleContext = resolve_school_cycle_context((int) $application['id'], $application, $requestedCycleId);
|
|
$selectedCycle = $cycleContext['selected'];
|
|
$selectedCycleId = $selectedCycle ? (int) ($selectedCycle['id'] ?? 0) : 0;
|
|
$cycleLabel = $selectedCycle ? (string) $selectedCycle['cycle_name'] : $cycleLabel;
|
|
}
|
|
|
|
$certificate = $isApprovedSchool && $selectedCycleId > 0 && $studentId > 0
|
|
? school_student_certificate_summary((int) $application['id'], $selectedCycleId, $studentId)
|
|
: [
|
|
'student' => null,
|
|
'assessments' => [],
|
|
'has_results' => false,
|
|
'completed_assessments' => 0,
|
|
'active_assessments' => 0,
|
|
'missing_assessments' => 0,
|
|
'absent_assessments' => 0,
|
|
'excused_assessments' => 0,
|
|
'overall_percentage' => 0.0,
|
|
'score_total' => 0.0,
|
|
'max_score_total' => 0.0,
|
|
'latest_assessed_on' => '',
|
|
'performance' => student_certificate_performance_meta(0.0),
|
|
];
|
|
$student = is_array($certificate['student'] ?? null) ? $certificate['student'] : null;
|
|
|
|
if (!$application || !$isApprovedSchool || $selectedCycleId <= 0 || $studentId <= 0 || $student === null) {
|
|
http_response_code(404);
|
|
}
|
|
|
|
$pageTitle = $student
|
|
? 'شهادة الطالب: ' . (string) $student['full_name']
|
|
: 'شهادة الإنجاز';
|
|
$pageDescription = 'شهادة إنجاز قابلة للطباعة تعرض أداء الطالب الإجمالي بعد انتهاء الدورة، مع تصنيف الأداء النهائي وملخص التقييمات.';
|
|
$studentsUrl = $application ? school_page_url('students.php', (int) $application['id'], $selectedCycleId) : 'students.php';
|
|
$approvedSchoolUrl = $application ? school_page_url('approved_school.php', (int) $application['id'], $selectedCycleId) : 'approved_school.php';
|
|
$performance = $certificate['performance'] ?? student_certificate_performance_meta(0.0);
|
|
$issuedOn = date('Y-m-d');
|
|
$coverageNote = '';
|
|
if (($certificate['missing_assessments'] ?? 0) > 0) {
|
|
$coverageNote = 'يعتمد هذا التقدير على التقييمات المرصودة حالياً فقط.';
|
|
} elseif (($certificate['completed_assessments'] ?? 0) > 0) {
|
|
$coverageNote = 'تم احتساب الأداء النهائي من متوسط التقييمات المرصودة في هذه الدورة.';
|
|
}
|
|
|
|
render_page_start($pageTitle, 'approved', $pageDescription);
|
|
render_flash($flash);
|
|
?>
|
|
<section class="student-certificate-page py-4 py-lg-5">
|
|
<div class="container-xl">
|
|
<div class="certificate-toolbar">
|
|
<div>
|
|
<div class="section-title">شهادة الإنجاز والمكافأة</div>
|
|
<div class="section-subtle">صفحة قابلة للطباعة بعد إكمال تقييمات الطالب في الدورة الحالية.</div>
|
|
</div>
|
|
<div class="certificate-toolbar-actions">
|
|
<a class="btn btn-outline-secondary" href="<?= e($studentsUrl) ?>">العودة إلى الطلاب</a>
|
|
<a class="btn btn-outline-secondary" href="<?= e($approvedSchoolUrl) ?>">صفحة المركز</a>
|
|
<?php if ($student): ?>
|
|
<button type="button" class="btn btn-primary" onclick="window.print()">طباعة الشهادة</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (!$application): ?>
|
|
<div class="app-card text-center py-5">
|
|
<div class="empty-title mb-2">المركز غير موجود</div>
|
|
<p class="text-muted mb-3">تحقق من الرابط ثم حاول فتح الشهادة من جديد من صفحة الطلاب.</p>
|
|
<a class="btn btn-primary" href="applications.php?status=approved">المراكز المعتمدة</a>
|
|
</div>
|
|
<?php elseif (!$isApprovedSchool): ?>
|
|
<div class="app-card text-center py-5">
|
|
<div class="empty-title mb-2">الشهادة غير متاحة بعد</div>
|
|
<p class="text-muted mb-0">يمكن إصدار شهادات الإنجاز فقط للمراكز المعتمدة.</p>
|
|
</div>
|
|
<?php elseif ($selectedCycleId <= 0 || !$student): ?>
|
|
<div class="app-card text-center py-5">
|
|
<div class="empty-title mb-2">تعذر العثور على الطالب</div>
|
|
<p class="text-muted mb-3">ربما تم تغيير الدورة أو أن الطالب لا يتبع هذا المركز.</p>
|
|
<a class="btn btn-primary" href="<?= e($studentsUrl) ?>">العودة إلى سجل الطلاب</a>
|
|
</div>
|
|
<?php else: ?>
|
|
<article class="student-certificate-card" aria-labelledby="certificate-title">
|
|
<div class="student-certificate-body">
|
|
<span class="certificate-kicker">Certificate of Completion & Performance</span>
|
|
<h1 class="certificate-title" id="certificate-title">شهادة تكريم وإتمام الدورة</h1>
|
|
<p class="certificate-subtitle mb-0">
|
|
تشهد إدارة <strong><?= e((string) $application['center_name']) ?></strong> بأن الطالب/الطالبة
|
|
<strong><?= e((string) $student['full_name']) ?></strong>
|
|
قد أتم/أتمت متطلبات الدورة <strong><?= e($cycleLabel) ?></strong>
|
|
وتم تقييم أدائه/أدائها وفق السجلات المرصودة في النظام.
|
|
</p>
|
|
|
|
<div class="certificate-student-name"><?= e((string) $student['full_name']) ?></div>
|
|
<div class="section-subtle">Student Code: <?= e((string) $student['student_code']) ?> · <?= e((string) $student['grade_level']) ?></div>
|
|
|
|
<div class="certificate-meta-grid">
|
|
<div class="certificate-meta-item">
|
|
<strong>المركز</strong>
|
|
<span><?= e((string) $application['center_name']) ?></span>
|
|
</div>
|
|
<div class="certificate-meta-item">
|
|
<strong>الدورة</strong>
|
|
<span><?= e($cycleLabel) ?></span>
|
|
</div>
|
|
<div class="certificate-meta-item">
|
|
<strong>مدة الدورة</strong>
|
|
<span><?= e(certificate_date_label((string) ($selectedCycle['start_date'] ?? ''))) ?> — <?= e(certificate_date_label((string) ($selectedCycle['end_date'] ?? ''))) ?></span>
|
|
</div>
|
|
<div class="certificate-meta-item">
|
|
<strong>تاريخ الإصدار</strong>
|
|
<span><?= e(certificate_date_label($issuedOn)) ?></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="certificate-grid">
|
|
<div class="certificate-panel">
|
|
<strong class="mb-2">نص الشهادة</strong>
|
|
<p class="mb-3">بناءً على حضور الطالب ومشاركته ونتائج تقييماته خلال هذه الدورة، تم منحه/منحها هذه الشهادة التقديرية مع بيان مستوى الأداء العام أدناه.</p>
|
|
<div class="performance-pill performance-<?= e((string) ($performance['key'] ?? 'poor')) ?> mb-3">
|
|
<?= e((string) ($performance['label_ar'] ?? 'ضعيف')) ?> — <?= e((string) ($performance['label'] ?? 'Poor')) ?>
|
|
</div>
|
|
<div class="certificate-stat-grid">
|
|
<div class="certificate-stat">
|
|
<strong><?= e(certificate_decimal_value((float) ($certificate['overall_percentage'] ?? 0))) ?>%</strong>
|
|
<span>متوسط الأداء النهائي</span>
|
|
</div>
|
|
<div class="certificate-stat">
|
|
<strong><?= e(certificate_number_value((int) ($certificate['completed_assessments'] ?? 0))) ?></strong>
|
|
<span>تقييمات مكتملة</span>
|
|
</div>
|
|
<div class="certificate-stat">
|
|
<strong><?= e(certificate_decimal_value((float) ($certificate['score_total'] ?? 0))) ?>/<?= e(certificate_decimal_value((float) ($certificate['max_score_total'] ?? 0))) ?></strong>
|
|
<span>إجمالي الدرجات المرصودة</span>
|
|
</div>
|
|
<div class="certificate-stat">
|
|
<strong><?= e(certificate_date_label((string) ($certificate['latest_assessed_on'] ?? ''))) ?></strong>
|
|
<span>آخر تقييم مسجل</span>
|
|
</div>
|
|
</div>
|
|
<?php if ($coverageNote !== ''): ?>
|
|
<div class="alert alert-light border mt-3 mb-0"><?= e($coverageNote) ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<aside class="certificate-panel">
|
|
<strong class="mb-2">ملخص الأداء</strong>
|
|
<div class="summary-stack">
|
|
<div class="summary-row"><span>التقييمات النشطة</span><strong><?= e(certificate_number_value((int) ($certificate['active_assessments'] ?? 0))) ?></strong></div>
|
|
<div class="summary-row"><span>المكتملة</span><strong><?= e(certificate_number_value((int) ($certificate['completed_assessments'] ?? 0))) ?></strong></div>
|
|
<div class="summary-row"><span>الغياب</span><strong><?= e(certificate_number_value((int) ($certificate['absent_assessments'] ?? 0))) ?></strong></div>
|
|
<div class="summary-row"><span>بعذر</span><strong><?= e(certificate_number_value((int) ($certificate['excused_assessments'] ?? 0))) ?></strong></div>
|
|
<div class="summary-row"><span>غير المرصود بعد</span><strong><?= e(certificate_number_value((int) ($certificate['missing_assessments'] ?? 0))) ?></strong></div>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
|
|
<?php if (!empty($certificate['assessments'])): ?>
|
|
<div class="certificate-panel mt-4">
|
|
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-3">
|
|
<strong class="mb-0">تفصيل التقييمات</strong>
|
|
<span class="section-subtle">Overall performance is calculated from the recorded assessments in this course.</span>
|
|
</div>
|
|
<div class="certificate-table-wrap">
|
|
<table class="certificate-table">
|
|
<thead>
|
|
<tr>
|
|
<th>التقييم</th>
|
|
<th>الفئة</th>
|
|
<th>الدرجة</th>
|
|
<th>النسبة</th>
|
|
<th>الوزن</th>
|
|
<th>التاريخ</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($certificate['assessments'] as $assessment): ?>
|
|
<tr>
|
|
<td>
|
|
<strong><?= e((string) ($assessment['title'] ?? 'تقييم')) ?></strong>
|
|
<?php if (!empty($assessment['notes'])): ?><small><?= e((string) $assessment['notes']) ?></small><?php endif; ?>
|
|
</td>
|
|
<td><?= e((string) ($assessment['category'] ?? '—')) ?></td>
|
|
<td><?= e(certificate_decimal_value((float) ($assessment['score'] ?? 0))) ?> / <?= e(certificate_decimal_value((float) ($assessment['max_score'] ?? 0))) ?></td>
|
|
<td><?= e(certificate_decimal_value((float) ($assessment['percentage'] ?? 0))) ?>%</td>
|
|
<td><?= e(certificate_decimal_value((float) ($assessment['weight_percentage'] ?? 0))) ?>%</td>
|
|
<td><?= e(certificate_date_label((string) ($assessment['assessed_on'] ?? ''))) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="certificate-panel certificate-empty-state mt-4">
|
|
<div class="empty-title mb-2">لا توجد تقييمات مرصودة بعد</div>
|
|
<p class="text-muted mb-3">أدخل درجات الطالب أولاً من صفحة رصد الدرجات، ثم افتح الشهادة من جديد لإظهار الأداء العام.</p>
|
|
<a class="btn btn-outline-secondary" href="<?= e($studentsUrl) ?>">العودة إلى الطلاب</a>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="certificate-signature-row">
|
|
<div class="certificate-signature">
|
|
<strong>مدير/ة المركز</strong>
|
|
<span><?= e((string) ($application['director_name'] ?? '')) ?></span>
|
|
</div>
|
|
<div class="certificate-signature">
|
|
<strong>اعتماد الأداء النهائي</strong>
|
|
<span><?= e((string) ($performance['label_ar'] ?? 'ضعيف')) ?> — <?= e((string) ($performance['label'] ?? 'Poor')) ?></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
<?php endif; ?>
|
|
</div>
|
|
</section>
|
|
<?php render_page_end();
|