From 21c93221277e7a7eb2925fe851dce50a954c51ac Mon Sep 17 00:00:00 2001 From: root Date: Tue, 7 Jul 2026 22:02:42 -0400 Subject: [PATCH] partial fix for teacher class progress --- .../ClassProgress/ClassProgressController.php | 17 +++-- app/Models/SubjectCurriculum.php | 8 ++- .../ClassProgressMetaService.php | 47 +++++++++++++ .../ClassProgressControllerTest.php | 70 +++++++++++++++++++ tests/Unit/Models/SubjectCurriculumTest.php | 2 +- 5 files changed, 137 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Api/ClassProgress/ClassProgressController.php b/app/Http/Controllers/Api/ClassProgress/ClassProgressController.php index 16d3a376..3f400cf4 100644 --- a/app/Http/Controllers/Api/ClassProgress/ClassProgressController.php +++ b/app/Http/Controllers/Api/ClassProgress/ClassProgressController.php @@ -59,15 +59,23 @@ class ClassProgressController extends BaseApiController return $auth; } - $schoolYear = (string) (Configuration::getConfig('school_year') ?? ''); - $semester = (string) (Configuration::getConfig('semester') ?? ''); + $schoolYear = trim((string) $request->query('school_year', Configuration::getConfig('school_year') ?? '')); + $semester = trim((string) $request->query('semester', Configuration::getConfig('semester') ?? '')); $assignments = $this->queryService->teacherAssignments($auth, $schoolYear, $semester); $requestedClassId = (int) ($request->validated('class_id') ?? 0); - $activeClassId = $requestedClassId > 0 ? $requestedClassId : (int) ($assignments[0]['class_id'] ?? 0); + $requestedClassSectionId = (int) $request->query('class_section_id', 0); + $requestedAssignment = $requestedClassSectionId > 0 + ? collect($assignments)->first( + fn (array $assignment) => (int) ($assignment['class_section_id'] ?? 0) === $requestedClassSectionId + ) + : null; + $activeClassId = $requestedClassId > 0 + ? $requestedClassId + : (int) (($requestedAssignment['class_id'] ?? null) ?: ($assignments[0]['class_id'] ?? 0)); $activeAssignment = collect($assignments)->first( fn (array $assignment) => (int) ($assignment['class_id'] ?? 0) === $activeClassId - ) ?? ($assignments[0] ?? []); + ) ?? $requestedAssignment ?? ($assignments[0] ?? []); $sundayCount = (int) ($request->validated('sunday_count') ?? 12); $payload = $this->buildMetaPayload($activeClassId > 0 ? $activeClassId : null, $sundayCount, $schoolYear, $semester); $payload['classes'] = $assignments; @@ -294,6 +302,7 @@ class ClassProgressController extends BaseApiController 'status_options' => $this->metaService->statusOptions(), 'sunday_options' => $this->metaService->sundayOptionsAlignedWithCi($sundayCount), 'curriculum' => $this->metaService->curriculumOptions($classId, $meta['school_year'] ?? null), + 'unit_options' => $this->metaService->unitOptions($classId, $meta['school_year'] ?? null), 'meta' => $meta, ]; } diff --git a/app/Models/SubjectCurriculum.php b/app/Models/SubjectCurriculum.php index ff925fed..ce6bf703 100644 --- a/app/Models/SubjectCurriculum.php +++ b/app/Models/SubjectCurriculum.php @@ -10,7 +10,7 @@ class SubjectCurriculum extends BaseModel { protected $table = 'subject_curriculum_items'; - protected $fillable = ['class_id', 'subject', 'unit_number', 'unit_title', 'chapter_name', 'created_at', 'updated_at']; + protected $fillable = ['class_id', 'school_year', 'subject', 'unit_number', 'unit_title', 'chapter_name', 'created_at', 'updated_at']; public $timestamps = true; @@ -54,7 +54,11 @@ class SubjectCurriculum extends BaseModel return $q; } - return $q->where('school_year', $schoolYear); + return $q->where(function (Builder $yearQuery) use ($schoolYear) { + $yearQuery->where('school_year', $schoolYear) + ->orWhereNull('school_year') + ->orWhere('school_year', ''); + }); } public function scopeOrdered(Builder $q): Builder diff --git a/app/Services/ClassProgress/ClassProgressMetaService.php b/app/Services/ClassProgress/ClassProgressMetaService.php index bc04e930..99039457 100644 --- a/app/Services/ClassProgress/ClassProgressMetaService.php +++ b/app/Services/ClassProgress/ClassProgressMetaService.php @@ -151,4 +151,51 @@ class ClassProgressMetaService return $options; } + + public function unitOptions(?int $classId, ?string $schoolYear = null): array + { + $curriculum = $this->curriculumOptions($classId, $schoolYear); + $units = []; + + foreach ($curriculum as $slug => $rows) { + $seen = []; + $units[$slug] = []; + + foreach ($rows as $row) { + $unitNumber = $row->unit_number ?? null; + $unitTitle = trim((string) ($row->unit_title ?? '')); + + if ($unitNumber === null && $unitTitle === '') { + continue; + } + + $key = ((string) $unitNumber).'|'.$unitTitle; + if (isset($seen[$key])) { + continue; + } + + $seen[$key] = true; + $units[$slug][] = [ + 'unit_number' => $unitNumber !== null ? (int) $unitNumber : null, + 'unit_title' => $unitTitle, + 'label' => $this->formatUnitLabel($unitNumber !== null ? (int) $unitNumber : null, $unitTitle), + ]; + } + } + + return $units; + } + + private function formatUnitLabel(?int $unitNumber, string $unitTitle): string + { + if ($unitNumber !== null && $unitTitle !== '') { + return 'Unit '.$unitNumber.' - '.$unitTitle; + } + + if ($unitNumber !== null) { + return 'Unit '.$unitNumber; + } + + return $unitTitle; + } } diff --git a/tests/Feature/Api/V1/ClassProgress/ClassProgressControllerTest.php b/tests/Feature/Api/V1/ClassProgress/ClassProgressControllerTest.php index 53c0ee71..d6630fed 100644 --- a/tests/Feature/Api/V1/ClassProgress/ClassProgressControllerTest.php +++ b/tests/Feature/Api/V1/ClassProgress/ClassProgressControllerTest.php @@ -27,6 +27,76 @@ class ClassProgressControllerTest extends TestCase $this->assertNotEmpty($response->json('data.subject_sections')); } + public function test_legacy_teacher_submit_meta_uses_requested_year_and_legacy_curriculum_units(): void + { + $user = $this->createUser(); + DB::table('configuration')->updateOrInsert( + ['config_key' => 'school_year'], + ['config_value' => '2024-2025'] + ); + DB::table('configuration')->updateOrInsert( + ['config_key' => 'semester'], + ['config_value' => 'Spring'] + ); + DB::table('school_years')->updateOrInsert([ + 'name' => '2025-2026', + ], [ + 'start_date' => '2025-08-01', + 'end_date' => '2026-07-31', + 'status' => 'active', + 'is_current' => 1, + 'created_at' => now(), + 'updated_at' => now(), + ]); + DB::table('classes')->insert([ + 'id' => 9, + 'class_name' => 'Grade 9', + 'schedule' => 'Sunday', + 'capacity' => 25, + 'semester' => 'Fall', + 'school_year' => '2025-2026', + ]); + DB::table('classSection')->insert([ + 'id' => 9, + 'class_id' => 9, + 'class_section_id' => 909, + 'class_section_name' => '9-A', + 'semester' => 'Fall', + 'school_year' => '2025-2026', + ]); + DB::table('teacher_class')->insert([ + 'class_section_id' => 909, + 'teacher_id' => $user->id, + 'position' => 'main', + 'semester' => 'Fall', + 'school_year' => '2025-2026', + 'created_at' => now(), + 'updated_at' => now(), + ]); + DB::table('subject_curriculum_items')->insert([ + 'class_id' => 9, + 'school_year' => null, + 'subject' => 'islamic', + 'unit_number' => 1, + 'unit_title' => 'Faith', + 'chapter_name' => 'Intro', + 'created_at' => now(), + 'updated_at' => now(), + ]); + + Sanctum::actingAs($user); + + $response = $this->getJson('/api/v1/teacher/class-progress-submit?school_year=2025-2026&semester=Fall&class_section_id=909'); + + $response->assertOk(); + $response->assertJsonPath('status', true); + $response->assertJsonPath('data.defaults.school_year', '2025-2026'); + $response->assertJsonPath('data.defaults.semester', 'Fall'); + $response->assertJsonPath('data.defaults.class_section_id', 909); + $response->assertJsonPath('data.curriculum.islamic.0.chapter_name', 'Intro'); + $response->assertJsonPath('data.unit_options.islamic.0.label', 'Unit 1 - Faith'); + } + public function test_index_returns_paginated_reports(): void { $user = $this->createUser(); diff --git a/tests/Unit/Models/SubjectCurriculumTest.php b/tests/Unit/Models/SubjectCurriculumTest.php index a9a873f6..ab09341c 100644 --- a/tests/Unit/Models/SubjectCurriculumTest.php +++ b/tests/Unit/Models/SubjectCurriculumTest.php @@ -14,7 +14,7 @@ class SubjectCurriculumTest extends TestCase $this->assertSame('subject_curriculum_items', $model->getTable()); $this->assertSame('id', $model->getKeyName()); $this->assertSame(true, $model->timestamps); - $this->assertSame(['class_id', 'subject', 'unit_number', 'unit_title', 'chapter_name', 'created_at', 'updated_at'], $model->getFillable()); + $this->assertSame(['class_id', 'school_year', 'subject', 'unit_number', 'unit_title', 'chapter_name', 'created_at', 'updated_at'], $model->getFillable()); } public function test_model_class_loads(): void