query('school_year'); if ($schoolYearParam !== null) { $schoolYear = trim((string) $schoolYearParam); } else { try { $schoolYear = trim((string) (Configuration::getConfig('school_year') ?? '')); } catch (\Throwable) { $schoolYear = ''; } } $classSectionId = $request->query('class_section_id'); try { $classSections = DB::table('classSection') ->select('class_section_id', 'class_section_name') ->orderBy('class_section_name', 'ASC') ->get() ->map(fn ($r) => (array) $r) ->all(); } catch (\Throwable $e) { Log::error('Certificate formOptions class query failed: ' . $e->getMessage()); return $this->error('Failed to load classes: ' . $e->getMessage(), 500); } $students = []; if ($classSectionId) { try { $studentQuery = DB::table('student_class as sc') ->select('s.id', 's.firstname', 's.lastname', 'cs.class_section_name as grade') ->join('students as s', 's.id', '=', 'sc.student_id') ->join('classSection as cs', 'cs.class_section_id', '=', 'sc.class_section_id') ->where('sc.class_section_id', (int) $classSectionId) ->where('s.is_active', 1) ->orderBy('s.lastname') ->orderBy('s.firstname'); if ($schoolYear !== '') { $studentQuery->where('sc.school_year', $schoolYear); } $students = $studentQuery->get()->map(fn ($r) => (array) $r)->all(); } catch (\Throwable $e) { Log::error('Certificate formOptions student query failed: ' . $e->getMessage()); return $this->error('Failed to load students: ' . $e->getMessage(), 500); } } return $this->success([ 'class_sections' => $classSections, 'students' => $students, 'school_year' => $schoolYear, 'selected_class_id' => $classSectionId, ]); } /** * POST /api/v1/administrator/certificates/generate */ public function generate(Request $request): Response|JsonResponse { $studentIds = $request->input('student_ids', []); $certDate = trim((string) ($request->input('cert_date') ?? date('m/d/Y'))); $classSectionId = $request->input('class_section_id'); if (empty($studentIds) || !is_array($studentIds)) { return $this->error('Please select at least one student.', 422); } $studentIds = array_values(array_filter(array_map('intval', $studentIds))); $certDate = preg_replace('/[^0-9\/\-]/', '', $certDate) ?? date('m/d/Y'); if (empty($studentIds)) { return $this->error('Invalid student selection.', 422); } $students = []; foreach ($studentIds as $id) { $row = null; if ($classSectionId) { $row = DB::table('student_class as sc') ->select('s.id', 's.firstname', 's.lastname', 'cs.class_section_name as grade') ->join('students as s', 's.id', '=', 'sc.student_id') ->join('classSection as cs', 'cs.class_section_id', '=', 'sc.class_section_id') ->where('sc.class_section_id', (int) $classSectionId) ->where('s.id', $id) ->first(); } if (!$row) { $row = DB::table('students') ->select('id', 'firstname', 'lastname', 'registration_grade as grade') ->where('id', $id) ->first(); } if ($row) { $students[] = (array) $row; } } if (empty($students)) { return $this->error('No valid students found.', 422); } try { $pdfService = app(CertificatePdfService::class); $pdfContent = $pdfService->generate($students, $certDate); } catch (\Throwable $e) { Log::error('Certificate PDF generation failed: ' . $e->getMessage(), ['exception' => $e]); return $this->error('Failed to generate certificates.', 500); } $filename = 'Certificates_' . date('Ymd_His') . '.pdf'; return response($pdfContent, 200, [ 'Content-Type' => 'application/pdf', 'Content-Disposition' => 'inline; filename="' . $filename . '"', ]); } private function currentSchoolYear(): string { return trim((string) (Configuration::getConfig('school_year') ?? '')); } }