recreate project
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\View;
|
||||
use App\Controllers\BaseController;
|
||||
use CodeIgniter\Controller;
|
||||
use App\Models\TeacherClassModel;
|
||||
use App\Models\StudentModel;
|
||||
use App\Models\ConfigurationModel;
|
||||
use App\Models\GradingLockModel;
|
||||
use App\Models\MissingScoreOverrideModel;
|
||||
|
||||
class FinalController extends BaseController
|
||||
{
|
||||
protected $db;
|
||||
protected $schoolYear;
|
||||
protected $semester;
|
||||
protected $configModel;
|
||||
protected $studentModel;
|
||||
protected $teacherClassModel;
|
||||
protected $gradingLockModel;
|
||||
protected $missingScoreOverrideModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->db = \Config\Database::connect();
|
||||
$this->configModel = new ConfigurationModel();
|
||||
$this->studentModel = new StudentModel();
|
||||
$this->teacherClassModel = new TeacherClassModel();
|
||||
$this->schoolYear = $this->configModel->getConfig('school_year');
|
||||
$this->semester = $this->configModel->getConfig('semester');
|
||||
$this->gradingLockModel = new GradingLockModel();
|
||||
$this->missingScoreOverrideModel = new MissingScoreOverrideModel();
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
// Accept class_section_id from POST/GET with session fallback
|
||||
$incoming = $this->request->getPost('class_section_id')
|
||||
?? $this->request->getGet('class_section_id')
|
||||
?? session()->get('class_section_id');
|
||||
|
||||
$classSectionId = (int) ($incoming ?: 0);
|
||||
if ($classSectionId <= 0) {
|
||||
return redirect()->back()->with('status', 'Missing class section.');
|
||||
}
|
||||
|
||||
// Persist for downstream calls
|
||||
session()->set('class_section_id', $classSectionId);
|
||||
|
||||
$semester = $this->getTeacherSelectedSemester();
|
||||
$schoolYear = $this->schoolYear;
|
||||
try {
|
||||
$result = $this->getSavedScores($classSectionId, $semester, $schoolYear);
|
||||
$missingOkMap = $this->missingScoreOverrideModel->getOverridesMap($classSectionId, $semester, $schoolYear, 'final_exam');
|
||||
|
||||
return view('teacher/add_final_exam', [
|
||||
'students' => $result['students'],
|
||||
'semester' => $result['semester'],
|
||||
'schoolYear' => $result['schoolYear'],
|
||||
'classSectionId' => $classSectionId,
|
||||
'missingOkMap' => $missingOkMap,
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
return redirect()->back()->with('status', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function showFinalMngt()
|
||||
{
|
||||
$incoming = $this->request->getPost('class_section_id')
|
||||
?? $this->request->getGet('class_section_id')
|
||||
?? session()->get('class_section_id');
|
||||
|
||||
$classSectionId = (int) ($incoming ?: 0);
|
||||
if ($classSectionId <= 0) {
|
||||
return redirect()->back()->with('status', 'Missing class section.');
|
||||
}
|
||||
|
||||
$semester = $this->getTeacherSelectedSemester();
|
||||
$schoolYear = $this->schoolYear;
|
||||
try {
|
||||
$result = $this->getSavedScores($classSectionId, $semester, $schoolYear);
|
||||
$scoresLocked = $this->gradingLockModel->isLocked($classSectionId, $semester, $schoolYear);
|
||||
|
||||
return view('grading/final', [
|
||||
'students' => $result['students'],
|
||||
'semester' => $result['semester'],
|
||||
'schoolYear' => $result['schoolYear'],
|
||||
'classSectionId' => $classSectionId,
|
||||
'scoresLocked' => $scoresLocked,
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
return redirect()->back()->with('status', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function getSavedScores(int $classSectionId, string $semester, string $schoolYear): array
|
||||
{
|
||||
if ($classSectionId <= 0) {
|
||||
throw new \InvalidArgumentException('Invalid class section id.');
|
||||
}
|
||||
|
||||
session()->set('class_section_id', $classSectionId);
|
||||
|
||||
// Subquery: pick ONE final exam row per student (latest by id)
|
||||
$latestFinalSub = $this->db->table('final_exam')
|
||||
->select('student_id, MAX(id) AS max_id')
|
||||
->where('class_section_id', $classSectionId)
|
||||
->where('semester', $semester)
|
||||
->where('school_year', $schoolYear)
|
||||
->groupBy('student_id')
|
||||
->getCompiledSelect();
|
||||
|
||||
// Main query: roster + LEFT JOIN the single final exam row
|
||||
$qb = $this->studentModel
|
||||
->select('
|
||||
s.id AS student_id,
|
||||
s.school_id,
|
||||
s.firstname,
|
||||
s.lastname,
|
||||
fe.score
|
||||
')
|
||||
->from('students s')
|
||||
->join(
|
||||
'student_class sc',
|
||||
'sc.student_id = s.id
|
||||
AND sc.class_section_id = ' . (int) $classSectionId . '
|
||||
AND sc.school_year = ' . $this->db->escape($schoolYear),
|
||||
'inner',
|
||||
false
|
||||
)
|
||||
->join('(' . $latestFinalSub . ') fl', 'fl.student_id = s.id', 'left', false)
|
||||
->join('final_exam fe', 'fe.id = fl.max_id', 'left')
|
||||
->orderBy('s.lastname', 'ASC')
|
||||
->orderBy('s.firstname', 'ASC');
|
||||
|
||||
$qb->distinct();
|
||||
$rows = $qb->get()->getResultArray();
|
||||
|
||||
// Ensure one row per student
|
||||
$unique = [];
|
||||
foreach ($rows as $r) {
|
||||
$unique[(int)$r['student_id']] = $r;
|
||||
}
|
||||
$students = array_values($unique);
|
||||
|
||||
return [
|
||||
'students' => $students,
|
||||
'semester' => $semester,
|
||||
'schoolYear' => $schoolYear,
|
||||
];
|
||||
}
|
||||
|
||||
private function getTeacherSelectedSemester(): string
|
||||
{
|
||||
helper('semester_selection_helper');
|
||||
return selected_teacher_semester();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user