recreate project
This commit is contained in:
@@ -0,0 +1,307 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\View;
|
||||
|
||||
class ClassPrepController extends PrintablesBaseController
|
||||
{
|
||||
// Compute per-student sticker counts for entire schoolYear (optionally semester).
|
||||
protected function computeStickerCountsAll(\CodeIgniter\Database\BaseConnection $db, string $schoolYear, ?string $semester = null): array
|
||||
{
|
||||
return $this->computeStickerCounts($schoolYear, null, $semester);
|
||||
}
|
||||
|
||||
// Compute per-student sticker counts for one class section.
|
||||
protected function computeStickerCountsForClass(\CodeIgniter\Database\BaseConnection $db, string $schoolYear, int $classSectionId, ?string $semester = null): array
|
||||
{
|
||||
return $this->computeStickerCounts($schoolYear, $classSectionId, $semester);
|
||||
}
|
||||
|
||||
protected function computeStickerCounts(
|
||||
string $schoolYear,
|
||||
?int $classSectionId,
|
||||
?string $semester
|
||||
): array {
|
||||
$specialMap = ['KG' => 1, '1-A' => 3, '1-B' => 4, '2-A' => 5, '2-B' => 5, '9' => 2];
|
||||
$isUpperBlock = static fn(string $g) => (bool) preg_match('/^(3|4|5|6|7|8)(-[AB])?$/', trim($g));
|
||||
$isGrade5 = static fn(string $g) => (bool) preg_match('/^5(\-|$)/', trim($g));
|
||||
|
||||
$b = $this->db->table('student_class sc')
|
||||
->select('sc.student_id, s.firstname, s.lastname, s.is_new, cs.class_section_name AS grade_label')
|
||||
->join('students s', 's.id = sc.student_id', 'inner')
|
||||
->join('classSection cs', 'cs.class_section_id = sc.class_section_id', 'inner')
|
||||
->join('classes c', 'c.id = cs.class_id', 'inner')
|
||||
->where('sc.school_year', $schoolYear);
|
||||
|
||||
if (!empty($classSectionId)) {
|
||||
$b->where('sc.class_section_id', $classSectionId);
|
||||
}
|
||||
|
||||
$rows = $b->get()->getResultArray();
|
||||
|
||||
// Exclude Youth and KG (case-insensitive; also ignore variants like youth-*, KG-*)
|
||||
$rows = array_values(array_filter($rows, static function ($r) {
|
||||
$g = trim((string) $r['grade_label']);
|
||||
return $g !== ''
|
||||
&& !preg_match('/^youth(?:\b|-)/i', $g)
|
||||
&& !preg_match('/^kg(?:\b|-)/i', $g);
|
||||
}));
|
||||
|
||||
$students = [];
|
||||
$total = 0;
|
||||
|
||||
foreach ($rows as $r) {
|
||||
$g = trim((string) $r['grade_label']);
|
||||
$isNew = ((int) $r['is_new']) === 1;
|
||||
|
||||
// Primary-only rules
|
||||
if (array_key_exists($g, $specialMap)) {
|
||||
$p = $specialMap[$g];
|
||||
} elseif ($isUpperBlock($g)) {
|
||||
$p = $isNew ? 4 : ($isGrade5($g) ? 3 : 2);
|
||||
} else {
|
||||
$p = 4;
|
||||
}
|
||||
|
||||
$total += $p;
|
||||
|
||||
$students[] = [
|
||||
'student_id' => (int) $r['student_id'],
|
||||
'firstname' => trim($r['firstname']),
|
||||
'lastname' => trim($r['lastname']),
|
||||
'grade_label' => $g,
|
||||
'primary_count' => $p,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'students' => $students,
|
||||
'totals' => [
|
||||
'stickers' => $total,
|
||||
'students' => count($students),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute sticker counts per student (no file I/O).
|
||||
*
|
||||
* @param BaseConnection $db
|
||||
* @param string $schoolYear e.g. "2025-2026"
|
||||
* @param string|null $semester e.g. "Fall" (optional filter)
|
||||
* @return array{
|
||||
* students: array<int, array{
|
||||
* student_id:int,
|
||||
* firstname:string,
|
||||
* lastname:string,
|
||||
* grade_label:string,
|
||||
* primary_count:int,
|
||||
* secondary_count:int
|
||||
* }>,
|
||||
* totals: array{primary:int, secondary:int, students:int}
|
||||
* }
|
||||
*/
|
||||
private function getStickerCountsPerStudent(string $schoolYear, ?string $semester = null): array
|
||||
{
|
||||
// --- Sticker rules helpers ----------------------------------------------
|
||||
$specialMap = [
|
||||
'KG' => 1,
|
||||
'1-A' => 3,
|
||||
'1-B' => 4,
|
||||
'2-A' => 5,
|
||||
'2-B' => 5,
|
||||
'9' => 2,
|
||||
];
|
||||
$isUpperBlock = static function (string $g): bool {
|
||||
// 3-A, 3-B, 4-A, 4-B, 5-A, 5-B, 6, 7, 8 (also allow plain 3/4/5/6/7/8)
|
||||
return (bool) preg_match('/^(3|4|5|6|7|8)(-[AB])?$/', trim($g));
|
||||
};
|
||||
$isGrade5 = static function (string $g): bool {
|
||||
// "5" OR "5-A"/"5-B"
|
||||
return (bool) preg_match('/^5(\-|$)/', trim($g));
|
||||
};
|
||||
|
||||
// --- Pull roster: student_class -> classSection -> classes -> students ---
|
||||
$builder = $this->db->table('student_class sc')
|
||||
->select([
|
||||
'sc.student_id',
|
||||
's.firstname',
|
||||
's.lastname',
|
||||
's.is_new',
|
||||
'cs.class_section_name AS grade_label',
|
||||
])
|
||||
->join('students s', 's.id = sc.student_id')
|
||||
->join('classSection cs', 'cs.class_section_id = sc.class_section_id')
|
||||
->join('classes c', 'c.id = cs.class_id')
|
||||
->where('sc.school_year', $schoolYear);
|
||||
|
||||
|
||||
$rows = $builder->get()->getResultArray();
|
||||
|
||||
// Filter out Youth (any case; includes youth-*), and empty labels
|
||||
$rows = array_values(array_filter($rows, static function ($r) {
|
||||
$g = trim((string) $r['grade_label']);
|
||||
return $g !== '' && strcasecmp($g, 'youth') !== 0 && strncasecmp($g, 'youth-', 6) !== 0;
|
||||
}));
|
||||
|
||||
$out = [];
|
||||
$totalPrimary = 0;
|
||||
$totalSecondary = 0;
|
||||
|
||||
foreach ($rows as $r) {
|
||||
$first = trim((string) $r['firstname']);
|
||||
$last = trim((string) $r['lastname']);
|
||||
$grade = trim((string) $r['grade_label']);
|
||||
$isNew = ((int) $r['is_new']) === 1;
|
||||
|
||||
$primary = 0;
|
||||
$secondary = 0;
|
||||
|
||||
// 1) Special fixed grades
|
||||
if (array_key_exists($grade, $specialMap)) {
|
||||
$primary = (int) $specialMap[$grade];
|
||||
$secondary = 0;
|
||||
}
|
||||
// 2) Upper block 3..8
|
||||
elseif ($isUpperBlock($grade)) {
|
||||
if ($isNew) {
|
||||
$primary = 4;
|
||||
$secondary = 0;
|
||||
} else {
|
||||
$primary = $isGrade5($grade) ? 3 : 2;
|
||||
$secondary = max(0, 4 - $primary);
|
||||
}
|
||||
}
|
||||
// 3) Fallback for other non-Youth labels (e.g., "1", "2", "10", "11")
|
||||
else {
|
||||
$primary = 4;
|
||||
$secondary = 0;
|
||||
}
|
||||
|
||||
$totalPrimary += $primary;
|
||||
$totalSecondary += $secondary;
|
||||
|
||||
$out[] = [
|
||||
'student_id' => (int) $r['student_id'],
|
||||
'firstname' => $first,
|
||||
'lastname' => $last,
|
||||
'grade_label' => $grade,
|
||||
'primary_count' => $primary,
|
||||
'secondary_count' => $secondary,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'students' => $out,
|
||||
'totals' => [
|
||||
'primary' => $totalPrimary,
|
||||
'secondary' => $totalSecondary,
|
||||
'students' => count($out),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getStickerCountsPerStudentForClass(
|
||||
string $schoolYear,
|
||||
int $classSectionId,
|
||||
?string $semester = null
|
||||
): array {
|
||||
// Reuse exact helpers/rules from getStickerCountsPerStudent()
|
||||
$specialMap = [
|
||||
'1-A' => 3,
|
||||
'1-B' => 4,
|
||||
'2-A' => 5,
|
||||
'2-B' => 5,
|
||||
'9' => 2,
|
||||
];
|
||||
$isUpperBlock = static fn($g) => (bool) preg_match('/^(3|4|5|6|7|8)(-[AB])?$/', trim($g));
|
||||
$isGrade5 = static fn($g) => (bool) preg_match('/^5(\-|$)/', trim($g));
|
||||
|
||||
$b = $this->db->table('student_class sc')
|
||||
->select('sc.student_id, s.firstname, s.lastname, s.is_new, cs.class_section_name AS grade_label')
|
||||
->join('students s', 's.id = sc.student_id')
|
||||
->join('classSection cs', 'cs.class_section_id = sc.class_section_id')
|
||||
->join('classes c', 'c.id = cs.class_id')
|
||||
->where('sc.school_year', $schoolYear)
|
||||
->where('sc.class_section_id', $classSectionId);
|
||||
|
||||
|
||||
$rows = $b->get()->getResultArray();
|
||||
|
||||
$rows = array_values(array_filter($rows, static function ($r) {
|
||||
$g = trim((string) $r['grade_label']);
|
||||
return $g !== '' && strcasecmp($g, 'youth') !== 0 && strncasecmp($g, 'youth-', 6) !== 0;
|
||||
}));
|
||||
|
||||
$out = [];
|
||||
$tp = 0;
|
||||
$ts = 0;
|
||||
foreach ($rows as $r) {
|
||||
$g = trim((string) $r['grade_label']);
|
||||
$isNew = ((int) $r['is_new']) === 1;
|
||||
$p = 0;
|
||||
$s = 0;
|
||||
|
||||
if (isset($specialMap[$g])) {
|
||||
$p = $specialMap[$g];
|
||||
} elseif ($isUpperBlock($g)) {
|
||||
if ($isNew) {
|
||||
$p = 4;
|
||||
} else {
|
||||
$p = $isGrade5($g) ? 3 : 2;
|
||||
$s = max(0, 4 - $p);
|
||||
}
|
||||
} else {
|
||||
$p = 4;
|
||||
}
|
||||
|
||||
$tp += $p;
|
||||
$ts += $s;
|
||||
|
||||
$out[] = [
|
||||
'student_id' => (int) $r['student_id'],
|
||||
'firstname' => trim($r['firstname']),
|
||||
'lastname' => trim($r['lastname']),
|
||||
'grade_label' => $g,
|
||||
'primary_count' => $p,
|
||||
'secondary_count' => $s,
|
||||
];
|
||||
}
|
||||
|
||||
return ['students' => $out, 'totals' => ['primary' => $tp, 'secondary' => $ts, 'students' => count($out)]];
|
||||
}
|
||||
|
||||
public function previewStickerCounts()
|
||||
{
|
||||
// Optional: allow class_id filter; if present, preview only that class
|
||||
$classId = (int) ($this->request->getGet('class_id') ?? 0);
|
||||
|
||||
if ($classId > 0) {
|
||||
// same join as getStickerCountsPerStudent but add class filter
|
||||
$result = $this->getStickerCountsPerStudentForClass($this->schoolYear, $classId, $this->semester);
|
||||
} else {
|
||||
// whole school year
|
||||
$result = $this->getStickerCountsPerStudent($this->schoolYear, $this->semester);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'ok',
|
||||
'data' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
public function studentsByClass(int $classSectionId)
|
||||
{
|
||||
$rows = $this->studentModel
|
||||
->select('students.id, students.firstname, students.lastname, students.gender, cs.class_section_name AS registration_grade')
|
||||
->join('student_class sc', 'sc.student_id = students.id', 'inner')
|
||||
->join('classSection cs', 'cs.class_section_id = sc.class_section_id', 'inner')
|
||||
->where('sc.school_year', $this->schoolYear)
|
||||
->where('sc.class_section_id', $classSectionId)
|
||||
->groupBy('students.id, students.firstname, students.lastname, students.gender, cs.class_section_name')
|
||||
->orderBy('students.firstname', 'ASC')
|
||||
->orderBy('students.lastname', 'ASC')
|
||||
->findAll(1000);
|
||||
|
||||
return $this->response->setJSON($rows);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user