From 3f25ca6c8a35bde1fd9b19af34fc1e3353cc2948 Mon Sep 17 00:00:00 2001 From: Novy San87 Date: Thu, 6 Aug 2026 13:10:41 +0700 Subject: [PATCH] feat: endpoint nilai wali (teacher_grades e-jurnal per mapel + rata-rata) --- .../Api/ParentStudentController.php | 57 +++++++++++++++++++ routes/api.php | 1 + 2 files changed, 58 insertions(+) diff --git a/app/Http/Controllers/Api/ParentStudentController.php b/app/Http/Controllers/Api/ParentStudentController.php index 49bacbb..b24850d 100644 --- a/app/Http/Controllers/Api/ParentStudentController.php +++ b/app/Http/Controllers/Api/ParentStudentController.php @@ -340,6 +340,63 @@ class ParentStudentController extends Controller ]); } + /** + * Nilai putra/putri (dari teacher_grades e-jurnal, dikelompokkan per mapel). + */ + public function grades(Request $request, Student $student): JsonResponse + { + $hasLink = ParentStudent::where('user_id', $request->user()->id) + ->where('student_id', $student->id) + ->where('status', 'active') + ->exists(); + + abort_unless($hasLink, 403, 'Putra/putri belum tertaut aktif.'); + + try { + $db = DB::connection('ejurnal'); + $ejStudent = $db->table('students')->where('nisn', $student->nisn)->first(); + if (! $ejStudent) { + return response()->json(['subjects' => [], 'overall_average' => null]); + } + + $rows = $db->table('teacher_grades as tg') + ->join('schedules as s', 's.id', '=', 'tg.schedule_id') + ->join('subjects as sub', 'sub.id', '=', 's.subject_id') + ->where('tg.student_id', $ejStudent->id) + ->orderBy('sub.name') + ->orderByDesc('tg.date') + ->get(['tg.label', 'tg.score', 'tg.category', 'tg.date', 'sub.name as subject']); + + $bySubject = $rows->groupBy('subject'); + $subjects = $bySubject->map(function ($items, $subject) { + $scores = $items->pluck('score')->map(fn ($s) => (int) $s); + + return [ + 'subject' => $subject, + 'average' => $scores->isNotEmpty() ? round($scores->avg(), 1) : null, + 'entries' => $items->map(fn ($r) => [ + 'label' => $r->label, + 'score' => (int) $r->score, + 'category' => $r->category, + 'date' => $r->date, + ])->values(), + ]; + })->values(); + + $allScores = $rows->pluck('score')->map(fn ($s) => (int) $s); + + return response()->json([ + 'subjects' => $subjects, + 'overall_average' => $allScores->isNotEmpty() ? round($allScores->avg(), 1) : null, + 'total_entries' => $rows->count(), + ]); + } catch (\Throwable $e) { + Log::error('Nilai gagal dimuat: '.$e->getMessage()); + + return response()->json(['message' => 'Nilai belum tersedia.'], 404); + } + } + /** * Tautkan anak tambahan (kakak/adik) ke akun wali. */ diff --git a/routes/api.php b/routes/api.php index 655ed3f..27a9184 100644 --- a/routes/api.php +++ b/routes/api.php @@ -39,6 +39,7 @@ Route::middleware('auth:sanctum')->prefix('parent')->group(function () { Route::get('/students/{student}/attendance', [ParentStudentController::class, 'attendance'])->name('api.parent.students.attendance'); Route::get('/students/{student}/points-history', [ParentStudentController::class, 'pointsHistory'])->name('api.parent.students.points-history'); Route::get('/students/{student}/violations-stats', [ParentStudentController::class, 'violationsStats'])->name('api.parent.students.violations-stats'); + Route::get('/students/{student}/grades', [ParentStudentController::class, 'grades'])->name('api.parent.students.grades'); // Notifikasi & perangkat Route::get('/notifications', [ParentNotificationController::class, 'index'])->name('api.parent.notifications');