From 2f04e1c8d561fc81e78dd868ef9fd7324274ae8a Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Tue, 21 Apr 2026 07:43:36 +0000 Subject: [PATCH] Autosave: 20260421-074336 --- assessment_categories.php | 273 ++++++ center_assessment_print_sheet.php | 785 ++++++++++++++++++ center_assessment_score_sheet.php | 15 + center_assessments.php | 155 +++- .../20260417_assessment_categories.sql | 22 + execute_global_assessment.php | 52 +- includes/app.php | 25 +- includes/sidebar.php | 5 + patch_app3.php | 54 ++ 9 files changed, 1322 insertions(+), 64 deletions(-) create mode 100644 assessment_categories.php create mode 100644 center_assessment_print_sheet.php create mode 100644 db/migrations/20260417_assessment_categories.sql create mode 100644 patch_app3.php diff --git a/assessment_categories.php b/assessment_categories.php new file mode 100644 index 0000000..4bb9986 --- /dev/null +++ b/assessment_categories.php @@ -0,0 +1,273 @@ + +
+
+

عذراً

+

هذه الصفحة مخصصة للمشرف العام فقط.

+ العودة للرئيسية +
+
+ prepare('INSERT INTO assessment_categories (name, description, status) VALUES (?, ?, ?)'); + $stmt->execute([$name, $description, $status]); + set_flash('success', 'تمت إضافة الفئة بنجاح.'); + } else { + set_flash('error', 'اسم الفئة مطلوب.'); + } + header('Location: assessment_categories.php'); + exit; + } + + if ($action === 'edit') { + $id = (int)($_POST['id'] ?? 0); + $name = clean_text($_POST['name'] ?? '', 255); + $description = clean_text($_POST['description'] ?? '', 1000); + $status = in_array($_POST['status'] ?? '', ['enabled', 'disabled']) ? $_POST['status'] : 'enabled'; + + if ($id > 0 && $name !== '') { + $stmt = db()->prepare('UPDATE assessment_categories SET name = ?, description = ?, status = ? WHERE id = ?'); + $stmt->execute([$name, $description, $status, $id]); + set_flash('success', 'تم تحديث الفئة بنجاح.'); + } else { + set_flash('error', 'تأكد من إدخال اسم الفئة.'); + } + header('Location: assessment_categories.php'); + exit; + } + + if ($action === 'delete') { + $id = (int)($_POST['id'] ?? 0); + if ($id > 0) { + $stmt = db()->prepare('DELETE FROM assessment_categories WHERE id = ?'); + $stmt->execute([$id]); + set_flash('success', 'تم حذف الفئة بنجاح.'); + } + header('Location: assessment_categories.php'); + exit; + } +} + +// Read list +$search = clean_text($_GET['search'] ?? '', 255); +$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT) ?: 1; +$limit = 10; +$offset = ($page - 1) * $limit; + +$query = 'SELECT * FROM assessment_categories'; +$countQuery = 'SELECT COUNT(*) FROM assessment_categories'; +$params = []; +if ($search !== '') { + $where = ' WHERE name LIKE ? OR description LIKE ?'; + $query .= $where; + $countQuery .= $where; + $params[] = "%$search%"; + $params[] = "%$search%"; +} + +$stmtCount = db()->prepare($countQuery); +$stmtCount->execute($params); +$totalItems = (int)$stmtCount->fetchColumn(); + +$query .= ' ORDER BY id DESC LIMIT ' . $limit . ' OFFSET ' . $offset; +$stmt = db()->prepare($query); +$stmt->execute($params); +$assessment_categories = $stmt->fetchAll(); + +$flash = consume_flash(); +render_page_start('فئات التقييم', 'assessment_categories', 'إدارة فئات التقييم الخاصة بالمراكز'); +render_flash($flash); +?> +
+
+
+
+ +
+
+
+
+
إدارة فئات التقييم
+ +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
#الاسمالوصفالحالةالإجراءات
لا توجد مواد مسجلة أو لم يتم العثور على نتائج.
+ + مفعل + + معطل + + +
+ + + +
+ + + +
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + diff --git a/center_assessment_print_sheet.php b/center_assessment_print_sheet.php new file mode 100644 index 0000000..4285e9c --- /dev/null +++ b/center_assessment_print_sheet.php @@ -0,0 +1,785 @@ + 0 ? get_application($applicationId) : null; +$isApprovedCenter = $application && (string) ($application['status'] ?? '') === 'approved'; +$cycleContext = ['cycles' => [], 'selected' => null, 'active' => null, 'read_only' => false]; +$selectedCycle = null; +$selectedCycleId = 0; +$cycleLabel = 'لا توجد دورة بعد'; + +$buildCenterAssessmentsUrl = static function (int $targetApplicationId = 0, int $targetCycleId = 0): string { + $params = []; + if ($targetApplicationId > 0) { + $params['id'] = $targetApplicationId; + } + if ($targetCycleId > 0) { + $params['cycle'] = $targetCycleId; + } + return 'center_assessments.php' . ($params !== [] ? '?' . http_build_query($params) : ''); +}; + +$buildCenterAssessmentScoreUrl = static function (int $targetApplicationId = 0, int $targetCycleId = 0, int $targetAssessmentId = 0): string { + $params = []; + if ($targetApplicationId > 0) { + $params['id'] = $targetApplicationId; + } + if ($targetCycleId > 0) { + $params['cycle'] = $targetCycleId; + } + if ($targetAssessmentId > 0) { + $params['assessment_id'] = $targetAssessmentId; + } + return 'center_assessment_score_sheet.php' . ($params !== [] ? '?' . http_build_query($params) : ''); +}; + +if (!$application || !$isApprovedCenter || $requestedCycleId <= 0 || $requestedAssessmentId <= 0) { + set_flash('error', 'اختر مركزاً ودورة وتقييماً صحيحاً لفتح ورقة الطباعة.'); + header('Location: ' . $buildCenterAssessmentsUrl($applicationId, $requestedCycleId)); + exit; +} + +$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) : $cycleLabel; + +if ($selectedCycleId <= 0) { + set_flash('error', 'تعذر تحديد الدورة المطلوبة لورقة الطباعة.'); + header('Location: ' . $buildCenterAssessmentsUrl((int) $application['id'], $requestedCycleId)); + exit; +} + +$selectedAssessment = null; +foreach (list_center_assessments_by_cycle((int) $application['id'], $selectedCycleId) as $assessment) { + if ((int) ($assessment['id'] ?? 0) === $requestedAssessmentId) { + $selectedAssessment = $assessment; + break; + } +} + +if (!$selectedAssessment) { + set_flash('error', 'تعذر العثور على التقييم المطلوب لطباعة النموذج.'); + header('Location: ' . $buildCenterAssessmentsUrl((int) $application['id'], $selectedCycleId)); + exit; +} + +$criteria = list_center_assessment_criteria_by_assessment((int) $application['id'], $selectedCycleId, $requestedAssessmentId, true); +$scoreBundle = center_assessment_score_bundle_by_assessment((int) $application['id'], $selectedCycleId, $requestedAssessmentId); +$scoreRow = $scoreBundle['score'] ?? null; +$criteriaScores = $scoreBundle['criteria_scores'] ?? []; +$statusKey = center_assessment_normalize_status((string) ($scoreRow['status'] ?? 'pending')); +$statusMeta = center_assessment_status_map()[$statusKey] ?? ['label' => 'غير محدد']; +$totalScore = isset($scoreRow['score']) && $scoreRow['score'] !== null ? (float) $scoreRow['score'] : null; +$maxScore = isset($scoreRow['max_score']) && $scoreRow['max_score'] !== null + ? (float) $scoreRow['max_score'] + : (float) ($selectedAssessment['max_score'] ?? 0); +if ($criteria !== []) { + $criteriaMax = 0.0; + foreach ($criteria as $criterion) { + $criteriaMax += (float) ($criterion['max_score'] ?? 0); + } + $maxScore = $criteriaMax > 0 ? $criteriaMax : $maxScore; +} +$percentage = $totalScore !== null && $maxScore > 0 ? round(($totalScore / $maxScore) * 100, 2) : null; +$notes = trim((string) ($scoreRow['notes'] ?? '')); +$assessmentDate = (string) ($scoreRow['assessed_on'] ?? ''); +$settings = get_app_settings(); +$projectName = (string) (!empty($settings['app_name']) ? $settings['app_name'] : project_name()); +$projectLogo = (string) ($settings['app_logo'] ?? ''); +$pageTitle = 'ورقة متابعة تقييم المركز — ' . (string) ($selectedAssessment['title'] ?? ''); +$pageDescription = 'نموذج رسمي قابل للطباعة لتوثيق تقييم المركز والتوقيعات وخطة المتابعة الإدارية.'; +$generatedAt = date('Y-m-d H:i'); +$scoreSheetUrl = $buildCenterAssessmentScoreUrl((int) $application['id'], $selectedCycleId, $requestedAssessmentId); +?> + + + + + + <?= e($pageTitle) ?> | <?= e($projectName) ?> + + + + + + + + +
+
+
ورقة تقييم قابلة للطباعة
+
نموذج رسمي للتوقيعات وخطة المتابعة الإدارية.
+
+ +
+ +
+
+
+
+
+ + <?= e($projectName) ?> + + + +
+
نموذج رسمي معتمد للمتابعة
+

ورقة تقييم ومتابعة إدارية للمركز

+

— توثيق نتيجة التقييم وخطوات المتابعة والتوقيعات.

+
+
+
+
+
رقم المركز#
+
الدورة
+
تاريخ التقييم
+
تاريخ الطباعة
+
الحالة
+
+
+ + + +
+
+

تفاصيل البنود

+

+
+
+ + + + + + + + + + + + + $criterion): ?> + + + + + + + + + + + + + + + + + + + +
#البند / المعيارالدرجة القصوىالدرجة المرصودةملاحظات مختصرة
+
+
+
1................................................................
+
+
+ + + +
+
+

التوقيعات والاعتماد

+

للاستخدام الرسمي بين المقيم وإدارة المركز والإدارة المشرفة.

+
+
+
+
+
المقيم / المشرف
+
+
الاسم والتوقيع
+
+
التاريخ
+
+
+
مدير المركز
+
+
الاسم والتوقيع
+
+
التاريخ
+
+
+
اعتماد الإدارة
+
+
الاسم والتوقيع
+
+
التاريخ
+
+
+
متابعة الإغلاق
+
+
تمت المراجعة / أغلقت الملاحظات
+
+
التاريخ
+
+
+
+
+ + +
+
+ + diff --git a/center_assessment_score_sheet.php b/center_assessment_score_sheet.php index 08da428..6157b6d 100644 --- a/center_assessment_score_sheet.php +++ b/center_assessment_score_sheet.php @@ -87,6 +87,20 @@ $buildCenterAssessmentReportUrl = static function (int $targetApplicationId = 0, return 'center_assessment_report.php' . ($params !== [] ? '?' . http_build_query($params) : ''); }; +$buildCenterAssessmentPrintUrl = static function (int $targetApplicationId = 0, int $targetCycleId = 0, int $targetAssessmentId = 0): string { + $params = []; + if ($targetApplicationId > 0) { + $params['id'] = $targetApplicationId; + } + if ($targetCycleId > 0) { + $params['cycle'] = $targetCycleId; + } + if ($targetAssessmentId > 0) { + $params['assessment_id'] = $targetAssessmentId; + } + return 'center_assessment_print_sheet.php' . ($params !== [] ? '?' . http_build_query($params) : ''); +}; + if ($applicationId <= 0 || $requestedCycleId <= 0) { set_flash('error', 'اختر المركز والدورة أولاً ثم افتح صفحة رصد التقييم من شاشة تقييم المراكز.'); header('Location: ' . $buildCenterAssessmentsUrl($applicationId, $requestedCycleId)); @@ -260,6 +274,7 @@ render_flash($flash); كل التقييمات تقرير الدورة + طباعة النموذج الرسمي إدارة البنود diff --git a/center_assessments.php b/center_assessments.php index ab147bb..b352b03 100644 --- a/center_assessments.php +++ b/center_assessments.php @@ -59,6 +59,20 @@ $buildCenterAssessmentReportUrl = static function (int $targetApplicationId = 0, return 'center_assessment_report.php' . ($params !== [] ? '?' . http_build_query($params) : ''); }; +$buildCenterAssessmentPrintUrl = static function (int $targetApplicationId = 0, int $targetCycleId = 0, int $targetAssessmentId = 0): string { + $params = []; + if ($targetApplicationId > 0) { + $params['id'] = $targetApplicationId; + } + if ($targetCycleId > 0) { + $params['cycle'] = $targetCycleId; + } + if ($targetAssessmentId > 0) { + $params['assessment_id'] = $targetAssessmentId; + } + return 'center_assessment_print_sheet.php' . ($params !== [] ? '?' . http_build_query($params) : ''); +}; + $buildCenterAssessmentCriteriaUrl = static function (int $targetApplicationId = 0, int $targetCycleId = 0, int $targetAssessmentId = 0): string { $params = []; if ($targetApplicationId > 0) { @@ -166,6 +180,49 @@ $pageDescription = 'إدارة تقييمات إشرافية مستقلة للم render_page_start($pageTitle, 'admin', $pageDescription); render_flash($flash); ?> +
@@ -177,7 +234,6 @@ render_flash($flash);
- مرحلة 2 — التقييم + البنود

إدارة تقييمات المراكز

هذه الصفحة تضيف طبقة مستقلة لتقييم المراكز المعتمدة حسب الدورة الموسمية، بدون خلطها مع تقييمات الطلاب. يمكنك الآن تعريف أنواع تقييم المراكز وأوزانها ثم فتح بنود كل تقييم بنفس النمط المستخدم في تقييم الطلاب، تمهيداً لصفحة الرصد الفعلي.

@@ -212,12 +268,6 @@ render_flash($flash);
-
-
إجمالي التقييمات
كل الأنواع المعرفة للمركز المحدد.
-
تقييمات نشطة
جاهزة لربط البنود ثم الرصد.
-
إجمالي الوزن النشط
٪
للمراجعة قبل تفعيل الرصد.
-
متوسط الدرجة القصوى
متوسط السقف لكل تقييم مركز.
-
@@ -300,8 +350,6 @@ render_flash($flash);
-
أصبحت دورة تقييم المراكز مكتملة: تعريف التقييم ثم البنود ثم الرصد ثم تقرير ملخّص للدورة.
-
لا توجد تقييمات مراكز بعد
@@ -317,9 +365,7 @@ render_flash($flash); التقييم الفئة - المقياس - الدرجة - الوزن + الدرجة والوزن البنود الحالة الإجراء @@ -330,29 +376,75 @@ render_flash($flash);
- -
- - - - - ٪ -
-
المجموع
+
+
+ + +
+
وزن ٪
+ + + -
- البنود - رصد +
+ + + إدارة البنود + + + + رصد الدرجات + + + + طباعة النموذج الرسمي + + > + + تعديل التقييم + - قراءة فقط + قراءة فقط
@@ -522,6 +619,10 @@ render_flash($flash);