update center page
This commit is contained in:
parent
a55b4a5394
commit
61e8c6788b
534
assessments.php
534
assessments.php
@ -15,6 +15,15 @@ $selectedCycleId = 0;
|
||||
$isCycleReadOnly = false;
|
||||
$cycleLabel = 'لا توجد دورة بعد';
|
||||
|
||||
$available_subjects = [];
|
||||
if ($application) {
|
||||
$center_subjects_ids = is_string($application['subjects']) ? json_decode($application['subjects'], true) : [];
|
||||
if (!is_array($center_subjects_ids)) $center_subjects_ids = [];
|
||||
$center_subjects_ids = array_map('strval', $center_subjects_ids);
|
||||
$all_subjects = get_enabled_subjects();
|
||||
$available_subjects = array_filter($all_subjects, fn($s) => in_array((string)$s['id'], $center_subjects_ids, true));
|
||||
}
|
||||
|
||||
if ($application && $isApprovedSchool) {
|
||||
$cycleContext = resolve_school_cycle_context((int) $application['id'], $application, $requestedCycleId);
|
||||
$selectedCycle = $cycleContext['selected'];
|
||||
@ -24,6 +33,9 @@ if ($application && $isApprovedSchool) {
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $application) {
|
||||
$action = $_POST['action'] ?? 'add';
|
||||
$assessmentId = filter_input(INPUT_POST, 'assessment_id', FILTER_VALIDATE_INT) ?: 0;
|
||||
|
||||
[$values, $errors] = validate_assessment_input($_POST);
|
||||
|
||||
if (!$isApprovedSchool) {
|
||||
@ -36,50 +48,37 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && $application) {
|
||||
|
||||
if ($errors === []) {
|
||||
try {
|
||||
create_assessment_type_in_cycle((int) $application['id'], $selectedCycleId, $values);
|
||||
set_flash('success', 'تم حفظ نوع التقييم داخل الدورة الموسمية المحددة.');
|
||||
header('Location: ' . school_page_url('assessments.php', (int) $application['id'], $selectedCycleId));
|
||||
if ($action === 'edit' && $assessmentId > 0) {
|
||||
update_assessment_type_in_cycle((int) $application['id'], $selectedCycleId, $assessmentId, $values);
|
||||
set_flash('success', 'تم تحديث التقييم بنجاح.');
|
||||
} else {
|
||||
create_assessment_type_in_cycle((int) $application['id'], $selectedCycleId, $values);
|
||||
set_flash('success', 'تم حفظ التقييم داخل الدورة الموسمية المحددة.');
|
||||
}
|
||||
header('Location: ' . school_page_url('assessments.php', (int) $application['id'], $selectedCycleId) . '&' . http_build_query(array_intersect_key($_GET, array_flip(['search', 'category', 'subject_id', 'page']))));
|
||||
exit;
|
||||
} catch (Throwable $exception) {
|
||||
$errors['form'] = 'تعذر حفظ نوع التقييم حالياً. يرجى المحاولة مرة أخرى.';
|
||||
$errors['form'] = 'تعذر حفظ التقييم حالياً. يرجى المحاولة مرة أخرى.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$search = clean_text($_GET['search'] ?? '', 255);
|
||||
$filters = [
|
||||
'search' => clean_text($_GET['search'] ?? '', 255),
|
||||
'category' => clean_text($_GET['category'] ?? '', 80),
|
||||
'subject_id' => clean_text($_GET['subject_id'] ?? '', 20)
|
||||
];
|
||||
|
||||
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT) ?: 1;
|
||||
$limit = 10;
|
||||
$limit = 20;
|
||||
$offset = ($page - 1) * $limit;
|
||||
|
||||
$assessments = $isApprovedSchool && $selectedCycleId > 0 ? list_school_assessments_by_cycle((int) $application['id'], $selectedCycleId, $search, $limit, $offset) : [];
|
||||
$totalAssessments = $isApprovedSchool && $selectedCycleId > 0 ? count_school_assessments_by_cycle((int) $application['id'], $selectedCycleId, $search) : 0;
|
||||
$assessments = $isApprovedSchool && $selectedCycleId > 0 ? list_school_assessments_by_cycle((int) $application['id'], $selectedCycleId, $filters, $limit, $offset) : [];
|
||||
$totalAssessments = $isApprovedSchool && $selectedCycleId > 0 ? count_school_assessments_by_cycle((int) $application['id'], $selectedCycleId, $filters) : 0;
|
||||
|
||||
$metrics = $isApprovedSchool && $selectedCycleId > 0 ? school_assessment_metrics_by_cycle((int) $application['id'], $selectedCycleId) : [
|
||||
'total' => 0,
|
||||
'active' => 0,
|
||||
'inactive' => 0,
|
||||
'total_weight' => 0.0,
|
||||
'active_weight' => 0.0,
|
||||
'average_max_score' => 0.0,
|
||||
'percentage' => 0,
|
||||
'points' => 0,
|
||||
'rubric' => 0,
|
||||
];
|
||||
$studentMetrics = $isApprovedSchool && $selectedCycleId > 0 ? school_student_metrics_by_cycle((int) $application['id'], $selectedCycleId) : [
|
||||
'total' => 0,
|
||||
'boys' => 0,
|
||||
'girls' => 0,
|
||||
'active' => 0,
|
||||
'waiting' => 0,
|
||||
'withdrawn' => 0,
|
||||
];
|
||||
$teacherMetrics = $isApprovedSchool && $selectedCycleId > 0 ? school_teacher_metrics_by_cycle((int) $application['id'], $selectedCycleId) : [
|
||||
'total' => 0,
|
||||
'active' => 0,
|
||||
'pending' => 0,
|
||||
'inactive' => 0,
|
||||
'email_ready' => 0,
|
||||
'supervisors' => 0,
|
||||
'total' => 0, 'active' => 0, 'inactive' => 0, 'total_weight' => 0.0, 'active_weight' => 0.0,
|
||||
'average_max_score' => 0.0, 'percentage' => 0, 'points' => 0, 'rubric' => 0,
|
||||
];
|
||||
|
||||
$activeWeight = round((float) $metrics['active_weight'], 2);
|
||||
@ -87,10 +86,6 @@ $weightGap = round(100 - $activeWeight, 2);
|
||||
$pageTitle = $application ? 'التقييمات والأوزان: ' . (string) $application['center_name'] . ($selectedCycle ? ' — ' . $cycleLabel : '') : 'التقييمات والأوزان';
|
||||
$pageDescription = 'صفحة مستقلة لتعريف أنواع التقييم، المقاييس، والأوزان لكل مدرسة معتمدة داخل دورة موسمية محددة.';
|
||||
$approvedSchoolUrl = $application ? school_page_url('approved_school.php', (int) $application['id'], $selectedCycleId) : 'approved_school.php';
|
||||
$studentsUrl = $application ? school_page_url('students.php', (int) $application['id'], $selectedCycleId) : 'students.php';
|
||||
$teachersUrl = $application ? school_page_url('teachers.php', (int) $application['id'], $selectedCycleId) : 'teachers.php';
|
||||
$attendanceUrl = $application ? school_page_url('attendance.php', (int) $application['id'], $selectedCycleId) : 'attendance.php';
|
||||
$applicationDetailUrl = $application ? 'application_detail.php?id=' . urlencode((string) $application['id']) : 'application_detail.php';
|
||||
|
||||
if (!$application) {
|
||||
http_response_code(404);
|
||||
@ -101,11 +96,11 @@ render_flash($flash);
|
||||
?>
|
||||
<section class="py-4 py-lg-5">
|
||||
<div class="container-xxl">
|
||||
<div class="row g-4 align-items-start">
|
||||
<div class="col-lg-3">
|
||||
<div class="row g-4 align-items-start">
|
||||
<div class="col-lg-2">
|
||||
<?php if ($application) { require __DIR__ . '/includes/center_sidebar.php'; } else { require __DIR__ . '/includes/sidebar.php'; } ?>
|
||||
</div>
|
||||
<div class="col-lg-9">
|
||||
<div class="col-lg-10">
|
||||
|
||||
<?php if (!$application): ?>
|
||||
<div class="app-card text-center py-5">
|
||||
@ -114,279 +109,246 @@ render_flash($flash);
|
||||
<a class="btn btn-dark" href="applications.php?status=approved">المراكز المعتمدة</a>
|
||||
</div>
|
||||
<?php elseif (!$isApprovedSchool): ?>
|
||||
<div class="page-banner mb-4 mb-lg-5">
|
||||
<div class="page-banner mb-4">
|
||||
<div class="row g-4 align-items-center">
|
||||
<div class="col-lg-8">
|
||||
<span class="eyebrow mb-3">التقييمات تبدأ بعد الاعتماد</span>
|
||||
<h1 class="page-title mb-3"><?= e((string) $application['center_name']) ?></h1>
|
||||
<p class="page-copy mb-3">تم تجهيز صفحة أنواع التقييم، لكن استخدامها مرتبط بتحويل حالة المركز إلى <strong>معتمد</strong> أولاً حتى تبقى الخطة الأكاديمية مرتبطة فقط بالمراكز الجاهزة للتشغيل.</p>
|
||||
<div class="hero-meta">
|
||||
<span>الحالة الحالية: <?= e(status_meta((string) $application['status'])['label']) ?></span>
|
||||
<span>المدينة: <?= e((string) $application['city']) ?></span>
|
||||
</div>
|
||||
<div class="cta-stack mt-4">
|
||||
<a class="btn btn-dark" href="<?= e($applicationDetailUrl) ?>">العودة لملف الاعتماد</a>
|
||||
<a class="btn btn-outline-secondary" href="<?= e($approvedSchoolUrl) ?>">صفحة المركز</a>
|
||||
</div>
|
||||
<p class="page-copy mb-3">يجب اعتماد المركز أولاً.</p>
|
||||
<a class="btn btn-dark" href="<?= e($approvedSchoolUrl) ?>">صفحة المركز</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="page-banner approved-hero mb-4 mb-lg-5">
|
||||
<div class="row g-4 align-items-start">
|
||||
<div class="col-lg-8">
|
||||
<span class="approved-kicker mb-3">صفحة مستقلة للتقييمات والأوزان</span>
|
||||
<h1 class="page-title mb-3">خطة التقييم — <?= e((string) $application['center_name']) ?></h1>
|
||||
<p class="page-copy mb-3">هنا يتم تعريف أنواع التقييم الخاصة بالمركز بعد تجهيز الطلاب والمعلمين: اسم التقييم، فئته، المقياس المستخدم، والوزن التشغيلي ضمن الخطة الأكاديمية.</p>
|
||||
<div class="hero-meta">
|
||||
<span><?= e((string) $application['city']) ?></span>
|
||||
<span><?= e((string) $metrics['active']) ?> تقييمات مفعلة</span>
|
||||
<span>إجمالي الأوزان المفعلة <?= e(number_format($activeWeight, 2, '.', '')) ?>%</span>
|
||||
</div>
|
||||
<div class="cta-stack mt-4">
|
||||
<a class="btn btn-dark" href="admin.php">لوحة الإدارة</a>
|
||||
<a class="btn btn-outline-secondary" href="<?= e($approvedSchoolUrl) ?>">العودة لصفحة المركز</a>
|
||||
<a class="btn btn-outline-secondary" href="<?= e($studentsUrl) ?>">تسجيل الطلاب</a>
|
||||
<a class="btn btn-outline-secondary" href="<?= e($teachersUrl) ?>">فريق المعلمين</a>
|
||||
<a class="btn btn-outline-secondary" href="<?= e($attendanceUrl) ?>">غياب الطلاب</a>
|
||||
<a class="btn btn-outline-secondary" href="<?= e($applicationDetailUrl) ?>">ملف الاعتماد</a>
|
||||
</div>
|
||||
|
||||
<div class="page-banner mb-4">
|
||||
<div class="row g-4 align-items-center">
|
||||
<div class="col-md-8">
|
||||
<h1 class="page-title mb-2">التقييمات: <?= e((string) $application['center_name']) ?></h1>
|
||||
<p class="page-copy mb-0">إدارة أنواع التقييم وتوزيع الدرجات ضمن الخطة الأكاديمية للدورة <strong><?= e($cycleLabel) ?></strong>.</p>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="app-card h-100 approved-note">
|
||||
<div class="section-title mb-3">توازن الأوزان</div>
|
||||
<?php if (abs($weightGap) < 0.01): ?>
|
||||
<div class="alert alert-success mb-3">ممتاز — الأوزان المفعلة تساوي 100% وجاهزة للاستخدام.</div>
|
||||
<?php elseif ($activeWeight > 100): ?>
|
||||
<div class="alert alert-danger mb-3">مجموع الأوزان المفعلة يتجاوز 100% بمقدار <?= e(number_format(abs($weightGap), 2, '.', '')) ?>%. يحتاج إلى إعادة موازنة.</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-warning mb-3">المجموع الحالي للأوزان المفعلة هو <?= e(number_format($activeWeight, 2, '.', '')) ?>%، والمتبقي <?= e(number_format(max(0, $weightGap), 2, '.', '')) ?>% لاستكمال الخطة.</div>
|
||||
<?php endif; ?>
|
||||
<div class="summary-stack">
|
||||
<div class="summary-row"><span>التقييمات المفعلة</span><strong><?= e((string) $metrics['active']) ?></strong></div>
|
||||
<div class="summary-row"><span>متوسط الدرجة القصوى</span><strong><?= e(number_format((float) $metrics['average_max_score'], 2, '.', '')) ?></strong></div>
|
||||
<div class="summary-row"><span>فريق التدريس</span><strong><?= e((string) $teacherMetrics['total']) ?> عضو</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 text-md-end">
|
||||
<?php if (!$isCycleReadOnly): ?>
|
||||
<button type="button" class="btn btn-dark" data-bs-toggle="modal" data-bs-target="#assessmentModal" onclick="resetAssessmentForm()">
|
||||
إضافة تقييم جديد
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($selectedCycle): ?>
|
||||
<?php $cycleStatusMap = school_cycle_status_map(); ?>
|
||||
<div class="row g-4 mb-4 align-items-start">
|
||||
<div class="col-lg-<?= is_super_admin() ? '7' : '12' ?>">
|
||||
<div class="app-card h-100">
|
||||
<div class="section-head mb-3">
|
||||
<div>
|
||||
<div class="section-title">الدورة الموسمية الحالية</div>
|
||||
<div class="section-copy">كل عناصر خطة التقييم في هذه الصفحة تخص الدورة <strong><?= e($cycleLabel) ?></strong>. يمكنك مراجعة مواسمك السابقة أو الحالية مباشرة من هنا.</div>
|
||||
</div>
|
||||
<?= school_cycle_status_badge((string) $selectedCycle['status']) ?>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>اسم الدورة</strong><span><?= e($cycleLabel) ?></span></div></div>
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>الفترة</strong><span><?= e((string) $selectedCycle['start_date']) ?> → <?= e((string) $selectedCycle['end_date']) ?></span></div></div>
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>عدد الدورات</strong><span><?= e((string) count($cycleContext['cycles'])) ?> دورة للمركز</span></div></div>
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>التقييمات كلها</strong><span><?= e((string) $metrics['total']) ?></span></div></div>
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>التقييمات المفعلة</strong><span><?= e((string) $metrics['active']) ?></span></div></div>
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>الأوزان المفعلة</strong><span><?= e(number_format($activeWeight, 2, '.', '')) ?>%</span></div></div>
|
||||
</div>
|
||||
<div class="cta-stack mt-3">
|
||||
<?php if (is_super_admin()): ?><a class="btn btn-outline-secondary" href="<?= e($approvedSchoolUrl) ?>#cycles">إدارة الدورات الموسمية</a><?php endif; ?>
|
||||
</div>
|
||||
<?php if ($isCycleReadOnly): ?>
|
||||
<div class="alert alert-warning mt-3 mb-0">هذه الدورة مؤرشفة، لذلك تبقى خطة التقييم للقراءة فقط حالياً.</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (is_super_admin()): ?>
|
||||
<div class="col-lg-5">
|
||||
<div class="app-card sidebar-card h-100">
|
||||
<div class="section-title mb-3">التبديل بين الدورات</div>
|
||||
<p class="section-subtle mb-3">افتح نفس صفحة التقييمات لأي موسم سابق أو حالي حتى تراجع الأوزان والخطط التاريخية بسرعة.</p>
|
||||
<div class="quick-link-stack">
|
||||
<?php foreach ($cycleContext['cycles'] as $cycle): ?>
|
||||
<?php
|
||||
$isCurrentCycleLink = (int) $cycle['id'] === $selectedCycleId;
|
||||
$isActiveCycleLink = (int) $cycle['id'] === (int) (($cycleContext['active']['id'] ?? 0));
|
||||
$cycleStatusLabel = (string) ($cycleStatusMap[$cycle['status']]['label'] ?? 'غير معروف');
|
||||
$cycleMetaLine = (string) $cycle['start_date'] . ' → ' . (string) $cycle['end_date'] . ' — ' . $cycleStatusLabel . ($isActiveCycleLink ? ' — النشطة حالياً' : '');
|
||||
?>
|
||||
<a class="quick-link-item <?= $isCurrentCycleLink ? 'is-current' : '' ?>" href="<?= e(school_page_url('assessments.php', (int) $application['id'], (int) $cycle['id'])) ?>">
|
||||
<div>
|
||||
<strong><?= e((string) $cycle['cycle_name']) ?><?= $isCurrentCycleLink ? ' — المعروضة الآن' : '' ?></strong>
|
||||
<span><?= e($cycleMetaLine) ?></span>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (isset($errors['form'])): ?>
|
||||
<div class="alert alert-danger"><?= e($errors['form']) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($isCycleReadOnly): ?>
|
||||
<div class="alert alert-warning mb-4">هذه الدورة مؤرشفة. التقييمات معروضة للقراءة فقط.</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row g-4 align-items-start">
|
||||
<div class="col-lg-4">
|
||||
<div class="app-card sidebar-card mb-4">
|
||||
<div class="section-title mb-3">إضافة نوع تقييم جديد</div>
|
||||
<p class="section-subtle mb-3">أدخل نوع التقييم مرة واحدة، ثم استخدم القائمة في الأسفل كمرجع للخطة الأكاديمية الخاصة بالمركز.</p>
|
||||
<div class="app-card mb-4">
|
||||
<form method="get" class="row g-2 align-items-center">
|
||||
<input type="hidden" name="id" value="<?= e((string)$application['id']) ?>">
|
||||
<input type="hidden" name="cycle" value="<?= e((string)$selectedCycleId) ?>">
|
||||
<div class="col-md-4">
|
||||
<input type="text" name="search" class="form-control" placeholder="ابحث باسم التقييم..." value="<?= e($filters['search']) ?>">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select name="subject_id" class="form-select">
|
||||
<option value="">كل المواد</option>
|
||||
<?php foreach ($available_subjects as $subj):
|
||||
?><option value="<?= e((string)$subj['id']) ?>" <?= $filters['subject_id'] === (string)$subj['id'] ? 'selected' : '' ?>><?= e($subj['name']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select name="category" class="form-select">
|
||||
<option value="">كل الفئات</option>
|
||||
<?php foreach (assessment_category_options() as $cat):
|
||||
?><option value="<?= e($cat) ?>" <?= $filters['category'] === $cat ? 'selected' : '' ?>><?= e($cat) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-dark w-100">تصفية</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php if (isset($errors['form'])): ?>
|
||||
<div class="alert alert-danger"><?= e($errors['form']) ?></div>
|
||||
<?php endif; ?>
|
||||
<div class="app-card mb-4">
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>إجمالي الأنواع</strong><span><?= e((string) $metrics['total']) ?> نوع</span></div></div>
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>المفعّل الآن</strong><span><?= e((string) $metrics['active']) ?> نوع</span></div></div>
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>الأوزان المفعلة</strong><span><?= e(number_format($activeWeight, 2, '.', '')) ?>%</span></div></div>
|
||||
</div>
|
||||
|
||||
<?php if ($isCycleReadOnly): ?>
|
||||
<div class="alert alert-warning mb-0">هذه الدورة مؤرشفة. يمكنك مراجعة خطة التقييم فقط، أو فتح دورة جديدة من صفحة المركز.</div>
|
||||
<?php else: ?>
|
||||
<form method="post" class="vstack gap-3" novalidate>
|
||||
<div>
|
||||
<label class="form-label" for="title">اسم نوع التقييم</label>
|
||||
<input class="form-control <?= isset($errors['title']) ? 'is-invalid' : '' ?>" id="title" name="title" value="<?= e($values['title']) ?>" placeholder="مثال: اختبار دوري أول">
|
||||
<?php if (isset($errors['title'])): ?><div class="invalid-feedback"><?= e($errors['title']) ?></div><?php endif; ?>
|
||||
<?php if ($assessments === []): ?>
|
||||
<div class="empty-state text-center p-4">
|
||||
<div class="empty-title mb-2">لا توجد تقييمات</div>
|
||||
<p class="text-muted mb-0">لم يتم العثور على أنواع تقييم تطابق خياراتك.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table app-table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>التقييم</th>
|
||||
<th>المادة</th>
|
||||
<th>الفئة</th>
|
||||
<th>المقياس</th>
|
||||
<th>الدرجة</th>
|
||||
<th>الوزن</th>
|
||||
<th>الحالة</th>
|
||||
<?php if (!$isCycleReadOnly): ?><th>الإجراء</th><?php endif; ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($assessments as $assessment):
|
||||
$subjName = 'عام';
|
||||
foreach ($available_subjects as $s) {
|
||||
if ((string)$s['id'] === (string)$assessment['subject_id']) {
|
||||
$subjName = $s['name']; break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<strong><?= e((string) $assessment['title']) ?></strong>
|
||||
<?php if (!empty($assessment['notes'])): ?><div class="small text-muted"><?= e((string) $assessment['notes']) ?></div><?php endif; ?>
|
||||
</td>
|
||||
<td><span class="badge bg-secondary"><?= e($subjName) ?></span></td>
|
||||
<td><?= e((string) $assessment['category']) ?></td>
|
||||
<td><?= assessment_scale_type_badge((string) $assessment['scale_type']) ?></td>
|
||||
<td><?= e(number_format((float) $assessment['max_score'], 2, '.', '')) ?></td>
|
||||
<td><strong><?= e(number_format((float) $assessment['weight_percentage'], 2, '.', '')) ?>%</strong></td>
|
||||
<td><?= assessment_active_badge((int) $assessment['is_active']) ?></td>
|
||||
<?php if (!$isCycleReadOnly):
|
||||
?><td>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="editAssessment(<?= htmlspecialchars(json_encode($assessment), ENT_QUOTES, 'UTF-8') ?>)">
|
||||
تعديل
|
||||
</button>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php render_pagination($totalAssessments, $limit, $page, $_GET); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Modal -->
|
||||
<?php if (!$isCycleReadOnly):
|
||||
?><div class="modal fade" id="assessmentModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<form method="post" id="assessmentForm" novalidate>
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="assessmentModalLabel">إضافة نوع تقييم</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="إغلاق"></button>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="category">الفئة</label>
|
||||
<select class="form-select <?= isset($errors['category']) ? 'is-invalid' : '' ?>" id="category" name="category">
|
||||
<?php foreach (assessment_category_options() as $option): ?>
|
||||
<option value="<?= e($option) ?>" <?= $values['category'] === $option ? 'selected' : '' ?>><?= e($option) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php if (isset($errors['category'])): ?><div class="invalid-feedback"><?= e($errors['category']) ?></div><?php endif; ?>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="scale_type">المقياس</label>
|
||||
<select class="form-select <?= isset($errors['scale_type']) ? 'is-invalid' : '' ?>" id="scale_type" name="scale_type">
|
||||
<?php foreach (assessment_scale_type_map() as $key => $meta): ?>
|
||||
<option value="<?= e($key) ?>" <?= $values['scale_type'] === $key ? 'selected' : '' ?>><?= e((string) $meta['label']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php if (isset($errors['scale_type'])): ?><div class="invalid-feedback"><?= e($errors['scale_type']) ?></div><?php endif; ?>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="max_score">الدرجة النهائية</label>
|
||||
<input type="number" step="0.01" min="0" max="1000" class="form-control <?= isset($errors['max_score']) ? 'is-invalid' : '' ?>" id="max_score" name="max_score" value="<?= e($values['max_score']) ?>">
|
||||
<?php if (isset($errors['max_score'])): ?><div class="invalid-feedback"><?= e($errors['max_score']) ?></div><?php endif; ?>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="weight_percentage">الوزن (%)</label>
|
||||
<input type="number" step="0.01" min="0" max="100" class="form-control <?= isset($errors['weight_percentage']) ? 'is-invalid' : '' ?>" id="weight_percentage" name="weight_percentage" value="<?= e($values['weight_percentage']) ?>">
|
||||
<?php if (isset($errors['weight_percentage'])): ?><div class="invalid-feedback"><?= e($errors['weight_percentage']) ?></div><?php endif; ?>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="action" id="formAction" value="add">
|
||||
<input type="hidden" name="assessment_id" id="formAssessmentId" value="">
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-12">
|
||||
<label class="form-label" for="title">اسم التقييم</label>
|
||||
<input class="form-control" id="title" name="title" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="subject_id">المادة الدراسية</label>
|
||||
<select class="form-select" id="subject_id" name="subject_id">
|
||||
<option value="">عام (لا يخص مادة معينة)</option>
|
||||
<?php foreach ($available_subjects as $subj):
|
||||
?><option value="<?= e((string)$subj['id']) ?>"><?= e($subj['name']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="category">الفئة</label>
|
||||
<select class="form-select" id="category" name="category">
|
||||
<?php foreach (assessment_category_options() as $option):
|
||||
?><option value="<?= e($option) ?>"><?= e($option) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="scale_type">المقياس</label>
|
||||
<select class="form-select" id="scale_type" name="scale_type">
|
||||
<?php foreach (assessment_scale_type_map() as $key => $meta):
|
||||
?><option value="<?= e($key) ?>"><?= e((string) $meta['label']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="max_score">الدرجة النهائية</label>
|
||||
<input type="number" step="0.01" min="0" max="1000" class="form-control" id="max_score" name="max_score" value="100">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="weight_percentage">الوزن (%)</label>
|
||||
<input type="number" step="0.01" min="0" max="100" class="form-control" id="weight_percentage" name="weight_percentage" value="10">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="is_active">حالة التفعيل</label>
|
||||
<select class="form-select" id="is_active" name="is_active">
|
||||
<option value="1">مفعل داخل الخطة</option>
|
||||
<option value="0">مؤرشف / تحضيري</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label" for="notes">ملاحظات</label>
|
||||
<textarea class="form-control" id="notes" name="notes" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="form-label" for="is_active">حالة التفعيل</label>
|
||||
<select class="form-select" id="is_active" name="is_active">
|
||||
<option value="1" <?= $values['is_active'] === '1' ? 'selected' : '' ?>>مفعل داخل الخطة</option>
|
||||
<option value="0" <?= $values['is_active'] === '0' ? 'selected' : '' ?>>مؤرشف / تحضيري</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="form-label" for="notes">ملاحظات</label>
|
||||
<textarea class="form-control" id="notes" name="notes" rows="4" placeholder="مثال: يطبق على جميع الصفوف أو يخص مساراً معيناً."><?= e($values['notes']) ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-dark" type="submit">حفظ نوع التقييم</button>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">إلغاء</button>
|
||||
<button type="submit" class="btn btn-dark">حفظ التقييم</button>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="app-card sidebar-card">
|
||||
<div class="section-title mb-3">الخطوة التالية بعد الخطة</div>
|
||||
<ul class="module-roadmap-list mb-0">
|
||||
<li><strong>غياب الطلاب</strong><span class="section-subtle">الصفحة أصبحت جاهزة الآن لتتبع الغياب اليومي، الأعذار، وحالات التأخر.</span><div class="mt-2"><a class="btn btn-sm btn-outline-secondary" href="<?= e($attendanceUrl) ?>">فتح صفحة الغياب</a></div></li>
|
||||
<li><strong>المتابعة الأكاديمية</strong><span class="section-subtle">يمكن لاحقاً ربط نتائج التقييم بالطلاب والحصص أو الأسابيع التشغيلية.</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-8">
|
||||
<div class="app-card mb-4">
|
||||
<div class="section-head mb-3">
|
||||
<div>
|
||||
<div class="section-title">خريطة التقييمات</div>
|
||||
<div class="section-copy">جميع أنواع التقييم المعرفة لهذا المركز فقط، مرتبة بحسب التفعيل والوزن.</div>
|
||||
</div>
|
||||
<span class="header-chip"><?= e((string) $metrics['percentage']) ?> نسبي / <?= e((string) $metrics['rubric']) ?> Rubric</span>
|
||||
</div>
|
||||
<?php render_search_bar($search, 'ابحث باسم التقييم أو الفئة...', school_page_url('assessments.php', (int)$application['id'], $selectedCycleId), $_GET); ?>
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>إجمالي الأنواع</strong><span><?= e((string) $metrics['total']) ?> نوع</span></div></div>
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>المفعّل الآن</strong><span><?= e((string) $metrics['active']) ?> نوع</span></div></div>
|
||||
<div class="col-md-4"><div class="school-data-item"><strong>الأوزان المفعلة</strong><span><?= e(number_format($activeWeight, 2, '.', '')) ?>%</span></div></div>
|
||||
</div>
|
||||
|
||||
<?php if ($assessments === []): ?>
|
||||
<div class="empty-state text-center p-4">
|
||||
<div class="empty-title mb-2">لا توجد تقييمات معرفة بعد</div>
|
||||
<p class="text-muted mb-0">ابدأ من النموذج في الجانب الأيمن لإضافة أول نوع تقييم إلى خطة المركز.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table app-table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>التقييم</th>
|
||||
<th>الفئة</th>
|
||||
<th>المقياس</th>
|
||||
<th>الدرجة</th>
|
||||
<th>الوزن</th>
|
||||
<th>الحالة</th>
|
||||
<th>الإضافة</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($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><?= assessment_scale_type_badge((string) $assessment['scale_type']) ?></td>
|
||||
<td><?= e(number_format((float) $assessment['max_score'], 2, '.', '')) ?></td>
|
||||
<td><strong><?= e(number_format((float) $assessment['weight_percentage'], 2, '.', '')) ?>%</strong></td>
|
||||
<td><?= assessment_active_badge((int) $assessment['is_active']) ?></td>
|
||||
<td><?= e(substr((string) $assessment['created_at'], 0, 10)) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php render_pagination($totalAssessments, $limit, $page, $_GET); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="app-card">
|
||||
<div class="section-title mb-3">سياق المدرسة</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6"><div class="school-data-item"><strong>مدير المركز</strong><span><?= e((string) $application['director_name']) ?></span></div></div>
|
||||
<div class="col-md-6"><div class="school-data-item"><strong>قيد الطلاب النشط</strong><span><?= e((string) $studentMetrics['active']) ?> طالب/طالبة</span></div></div>
|
||||
<div class="col-md-6"><div class="school-data-item"><strong>الفريق التعليمي</strong><span><?= e((string) $teacherMetrics['total']) ?> عضو</span></div></div>
|
||||
<div class="col-md-6"><div class="school-data-item"><strong>التقييمات النقطية</strong><span><?= e((string) $metrics['points']) ?> نوع</span></div></div>
|
||||
</div>
|
||||
<div class="cta-stack mt-4">
|
||||
<a class="btn btn-outline-secondary" href="<?= e($teachersUrl) ?>">العودة إلى المعلمين</a>
|
||||
<a class="btn btn-outline-secondary" href="<?= e($studentsUrl) ?>">العودة إلى الطلاب</a>
|
||||
<a class="btn btn-outline-secondary" href="<?= e($attendanceUrl) ?>">فتح الغياب</a>
|
||||
<a class="btn btn-outline-secondary" href="<?= e($approvedSchoolUrl) ?>">صفحة المركز</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<script>
|
||||
let assessmentModal;
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const m = document.getElementById('assessmentModal');
|
||||
if (m) assessmentModal = new bootstrap.Modal(m);
|
||||
});
|
||||
function resetAssessmentForm() {
|
||||
document.getElementById('assessmentForm').reset();
|
||||
document.getElementById('formAction').value = 'add';
|
||||
document.getElementById('formAssessmentId').value = '';
|
||||
document.getElementById('assessmentModalLabel').innerText = 'إضافة نوع تقييم';
|
||||
}
|
||||
function editAssessment(data) {
|
||||
resetAssessmentForm();
|
||||
document.getElementById('formAction').value = 'edit';
|
||||
document.getElementById('formAssessmentId').value = data.id;
|
||||
document.getElementById('assessmentModalLabel').innerText = 'تعديل التقييم';
|
||||
|
||||
document.getElementById('title').value = data.title || '';
|
||||
document.getElementById('subject_id').value = data.subject_id || '';
|
||||
document.getElementById('category').value = data.category || '';
|
||||
document.getElementById('scale_type').value = data.scale_type || '';
|
||||
document.getElementById('max_score').value = data.max_score || '100';
|
||||
document.getElementById('weight_percentage').value = data.weight_percentage || '0';
|
||||
document.getElementById('is_active').value = data.is_active;
|
||||
document.getElementById('notes').value = data.notes || '';
|
||||
|
||||
if (assessmentModal) assessmentModal.show();
|
||||
}
|
||||
<?php if (!empty($errors) && isset($_POST['action'])):
|
||||
?>document.addEventListener("DOMContentLoaded", () => {
|
||||
if (assessmentModal) assessmentModal.show();
|
||||
});
|
||||
<?php endif; ?>
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
<?php render_page_end();
|
||||
<?php render_page_end(); ?>
|
||||
|
||||
@ -67,7 +67,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
|
||||
$errors['form'] = 'تعذر حفظ البيانات. يرجى المحاولة لاحقاً.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render_page_start('إدارة المواد الدراسية: ' . (string) $application['center_name'], 'profile', 'تحديد المواد الدراسية التي يتم تدريسها في المركز.');
|
||||
render_flash($flash);
|
||||
|
||||
18
db/migrations/20260416_alter_assessments_subject.sql
Normal file
18
db/migrations/20260416_alter_assessments_subject.sql
Normal file
@ -0,0 +1,18 @@
|
||||
-- Safely add the column.
|
||||
SET @dbname = DATABASE();
|
||||
SET @tablename = 'school_assessment_types';
|
||||
SET @columnname = 'subject_id';
|
||||
SET @preparedStatement = (SELECT IF(
|
||||
(
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE
|
||||
(table_name = @tablename)
|
||||
AND (table_schema = @dbname)
|
||||
AND (column_name = @columnname)
|
||||
) > 0,
|
||||
"SELECT 1",
|
||||
CONCAT("ALTER TABLE ", @tablename, " ADD ", @columnname, " INT UNSIGNED NULL AFTER cycle_id;")
|
||||
));
|
||||
PREPARE alterIfNotExists FROM @preparedStatement;
|
||||
EXECUTE alterIfNotExists;
|
||||
DEALLOCATE PREPARE alterIfNotExists;
|
||||
@ -995,6 +995,7 @@ function assessment_active_badge(int $isActive): string
|
||||
function validate_assessment_input(array $input): array
|
||||
{
|
||||
$data = assessment_defaults();
|
||||
$data['subject_id'] = clean_text((string) ($input['subject_id'] ?? ''), 20);
|
||||
$data['title'] = clean_text((string) ($input['title'] ?? ''), 150);
|
||||
$data['category'] = clean_text((string) ($input['category'] ?? ''), 80);
|
||||
$data['scale_type'] = clean_text((string) ($input['scale_type'] ?? ''), 40);
|
||||
|
||||
@ -406,12 +406,12 @@ function copy_school_cycle_rollover(PDO $pdo, int $centerApplicationId, int $sou
|
||||
if (!empty($rollover['copy_assessments'])) {
|
||||
$stmt = $pdo->prepare(
|
||||
'INSERT INTO school_assessment_types (
|
||||
center_application_id, cycle_id, title, category, scale_type,
|
||||
center_application_id, cycle_id, subject_id, title, category, scale_type,
|
||||
max_score, weight_percentage, is_active, notes,
|
||||
created_at, updated_at
|
||||
)
|
||||
SELECT
|
||||
center_application_id, :target_cycle_id, title, category, scale_type,
|
||||
center_application_id, :target_cycle_id, subject_id, title, category, scale_type,
|
||||
max_score, weight_percentage, is_active, notes,
|
||||
NOW(), NOW()
|
||||
FROM school_assessment_types
|
||||
@ -833,11 +833,11 @@ function create_assessment_type_in_cycle(int $centerApplicationId, int $cycleId,
|
||||
$pdo = db_connection();
|
||||
$stmt = $pdo->prepare(
|
||||
'INSERT INTO school_assessment_types (
|
||||
center_application_id, cycle_id, title, category, scale_type,
|
||||
center_application_id, cycle_id, subject_id, title, category, scale_type,
|
||||
max_score, weight_percentage, is_active, notes,
|
||||
created_at, updated_at
|
||||
) VALUES (
|
||||
:center_application_id, :cycle_id, :title, :category, :scale_type,
|
||||
:center_application_id, :cycle_id, :subject_id, :title, :category, :scale_type,
|
||||
:max_score, :weight_percentage, :is_active, :notes,
|
||||
NOW(), NOW()
|
||||
)'
|
||||
@ -845,6 +845,7 @@ function create_assessment_type_in_cycle(int $centerApplicationId, int $cycleId,
|
||||
$stmt->execute([
|
||||
':center_application_id' => $centerApplicationId,
|
||||
':cycle_id' => $cycleId,
|
||||
':subject_id' => !empty($data['subject_id']) ? (int) $data['subject_id'] : null,
|
||||
':title' => $data['title'],
|
||||
':category' => $data['category'],
|
||||
':scale_type' => $data['scale_type'],
|
||||
@ -856,7 +857,7 @@ function create_assessment_type_in_cycle(int $centerApplicationId, int $cycleId,
|
||||
return (int) $pdo->lastInsertId();
|
||||
}
|
||||
|
||||
function list_school_assessments_by_cycle(int $centerApplicationId, int $cycleId, string $search = '', int $limit = 0, int $offset = 0): array
|
||||
function list_school_assessments_by_cycle(int $centerApplicationId, int $cycleId, array $filters = [], int $limit = 0, int $offset = 0): array
|
||||
{
|
||||
$pdo = db_connection();
|
||||
$query = 'SELECT * FROM school_assessment_types WHERE center_application_id = :center_application_id AND cycle_id = :cycle_id';
|
||||
@ -865,12 +866,25 @@ function list_school_assessments_by_cycle(int $centerApplicationId, int $cycleId
|
||||
':cycle_id' => $cycleId,
|
||||
];
|
||||
|
||||
$search = $filters['search'] ?? '';
|
||||
if ($search !== '') {
|
||||
$query .= ' AND (assessment_name LIKE :search1 OR assessment_category LIKE :search2)';
|
||||
$query .= ' AND (title LIKE :search1 OR category LIKE :search2)';
|
||||
$params[':search1'] = "%$search%";
|
||||
$params[':search2'] = "%$search%";
|
||||
}
|
||||
|
||||
$subject_id = $filters['subject_id'] ?? '';
|
||||
if ($subject_id !== '') {
|
||||
$query .= ' AND subject_id = :subject_id';
|
||||
$params[':subject_id'] = (int) $subject_id;
|
||||
}
|
||||
|
||||
$category = $filters['category'] ?? '';
|
||||
if ($category !== '') {
|
||||
$query .= ' AND category = :category';
|
||||
$params[':category'] = $category;
|
||||
}
|
||||
|
||||
$query .= ' ORDER BY is_active DESC, created_at DESC, id DESC';
|
||||
|
||||
if ($limit > 0) {
|
||||
@ -882,7 +896,7 @@ function list_school_assessments_by_cycle(int $centerApplicationId, int $cycleId
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
function count_school_assessments_by_cycle(int $centerApplicationId, int $cycleId, string $search = ''): int
|
||||
function count_school_assessments_by_cycle(int $centerApplicationId, int $cycleId, array $filters = []): int
|
||||
{
|
||||
$pdo = db_connection();
|
||||
$query = 'SELECT COUNT(*) FROM school_assessment_types WHERE center_application_id = :center_application_id AND cycle_id = :cycle_id';
|
||||
@ -891,12 +905,25 @@ function count_school_assessments_by_cycle(int $centerApplicationId, int $cycleI
|
||||
':cycle_id' => $cycleId,
|
||||
];
|
||||
|
||||
$search = $filters['search'] ?? '';
|
||||
if ($search !== '') {
|
||||
$query .= ' AND (assessment_name LIKE :search1 OR assessment_category LIKE :search2)';
|
||||
$query .= ' AND (title LIKE :search1 OR category LIKE :search2)';
|
||||
$params[':search1'] = "%$search%";
|
||||
$params[':search2'] = "%$search%";
|
||||
}
|
||||
|
||||
$subject_id = $filters['subject_id'] ?? '';
|
||||
if ($subject_id !== '') {
|
||||
$query .= ' AND subject_id = :subject_id';
|
||||
$params[':subject_id'] = (int) $subject_id;
|
||||
}
|
||||
|
||||
$category = $filters['category'] ?? '';
|
||||
if ($category !== '') {
|
||||
$query .= ' AND category = :category';
|
||||
$params[':category'] = $category;
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare($query);
|
||||
$stmt->execute($params);
|
||||
return (int)$stmt->fetchColumn();
|
||||
@ -1126,3 +1153,33 @@ function update_student_in_cycle(int $centerApplicationId, int $cycleId, int $st
|
||||
$stmt->bindValue(':notes', $data['notes'] !== '' ? $data['notes'] : null, $data['notes'] !== '' ? PDO::PARAM_STR : PDO::PARAM_NULL);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
function update_assessment_type_in_cycle(int $centerApplicationId, int $cycleId, int $assessmentId, array $data): bool
|
||||
{
|
||||
$pdo = db_connection();
|
||||
$stmt = $pdo->prepare(
|
||||
'UPDATE school_assessment_types SET
|
||||
subject_id = :subject_id,
|
||||
title = :title,
|
||||
category = :category,
|
||||
scale_type = :scale_type,
|
||||
max_score = :max_score,
|
||||
weight_percentage = :weight_percentage,
|
||||
is_active = :is_active,
|
||||
notes = :notes
|
||||
WHERE id = :id AND center_application_id = :center_application_id AND cycle_id = :cycle_id'
|
||||
);
|
||||
return $stmt->execute([
|
||||
':id' => $assessmentId,
|
||||
':center_application_id' => $centerApplicationId,
|
||||
':cycle_id' => $cycleId,
|
||||
':subject_id' => !empty($data['subject_id']) ? (int) $data['subject_id'] : null,
|
||||
':title' => $data['title'],
|
||||
':category' => $data['category'],
|
||||
':scale_type' => $data['scale_type'],
|
||||
':max_score' => (float) $data['max_score'],
|
||||
':weight_percentage' => (float) $data['weight_percentage'],
|
||||
':is_active' => (int) $data['is_active'],
|
||||
':notes' => $data['notes'] !== '' ? $data['notes'] : null,
|
||||
]);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user