fix teacher page
This commit is contained in:
@@ -44,6 +44,7 @@ class ScoreController extends BaseApiController
|
|||||||
'semester' => $data['semester'] ?? null,
|
'semester' => $data['semester'] ?? null,
|
||||||
'school_year' => $data['school_year'] ?? null,
|
'school_year' => $data['school_year'] ?? null,
|
||||||
'scores_locked' => $data['scoresLocked'] ?? false,
|
'scores_locked' => $data['scoresLocked'] ?? false,
|
||||||
|
'missing_ok_map' => $data['missing_ok_map'] ?? [],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ class TeacherClass extends BaseModel
|
|||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'teacher_id',
|
'teacher_id',
|
||||||
'class_section_id',
|
'class_section_id',
|
||||||
|
'semester',
|
||||||
'school_year',
|
'school_year',
|
||||||
'position',
|
'position',
|
||||||
'updated_by',
|
'updated_by',
|
||||||
@@ -404,6 +405,7 @@ class TeacherClass extends BaseModel
|
|||||||
return [
|
return [
|
||||||
'teacher_id' => [$req, 'integer', 'min:1', 'exists:users,id'],
|
'teacher_id' => [$req, 'integer', 'min:1', 'exists:users,id'],
|
||||||
'class_section_id' => [$req, 'integer', 'min:1'],
|
'class_section_id' => [$req, 'integer', 'min:1'],
|
||||||
|
'semester' => [$req, 'string', 'max:25'],
|
||||||
'school_year' => [$req, 'string', 'max:9'],
|
'school_year' => [$req, 'string', 'max:9'],
|
||||||
'position' => [$req, 'string', 'in:' . implode(',', self::allowedPositions())],
|
'position' => [$req, 'string', 'in:' . implode(',', self::allowedPositions())],
|
||||||
'updated_by' => ['nullable', 'integer'],
|
'updated_by' => ['nullable', 'integer'],
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ class ScoreDashboardService
|
|||||||
'homework' => $this->normalizeScore($scoreRow->homework_avg),
|
'homework' => $this->normalizeScore($scoreRow->homework_avg),
|
||||||
'quiz' => $this->normalizeScore($scoreRow->quiz_avg),
|
'quiz' => $this->normalizeScore($scoreRow->quiz_avg),
|
||||||
'project' => $this->normalizeScore($scoreRow->project_avg),
|
'project' => $this->normalizeScore($scoreRow->project_avg),
|
||||||
|
'participation' => $this->normalizeScore($scoreRow->participation_score),
|
||||||
'midterm_exam' => $this->normalizeScore($scoreRow->midterm_exam_score),
|
'midterm_exam' => $this->normalizeScore($scoreRow->midterm_exam_score),
|
||||||
'final_exam' => $this->normalizeScore($scoreRow->final_exam_score),
|
'final_exam' => $this->normalizeScore($scoreRow->final_exam_score),
|
||||||
'attendance' => $this->normalizeScore($scoreRow->attendance_score),
|
'attendance' => $this->normalizeScore($scoreRow->attendance_score),
|
||||||
@@ -125,6 +126,24 @@ class ScoreDashboardService
|
|||||||
unset($student);
|
unset($student);
|
||||||
|
|
||||||
$classSection = ClassSection::query()->where('class_section_id', $classSectionId)->first();
|
$classSection = ClassSection::query()->where('class_section_id', $classSectionId)->first();
|
||||||
|
$missingOkMap = [
|
||||||
|
'ptap_comment' => MissingScoreOverride::getOverridesMap($classSectionId, $semesterLabel, $schoolYear, 'ptap_comment'),
|
||||||
|
];
|
||||||
|
if (strtolower($semesterLabel) === 'fall') {
|
||||||
|
$missingOkMap['midterm_comment'] = MissingScoreOverride::getOverridesMap(
|
||||||
|
$classSectionId,
|
||||||
|
$semesterLabel,
|
||||||
|
$schoolYear,
|
||||||
|
'midterm_comment'
|
||||||
|
);
|
||||||
|
} elseif (strtolower($semesterLabel) === 'spring') {
|
||||||
|
$missingOkMap['final_comment'] = MissingScoreOverride::getOverridesMap(
|
||||||
|
$classSectionId,
|
||||||
|
$semesterLabel,
|
||||||
|
$schoolYear,
|
||||||
|
'final_comment'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'students' => $students,
|
'students' => $students,
|
||||||
@@ -133,6 +152,7 @@ class ScoreDashboardService
|
|||||||
'semester' => $semesterLabel,
|
'semester' => $semesterLabel,
|
||||||
'school_year' => $schoolYear,
|
'school_year' => $schoolYear,
|
||||||
'scoresLocked' => GradingLock::isLocked($classSectionId, $semesterLabel, $schoolYear),
|
'scoresLocked' => GradingLock::isLocked($classSectionId, $semesterLabel, $schoolYear),
|
||||||
|
'missing_ok_map' => $missingOkMap,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class TeacherAssignmentService
|
|||||||
{
|
{
|
||||||
$context = $this->configService->context();
|
$context = $this->configService->context();
|
||||||
$schoolYear = $schoolYear ?: (string) ($context['school_year'] ?? '');
|
$schoolYear = $schoolYear ?: (string) ($context['school_year'] ?? '');
|
||||||
|
$semester = trim((string) ($context['semester'] ?? ''));
|
||||||
|
|
||||||
$teachers = User::getTeachersAndTAs();
|
$teachers = User::getTeachersAndTAs();
|
||||||
$classSections = ClassSection::query()
|
$classSections = ClassSection::query()
|
||||||
@@ -39,6 +40,7 @@ class TeacherAssignmentService
|
|||||||
|
|
||||||
$assignments = TeacherClass::query()
|
$assignments = TeacherClass::query()
|
||||||
->when($schoolYear !== '', fn ($q) => $q->where('school_year', $schoolYear))
|
->when($schoolYear !== '', fn ($q) => $q->where('school_year', $schoolYear))
|
||||||
|
->when($semester !== '', fn ($q) => $q->where('semester', $semester))
|
||||||
->get()
|
->get()
|
||||||
->toArray();
|
->toArray();
|
||||||
|
|
||||||
@@ -113,12 +115,13 @@ class TeacherAssignmentService
|
|||||||
{
|
{
|
||||||
$context = $this->configService->context();
|
$context = $this->configService->context();
|
||||||
$schoolYear = (string) ($input['school_year'] ?? $context['school_year'] ?? '');
|
$schoolYear = (string) ($input['school_year'] ?? $context['school_year'] ?? '');
|
||||||
|
$semester = trim((string) ($input['semester'] ?? $context['semester'] ?? ''));
|
||||||
$teacherId = (int) ($input['teacher_id'] ?? 0);
|
$teacherId = (int) ($input['teacher_id'] ?? 0);
|
||||||
$classSectionId = (int) ($input['class_section_id'] ?? 0);
|
$classSectionId = (int) ($input['class_section_id'] ?? 0);
|
||||||
$teacherRole = (string) ($input['teacher_role'] ?? '');
|
$teacherRole = (string) ($input['teacher_role'] ?? '');
|
||||||
$loggedInUserId = (int) ($input['updated_by'] ?? 0);
|
$loggedInUserId = (int) ($input['updated_by'] ?? 0);
|
||||||
|
|
||||||
if ($teacherId <= 0 || $classSectionId <= 0 || $schoolYear === '') {
|
if ($teacherId <= 0 || $classSectionId <= 0 || $schoolYear === '' || $semester === '') {
|
||||||
return ['ok' => false, 'message' => 'Missing required parameters for assignment.'];
|
return ['ok' => false, 'message' => 'Missing required parameters for assignment.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +135,7 @@ class TeacherAssignmentService
|
|||||||
->where('teacher_id', $teacherId)
|
->where('teacher_id', $teacherId)
|
||||||
->where('class_section_id', $classSectionId)
|
->where('class_section_id', $classSectionId)
|
||||||
->where('position', $position)
|
->where('position', $position)
|
||||||
|
->where('semester', $semester)
|
||||||
->where('school_year', $schoolYear)
|
->where('school_year', $schoolYear)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
@@ -143,6 +147,7 @@ class TeacherAssignmentService
|
|||||||
'teacher_id' => $teacherId,
|
'teacher_id' => $teacherId,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'position' => $position,
|
'position' => $position,
|
||||||
|
'semester' => $semester,
|
||||||
'school_year' => $schoolYear,
|
'school_year' => $schoolYear,
|
||||||
'created_at' => now(),
|
'created_at' => now(),
|
||||||
'updated_at' => now(),
|
'updated_at' => now(),
|
||||||
@@ -162,15 +167,17 @@ class TeacherAssignmentService
|
|||||||
$teacherId = (int) ($input['teacher_id'] ?? 0);
|
$teacherId = (int) ($input['teacher_id'] ?? 0);
|
||||||
$classSectionId = (int) ($input['class_section_id'] ?? 0);
|
$classSectionId = (int) ($input['class_section_id'] ?? 0);
|
||||||
$position = strtolower((string) ($input['position'] ?? ''));
|
$position = strtolower((string) ($input['position'] ?? ''));
|
||||||
|
$semester = trim((string) ($input['semester'] ?? $context['semester'] ?? ''));
|
||||||
$schoolYear = trim((string) ($input['school_year'] ?? $context['school_year'] ?? ''));
|
$schoolYear = trim((string) ($input['school_year'] ?? $context['school_year'] ?? ''));
|
||||||
|
|
||||||
if ($teacherId <= 0 || $classSectionId <= 0 || !in_array($position, ['main', 'ta'], true) || $schoolYear === '') {
|
if ($teacherId <= 0 || $classSectionId <= 0 || !in_array($position, ['main', 'ta'], true) || $schoolYear === '' || $semester === '') {
|
||||||
return ['ok' => false, 'message' => 'Missing or invalid data for deletion.'];
|
return ['ok' => false, 'message' => 'Missing or invalid data for deletion.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$assignment = TeacherClass::query()
|
$assignment = TeacherClass::query()
|
||||||
->where('teacher_id', $teacherId)
|
->where('teacher_id', $teacherId)
|
||||||
->where('class_section_id', $classSectionId)
|
->where('class_section_id', $classSectionId)
|
||||||
|
->where('semester', $semester)
|
||||||
->where('school_year', $schoolYear)
|
->where('school_year', $schoolYear)
|
||||||
->where('position', $position)
|
->where('position', $position)
|
||||||
->first();
|
->first();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -80,4 +80,10 @@ Route::middleware('web')->group(function () {
|
|||||||
->name('teacher.calendar');
|
->name('teacher.calendar');
|
||||||
Route::middleware('auth')->get('app/teacher/calendar', [TeacherCalendarPageController::class, 'show'])
|
Route::middleware('auth')->get('app/teacher/calendar', [TeacherCalendarPageController::class, 'show'])
|
||||||
->name('app.teacher.calendar');
|
->name('app.teacher.calendar');
|
||||||
|
Route::middleware('auth')->get('teacher/absence-vacation', function () {
|
||||||
|
return redirect('/app/teacher/absence-vacation');
|
||||||
|
})->name('teacher.absence-vacation');
|
||||||
|
Route::middleware('auth')->get('teacher/absence_vacation', function () {
|
||||||
|
return redirect('/app/teacher/absence-vacation');
|
||||||
|
})->name('teacher.absence_vacation');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class TeacherClassAssignmentControllerTest extends TestCase
|
|||||||
$this->seedTeacherUser();
|
$this->seedTeacherUser();
|
||||||
$this->seedClassSection();
|
$this->seedClassSection();
|
||||||
|
|
||||||
Sanctum::actingAs($admin);
|
Sanctum::actingAs($admin, [], 'api');
|
||||||
$response = $this->getJson('/api/v1/administrator/teacher-class/assignments?school_year=2025-2026');
|
$response = $this->getJson('/api/v1/administrator/teacher-class/assignments?school_year=2025-2026');
|
||||||
|
|
||||||
$response->assertOk();
|
$response->assertOk();
|
||||||
@@ -35,7 +35,7 @@ class TeacherClassAssignmentControllerTest extends TestCase
|
|||||||
$teacher = $this->seedTeacherUser();
|
$teacher = $this->seedTeacherUser();
|
||||||
$classSectionId = $this->seedClassSection();
|
$classSectionId = $this->seedClassSection();
|
||||||
|
|
||||||
Sanctum::actingAs($admin);
|
Sanctum::actingAs($admin, [], 'api');
|
||||||
$storeResponse = $this->postJson('/api/v1/administrator/teacher-class/assign', [
|
$storeResponse = $this->postJson('/api/v1/administrator/teacher-class/assign', [
|
||||||
'teacher_id' => $teacher->id,
|
'teacher_id' => $teacher->id,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
@@ -48,6 +48,8 @@ class TeacherClassAssignmentControllerTest extends TestCase
|
|||||||
'teacher_id' => $teacher->id,
|
'teacher_id' => $teacher->id,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'position' => 'main',
|
'position' => 'main',
|
||||||
|
'semester' => 'Fall',
|
||||||
|
'school_year' => '2025-2026',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$deleteResponse = $this->postJson('/api/v1/administrator/teacher-class/delete', [
|
$deleteResponse = $this->postJson('/api/v1/administrator/teacher-class/delete', [
|
||||||
@@ -62,6 +64,8 @@ class TeacherClassAssignmentControllerTest extends TestCase
|
|||||||
'teacher_id' => $teacher->id,
|
'teacher_id' => $teacher->id,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'position' => 'main',
|
'position' => 'main',
|
||||||
|
'semester' => 'Fall',
|
||||||
|
'school_year' => '2025-2026',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +79,12 @@ class TeacherClassAssignmentControllerTest extends TestCase
|
|||||||
|
|
||||||
private function seedAdminUser(): User
|
private function seedAdminUser(): User
|
||||||
{
|
{
|
||||||
|
$roleId = DB::table('roles')->insertGetId([
|
||||||
|
'name' => 'administrator',
|
||||||
|
'slug' => 'administrator',
|
||||||
|
'is_active' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
$userId = DB::table('users')->insertGetId([
|
$userId = DB::table('users')->insertGetId([
|
||||||
'firstname' => 'Admin',
|
'firstname' => 'Admin',
|
||||||
'lastname' => 'User',
|
'lastname' => 'User',
|
||||||
@@ -92,6 +102,11 @@ class TeacherClassAssignmentControllerTest extends TestCase
|
|||||||
'status' => 'Active',
|
'status' => 'Active',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
DB::table('user_roles')->insert([
|
||||||
|
'user_id' => $userId,
|
||||||
|
'role_id' => $roleId,
|
||||||
|
]);
|
||||||
|
|
||||||
return User::query()->findOrFail($userId);
|
return User::query()->findOrFail($userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Encryption\Encrypter;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class TeacherAbsenceVacationRouteTest extends TestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$key = 'base64:'.base64_encode(random_bytes(32));
|
||||||
|
config([
|
||||||
|
'app.key' => $key,
|
||||||
|
'app.cipher' => 'aes-256-cbc',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$rawKey = base64_decode(substr($key, 7), true);
|
||||||
|
$this->app->instance('encrypter', new Encrypter($rawKey, 'aes-256-cbc'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_authenticated_teacher_absence_vacation_route_redirects_to_spa_page(): void
|
||||||
|
{
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->get('/teacher/absence-vacation');
|
||||||
|
|
||||||
|
$response->assertRedirect('/app/teacher/absence-vacation');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_authenticated_legacy_teacher_absence_vacation_route_redirects_to_spa_page(): void
|
||||||
|
{
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->get('/teacher/absence_vacation');
|
||||||
|
|
||||||
|
$response->assertRedirect('/app/teacher/absence-vacation');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,8 @@ class TeacherAssignmentServiceTest extends TestCase
|
|||||||
'teacher_id' => $teacherId,
|
'teacher_id' => $teacherId,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'position' => 'main',
|
'position' => 'main',
|
||||||
|
'semester' => 'Fall',
|
||||||
|
'school_year' => '2025-2026',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,6 +45,7 @@ class TeacherAssignmentServiceTest extends TestCase
|
|||||||
'teacher_id' => $teacherId,
|
'teacher_id' => $teacherId,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'position' => 'ta',
|
'position' => 'ta',
|
||||||
|
'semester' => 'Fall',
|
||||||
'school_year' => '2025-2026',
|
'school_year' => '2025-2026',
|
||||||
'created_at' => now(),
|
'created_at' => now(),
|
||||||
'updated_at' => now(),
|
'updated_at' => now(),
|
||||||
@@ -60,6 +63,8 @@ class TeacherAssignmentServiceTest extends TestCase
|
|||||||
'teacher_id' => $teacherId,
|
'teacher_id' => $teacherId,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'position' => 'ta',
|
'position' => 'ta',
|
||||||
|
'semester' => 'Fall',
|
||||||
|
'school_year' => '2025-2026',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user