extend('layout/management_layout') ?> section('content') ?> $sections) { $kept = []; foreach ($sections as $section) { $secKey = (string)($section['class_section_id'] ?? ($section['id'] ?? '')); if ($secKey !== '' && !empty($studentsBySection[$secKey])) { $kept[] = $section; } } if (!empty($kept)) { $filteredGrades[$cid] = $kept; } } $grades = $filteredGrades; ?>

Attendance Analysis

include('partials/academic_filter') ?> section('styles') ?> endSection() ?> getGet('start_date') ?? '')); $endDateRaw = trim((string)($req->getGet('end_date') ?? '')); $isValidDate = static function (string $d): bool { if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $d)) return false; [$y, $m, $day] = array_map('intval', explode('-', $d)); return checkdate($m, $day, $y); }; $filterStart = ($startDateRaw !== '' && $isValidDate($startDateRaw)) ? $startDateRaw : ''; $filterEnd = ($endDateRaw !== '' && $isValidDate($endDateRaw)) ? $endDateRaw : ''; // ---- Build labels and a stable order: KG -> Grade 1..12 -> Youth ---- $labelsByClassId = []; $gradeNumberById = []; $kgIds = []; $arabicIds = []; $youthIds = []; foreach ($grades as $classId => $sections) { $cid = (int)$classId; $sampleName = ''; $isArabicProgram = false; foreach ($sections as $s) { $sampleName = (string)($s['class_section_name'] ?? ''); $lowName = strtolower($sampleName); $lowCode = strtolower((string)($s['class_section_id'] ?? '')); if (strpos($lowName, 'arabic') !== false || strpos($lowCode, 'arabic') !== false) { $isArabicProgram = true; } if ($sampleName !== '') break; } if ($isArabicProgram || $cid === 14) { $labelsByClassId[$cid] = 'Arabic'; $arabicIds[] = $cid; } elseif (preg_match('/\bKG\b/i', $sampleName)) { $labelsByClassId[$cid] = 'KG'; $kgIds[] = $cid; } elseif (preg_match('/\bYouth\b/i', $sampleName)) { $labelsByClassId[$cid] = 'Youth'; $youthIds[] = $cid; } elseif (preg_match('/Grade\s*(\d+)/i', $sampleName, $m)) { $labelsByClassId[$cid] = 'Grade ' . (int)$m[1]; $gradeNumberById[$cid] = (int)$m[1]; } else { if ($cid === 0) { $labelsByClassId[$cid] = 'KG'; $kgIds[] = $cid; } elseif ($cid === 13) { $labelsByClassId[$cid] = 'Youth'; $youthIds[] = $cid; } else { $labelsByClassId[$cid] = 'Grade ' . $cid; $gradeNumberById[$cid] = $cid; } } } $sortedClassIds = []; if ($kgIds) { sort($kgIds, SORT_NUMERIC); $sortedClassIds = array_merge($sortedClassIds, $kgIds); } if ($gradeNumberById) { asort($gradeNumberById, SORT_NUMERIC); $sortedClassIds = array_merge($sortedClassIds, array_keys($gradeNumberById)); } if ($youthIds) { sort($youthIds, SORT_NUMERIC); $sortedClassIds = array_merge($sortedClassIds, $youthIds); } if ($arabicIds) { sort($arabicIds, SORT_NUMERIC); $sortedClassIds = array_merge($sortedClassIds, $arabicIds); } $presentIds = array_map('intval', array_keys($grades)); $missingIds = array_values(array_diff($presentIds, $sortedClassIds)); if (!empty($missingIds)) { $sortedClassIds = array_merge($sortedClassIds, $missingIds); } $labelFor = function (int $id) use ($labelsByClassId): string { return $labelsByClassId[$id] ?? ('Class ' . $id); }; // ---- Attendance analysis ---- $analysisOverall = ['present' => 0, 'late' => 0, 'absent' => 0]; $analysisByGrade = []; $analysisBySection = []; $analysisTotal = 0; foreach ($grades as $classId => $sections) { $gradeLabel = $labelFor((int)$classId); if (!isset($analysisByGrade[$gradeLabel])) { $analysisByGrade[$gradeLabel] = ['present' => 0, 'late' => 0, 'absent' => 0]; } foreach ($sections as $section) { $sectionKey = (string)($section['class_section_id'] ?? ($section['id'] ?? '')); if ($sectionKey === '' || empty($studentsBySection[$sectionKey])) continue; $secNameRaw = trim((string)($section['class_section_name'] ?? '')); $secLabel = $secNameRaw !== '' ? $secNameRaw : ('Section ' . $sectionKey); if (!isset($analysisBySection[$secLabel])) { $analysisBySection[$secLabel] = ['present' => 0, 'late' => 0, 'absent' => 0, 'total_students' => 0]; } $sectionTotalStudents = count($studentsBySection[$sectionKey]); if ($sectionTotalStudents > ($analysisBySection[$secLabel]['total_students'] ?? 0)) { $analysisBySection[$secLabel]['total_students'] = $sectionTotalStudents; } foreach ($studentsBySection[$sectionKey] as $stu) { $sid = (int)($stu['id'] ?? 0); if ($sid <= 0) continue; $entries = $attendanceData[$sectionKey][$sid] ?? []; if (!is_array($entries)) continue; foreach ($entries as $e) { $d = substr((string)($e['date'] ?? ''), 0, 10); if ($d === '') continue; if ($filterStart !== '' && $d < $filterStart) continue; if ($filterEnd !== '' && $d > $filterEnd) continue; $st = strtolower(trim((string)($e['status'] ?? ''))); if (!in_array($st, ['present', 'late', 'absent'], true)) continue; $analysisOverall[$st]++; $analysisByGrade[$gradeLabel][$st]++; $analysisBySection[$secLabel][$st]++; $analysisTotal++; } } } } $overallPercent = []; foreach (['present', 'late', 'absent'] as $st) { $overallPercent[$st] = $analysisTotal > 0 ? round(($analysisOverall[$st] * 100) / $analysisTotal, 1) : 0; } $analysisGradeLabels = []; $analysisGradeAbsent = []; $analysisGradeLate = []; $analysisGradeTotals = []; foreach ($sortedClassIds as $cid) { $lbl = $labelFor((int)$cid); $g = $analysisByGrade[$lbl] ?? ['present' => 0, 'late' => 0, 'absent' => 0]; $analysisGradeLabels[] = $lbl; $analysisGradeAbsent[] = (int)($g['absent'] ?? 0); $analysisGradeLate[] = (int)($g['late'] ?? 0); $analysisGradeTotals[] = (int)($g['present'] ?? 0) + (int)($g['late'] ?? 0) + (int)($g['absent'] ?? 0); } $analysisSectionLabels = array_keys($analysisBySection); $analysisSectionAbsent = []; $analysisSectionLate = []; $analysisSectionTotals = []; foreach ($analysisSectionLabels as $lbl) { $s = $analysisBySection[$lbl] ?? ['present' => 0, 'late' => 0, 'absent' => 0]; $analysisSectionAbsent[] = (int)($s['absent'] ?? 0); $analysisSectionLate[] = (int)($s['late'] ?? 0); $analysisSectionTotals[] = (int)($s['total_students'] ?? 0); } $totalDaysForPercent = 0; if ($filterStart === '' && $filterEnd === '' && !empty($totalPassedDays)) { $totalDaysForPercent = (int)$totalPassedDays; } elseif (!empty($dateList) && is_array($dateList)) { foreach ($dateList as $d) { $d = (string)$d; if ($d === '') continue; if ($filterStart !== '' && $d < $filterStart) continue; if ($filterEnd !== '' && $d > $filterEnd) continue; if (!empty($noSchoolDays[$d])) continue; $totalDaysForPercent++; } } $backUrl = site_url('administrator/daily_attendance'); $queryParts = []; if (!empty($semester)) $queryParts[] = 'semester=' . urlencode((string)$semester); if (!empty($schoolYear)) $queryParts[] = 'school_year=' . urlencode((string)$schoolYear); if ($queryParts) $backUrl .= '?' . implode('&', $queryParts); ?>
Clear
Overall Distribution
Status Count Percent
Present %
Late %
Absent %
By Section (Absent / Late)
$lbl): ?> 0 ? ($totalDaysForPercent * $tot) : 0; $absPct = $denom > 0 ? round(($abs * 100) / $denom, 1) : 0; $latePct = $denom > 0 ? round(($late * 100) / $denom, 1) : 0; ?>
Section Semester Days Total Students Absent Absent% Late Late%
% %
endSection() ?> section('scripts') ?> endSection() ?>