fix financial and certificates
This commit is contained in:
@@ -5,149 +5,141 @@ declare(strict_types=1);
|
||||
namespace App\Http\Controllers\Api\Certificates;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Models\Configuration;
|
||||
use App\Services\Certificates\CertificateAdminService;
|
||||
use App\Services\Certificates\CertificatePdfService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CertificateController extends BaseApiController
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
public function __construct(
|
||||
private CertificateAdminService $service,
|
||||
private CertificatePdfService $pdfService,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/administrator/certificates/form-options
|
||||
*/
|
||||
public function formOptions(Request $request): JsonResponse
|
||||
public function dashboard(Request $request): JsonResponse
|
||||
{
|
||||
$schoolYearParam = $request->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();
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => $this->service->dashboard($request->query('school_year')),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Certificate formOptions class query failed: ' . $e->getMessage());
|
||||
return $this->error('Failed to load classes: ' . $e->getMessage(), 500);
|
||||
Log::error('Certificate dashboard failed', ['exception' => $e]);
|
||||
|
||||
return $this->error('Failed to load certificate dashboard.', 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function formOptions(Request $request): JsonResponse
|
||||
{
|
||||
return $this->dashboard($request);
|
||||
}
|
||||
|
||||
public function auditLog(Request $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => $this->service->auditLog($request->query('school_year')),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Certificate audit log failed', ['exception' => $e]);
|
||||
|
||||
return $this->error('Failed to load certificate audit log.', 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')));
|
||||
$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);
|
||||
}
|
||||
$schoolYear = $request->input('school_year');
|
||||
|
||||
try {
|
||||
$pdfService = app(CertificatePdfService::class);
|
||||
$pdfContent = $pdfService->generate($students, $certDate);
|
||||
$payload = $this->service->issueCertificates(
|
||||
is_array($studentIds) ? $studentIds : [],
|
||||
$certDate,
|
||||
$classSectionId !== null && $classSectionId !== '' ? (int) $classSectionId : null,
|
||||
is_string($schoolYear) ? $schoolYear : null,
|
||||
$this->getCurrentUserId()
|
||||
);
|
||||
$pdfContent = $this->pdfService->generate(
|
||||
$payload['students'],
|
||||
$payload['cert_date_display']
|
||||
);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return $this->error($e->getMessage(), 422);
|
||||
} catch (\RuntimeException $e) {
|
||||
return $this->error($e->getMessage(), 422);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Certificate PDF generation failed: ' . $e->getMessage(), ['exception' => $e]);
|
||||
Log::error('Certificate generation failed', ['exception' => $e]);
|
||||
|
||||
return $this->error('Failed to generate certificates.', 500);
|
||||
}
|
||||
|
||||
$filename = 'Certificates_' . date('Ymd_His') . '.pdf';
|
||||
$filename = 'Certificates_'.date('Ymd_His').'.pdf';
|
||||
|
||||
return response($pdfContent, 200, [
|
||||
'Content-Type' => 'application/pdf',
|
||||
'Content-Disposition' => 'inline; filename="' . $filename . '"',
|
||||
'Content-Type' => 'application/pdf',
|
||||
'Content-Disposition' => 'inline; filename="'.$filename.'"',
|
||||
]);
|
||||
}
|
||||
|
||||
private function currentSchoolYear(): string
|
||||
public function reprint(string $certificateNumber): Response|JsonResponse
|
||||
{
|
||||
return trim((string) (Configuration::getConfig('school_year') ?? ''));
|
||||
try {
|
||||
$payload = $this->service->reprintPayload($certificateNumber);
|
||||
if ($payload === null) {
|
||||
return $this->error('Certificate not found: '.$certificateNumber, 404);
|
||||
}
|
||||
|
||||
$pdfContent = $this->pdfService->generate(
|
||||
[$payload['student']],
|
||||
$payload['cert_date_display']
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Certificate reprint failed', [
|
||||
'certificate_number' => $certificateNumber,
|
||||
'exception' => $e,
|
||||
]);
|
||||
|
||||
return $this->error('Failed to reprint certificate.', 500);
|
||||
}
|
||||
|
||||
$filename = 'Certificate_'.strtoupper($certificateNumber).'.pdf';
|
||||
|
||||
return response($pdfContent, 200, [
|
||||
'Content-Type' => 'application/pdf',
|
||||
'Content-Disposition' => 'inline; filename="'.$filename.'"',
|
||||
]);
|
||||
}
|
||||
|
||||
public function verify(string $token): JsonResponse
|
||||
{
|
||||
try {
|
||||
$payload = $this->service->verifyPayload($token);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Certificate verify failed', ['token' => $token, 'exception' => $e]);
|
||||
|
||||
return $this->error('Failed to verify certificate.', 500);
|
||||
}
|
||||
|
||||
if ($payload === null) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Certificate not found.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => $payload,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user