add more controller

This commit is contained in:
root
2026-03-10 00:48:32 -04:00
parent 5eeaec0257
commit 20ee70d153
151 changed files with 9481 additions and 8407 deletions
@@ -0,0 +1,47 @@
<?php
namespace App\Http\Controllers\Api\Administrator;
use App\Http\Controllers\Controller;
use App\Http\Requests\EmergencyContacts\EmergencyContactUpdateRequest;
use App\Http\Resources\EmergencyContacts\EmergencyContactGroupResource;
use App\Http\Resources\EmergencyContacts\EmergencyContactResource;
use App\Services\EmergencyContacts\EmergencyContactCrudService;
use App\Services\EmergencyContacts\EmergencyContactDirectoryService;
use Illuminate\Http\JsonResponse;
class EmergencyContactController extends Controller
{
public function __construct(
private EmergencyContactDirectoryService $directoryService,
private EmergencyContactCrudService $crudService
) {
}
public function index(): JsonResponse
{
$groups = $this->directoryService->groups();
return response()->json([
'ok' => true,
'groups' => EmergencyContactGroupResource::collection($groups),
]);
}
public function update(EmergencyContactUpdateRequest $request, int $contactId): JsonResponse
{
$contact = $this->crudService->update($contactId, $request->validated());
return response()->json([
'ok' => true,
'contact' => new EmergencyContactResource($contact),
]);
}
public function destroy(int $contactId): JsonResponse
{
$this->crudService->delete($contactId);
return response()->json(['ok' => true]);
}
}
@@ -0,0 +1,58 @@
<?php
namespace App\Http\Controllers\Api\Administrator;
use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Teachers\TeacherAssignmentDeleteRequest;
use App\Http\Requests\Teachers\TeacherAssignmentListRequest;
use App\Http\Requests\Teachers\TeacherAssignmentStoreRequest;
use App\Http\Resources\Teachers\TeacherAssignmentResource;
use App\Http\Resources\Teachers\TeacherClassResource;
use App\Services\Teachers\TeacherAssignmentService;
use Illuminate\Http\JsonResponse;
class TeacherClassAssignmentController extends BaseApiController
{
public function __construct(private TeacherAssignmentService $assignmentService)
{
parent::__construct();
}
public function index(TeacherAssignmentListRequest $request): JsonResponse
{
$data = $this->assignmentService->listAssignments($request->validated()['school_year'] ?? null);
return response()->json([
'ok' => true,
'school_year' => $data['school_year'],
'teachers' => TeacherAssignmentResource::collection($data['teachers']),
'classes' => TeacherClassResource::collection($data['classes']),
]);
}
public function store(TeacherAssignmentStoreRequest $request): JsonResponse
{
$payload = $request->validated();
$payload['updated_by'] = (int) (auth()->id() ?? 0);
$result = $this->assignmentService->assign($payload);
$status = $result['ok'] ? 200 : 422;
return response()->json([
'ok' => (bool) $result['ok'],
'message' => $result['message'] ?? '',
'position' => $result['position'] ?? null,
], $status);
}
public function destroy(TeacherAssignmentDeleteRequest $request): JsonResponse
{
$result = $this->assignmentService->delete($request->validated());
$status = $result['ok'] ? 200 : 422;
return response()->json([
'ok' => (bool) $result['ok'],
'message' => $result['message'] ?? '',
], $status);
}
}
@@ -0,0 +1,115 @@
<?php
namespace App\Http\Controllers\Api\Exams;
use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Exams\ExamDraftAdminLegacyRequest;
use App\Http\Requests\Exams\ExamDraftAdminReviewRequest;
use App\Http\Requests\Exams\ExamDraftTeacherStoreRequest;
use App\Http\Resources\Exams\ExamDraftResource;
use App\Services\Exams\ExamDraftAdminService;
use App\Services\Exams\ExamDraftTeacherService;
use Illuminate\Http\JsonResponse;
class ExamDraftController extends BaseApiController
{
public function __construct(
private ExamDraftTeacherService $teacherService,
private ExamDraftAdminService $adminService
) {
parent::__construct();
}
public function teacherIndex(): JsonResponse
{
$teacherId = (int) (auth()->id() ?? 0);
if ($teacherId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$data = $this->teacherService->listForTeacher($teacherId);
return response()->json([
'ok' => true,
'assignments' => $data['assignments'],
'drafts' => ExamDraftResource::collection($data['drafts']),
'legacy_exams' => ExamDraftResource::collection($data['legacyExams']),
'exam_types' => $data['examTypes'],
'status_options' => $data['statusOptions'],
'school_year' => $data['schoolYear'],
'semester' => $data['semester'],
]);
}
public function teacherStore(ExamDraftTeacherStoreRequest $request): JsonResponse
{
$teacherId = (int) (auth()->id() ?? 0);
if ($teacherId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$result = $this->teacherService->store($teacherId, $request->validated(), $request->file('draft_file'));
if (!$result['ok']) {
return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Unable to save.'], 422);
}
return response()->json([
'ok' => true,
'draft' => new ExamDraftResource($result['draft']),
], 201);
}
public function adminIndex(): JsonResponse
{
$data = $this->adminService->list();
return response()->json([
'ok' => true,
'drafts' => ExamDraftResource::collection($data['drafts']),
'class_sections' => $data['classSections'],
'legacy_by_class' => $data['legacyByClass'],
'exam_types' => $data['examTypes'],
'status_options' => $data['statusOptions'],
'school_year' => $data['schoolYear'],
'semester' => $data['semester'],
'allowed_extensions' => $data['allowedExtensions'],
'max_upload_bytes' => $data['maxUploadBytes'],
]);
}
public function adminUploadLegacy(ExamDraftAdminLegacyRequest $request): JsonResponse
{
$adminId = (int) (auth()->id() ?? 0);
if ($adminId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$result = $this->adminService->uploadLegacy($adminId, $request->validated(), $request->file('old_exam_file'));
if (!$result['ok']) {
return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Unable to save.'], 422);
}
return response()->json([
'ok' => true,
'draft' => new ExamDraftResource($result['draft']),
], 201);
}
public function adminReview(ExamDraftAdminReviewRequest $request): JsonResponse
{
$adminId = (int) (auth()->id() ?? 0);
if ($adminId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$result = $this->adminService->review($adminId, $request->validated(), $request->file('final_file'));
if (!$result['ok']) {
return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Unable to save.'], 422);
}
return response()->json([
'ok' => true,
'draft' => new ExamDraftResource($result['draft']),
]);
}
}
@@ -0,0 +1,108 @@
<?php
namespace App\Http\Controllers\Api\Parents;
use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Parents\ParentAttendanceReportSubmitRequest;
use App\Http\Requests\Parents\ParentAttendanceReportListRequest;
use App\Http\Requests\Parents\ParentAttendanceReportCheckRequest;
use App\Http\Requests\Parents\ParentAttendanceReportUpdateRequest;
use App\Http\Resources\Parents\ParentAttendanceReportResource;
use App\Services\Parents\ParentAttendanceReportService;
use Illuminate\Http\JsonResponse;
class ParentAttendanceReportController extends BaseApiController
{
public function __construct(private ParentAttendanceReportService $reportService)
{
parent::__construct();
}
public function form(): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$data = $this->reportService->formData($parentId);
return response()->json([
'ok' => true,
'students' => $data['students'],
'today' => $data['today'],
'sundays' => $data['sundays'],
'defaultDate' => $data['defaultDate'],
'myReports' => ParentAttendanceReportResource::collection($data['myReports']),
'cutoffThreshold' => $data['cutoffThreshold'],
]);
}
public function submit(ParentAttendanceReportSubmitRequest $request): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
try {
$result = $this->reportService->submit($parentId, $request->validated());
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
}
return response()->json([
'ok' => true,
'inserted' => $result['inserted'],
'blocked' => $result['blocked'],
'students' => $result['students'],
'dates' => $result['dates'],
], 201);
}
public function list(ParentAttendanceReportListRequest $request): JsonResponse
{
$payload = $request->validated();
$start = $payload['start'] ?? now()->toDateString();
$end = $payload['end'] ?? null;
$schoolYear = $payload['school_year'] ?? null;
$semester = $payload['semester'] ?? null;
$rows = $this->reportService->listReports($start, $end, $schoolYear, $semester);
return response()->json([
'ok' => true,
'reports' => ParentAttendanceReportResource::collection($rows),
]);
}
public function checkExisting(ParentAttendanceReportCheckRequest $request): JsonResponse
{
try {
$rows = $this->reportService->checkExisting($request->validated());
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
}
return response()->json([
'ok' => true,
'students' => $rows,
]);
}
public function update(ParentAttendanceReportUpdateRequest $request, int $reportId): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
try {
$this->reportService->updateReport($parentId, $reportId, $request->validated());
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
}
return response()->json(['ok' => true]);
}
}
@@ -0,0 +1,284 @@
<?php
namespace App\Http\Controllers\Api\Parents;
use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Parents\ParentAttendanceRequest;
use App\Http\Requests\Parents\ParentEnrollmentActionRequest;
use App\Http\Requests\Parents\ParentEnrollmentRequest;
use App\Http\Requests\Parents\ParentEmergencyContactRequest;
use App\Http\Requests\Parents\ParentEventParticipationRequest;
use App\Http\Requests\Parents\ParentInvoiceRequest;
use App\Http\Requests\Parents\ParentProfileUpdateRequest;
use App\Http\Requests\Parents\ParentRegistrationRequest;
use App\Http\Requests\Parents\ParentStudentUpdateRequest;
use App\Http\Resources\Parents\ParentAttendanceResource;
use App\Http\Resources\Parents\ParentEmergencyContactResource;
use App\Http\Resources\Parents\ParentStudentResource;
use App\Http\Resources\Invoices\InvoiceResource;
use App\Services\Parents\ParentAttendanceService;
use App\Services\Parents\ParentEmergencyContactService;
use App\Services\Parents\ParentEnrollmentService;
use App\Services\Parents\ParentEventParticipationService;
use App\Services\Parents\ParentInvoiceService;
use App\Services\Parents\ParentProfileService;
use App\Services\Parents\ParentRegistrationService;
use Illuminate\Http\JsonResponse;
class ParentController extends BaseApiController
{
public function __construct(
private ParentAttendanceService $attendanceService,
private ParentInvoiceService $invoiceService,
private ParentEnrollmentService $enrollmentService,
private ParentRegistrationService $registrationService,
private ParentEmergencyContactService $emergencyContactService,
private ParentProfileService $profileService,
private ParentEventParticipationService $eventService
) {
parent::__construct();
}
public function attendance(ParentAttendanceRequest $request): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$data = $this->attendanceService->listAttendance($parentId, $request->validated()['school_year'] ?? null);
return response()->json([
'ok' => true,
'attendance' => ParentAttendanceResource::collection($data['attendance']),
'schoolYears' => $data['schoolYears'],
'selectedYear' => $data['selectedYear'],
]);
}
public function invoices(ParentInvoiceRequest $request): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$schoolYear = $request->validated()['school_year'] ?? null;
$rows = $this->invoiceService->listInvoices($parentId, $schoolYear);
return response()->json([
'ok' => true,
'invoices' => InvoiceResource::collection($rows),
]);
}
public function enrollments(ParentEnrollmentRequest $request): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$data = $this->enrollmentService->overview($parentId, $request->validated()['school_year'] ?? null);
return response()->json([
'ok' => true,
'students' => ParentStudentResource::collection($data['students']),
'schoolYears' => $data['schoolYears'],
'selectedYear' => $data['selectedYear'],
'withdrawalDeadline' => $data['withdrawalDeadline'],
'lastDayOfRegistration' => $data['lastDayOfRegistration'],
'schoolStartDate' => $data['schoolStartDate'],
]);
}
public function updateEnrollments(ParentEnrollmentActionRequest $request): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$payload = $request->validated();
$result = $this->enrollmentService->updateEnrollment(
$parentId,
$payload['enroll'] ?? [],
$payload['withdraw'] ?? []
);
return response()->json([
'ok' => true,
'enrolled' => $result['enrolled'],
'withdrawn' => $result['withdrawn'],
]);
}
public function registration(): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$data = $this->registrationService->overview($parentId);
return response()->json([
'ok' => true,
'parent' => $data['parent'],
'existingKids' => ParentStudentResource::collection($data['existingKids']),
'emergencies' => ParentEmergencyContactResource::collection($data['emergencies']),
'maxChilds' => $data['maxChilds'],
'maxEmergency' => $data['maxEmergency'],
'lastDayOfRegistration' => $data['lastDayOfRegistration'],
'registrationAgeDeadline' => $data['registrationAgeDeadline'],
]);
}
public function storeRegistration(ParentRegistrationRequest $request): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$payload = $request->validated();
$result = $this->registrationService->register(
$parentId,
$payload['students'] ?? [],
$payload['emergency_contacts'] ?? []
);
return response()->json([
'ok' => true,
'created_student_ids' => $result['created_student_ids'],
], 201);
}
public function updateStudent(ParentStudentUpdateRequest $request, int $studentId): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$this->registrationService->updateStudent($parentId, $studentId, $request->validated());
return response()->json(['ok' => true]);
}
public function deleteStudent(int $studentId): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$this->registrationService->deleteStudent($parentId, $studentId);
return response()->json(['ok' => true]);
}
public function emergencyContacts(): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$rows = $this->emergencyContactService->list($parentId);
return response()->json([
'ok' => true,
'contacts' => ParentEmergencyContactResource::collection($rows),
]);
}
public function storeEmergencyContact(ParentEmergencyContactRequest $request): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$contact = $this->emergencyContactService->store($parentId, $request->validated());
return response()->json([
'ok' => true,
'contact' => new ParentEmergencyContactResource($contact),
], 201);
}
public function updateEmergencyContact(ParentEmergencyContactRequest $request, int $contactId): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$contact = $this->emergencyContactService->update($parentId, $contactId, $request->validated());
return response()->json([
'ok' => true,
'contact' => new ParentEmergencyContactResource($contact),
]);
}
public function profile(): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$profile = $this->profileService->getProfile($parentId);
return response()->json([
'ok' => true,
'profile' => $profile,
]);
}
public function updateProfile(ParentProfileUpdateRequest $request): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$profile = $this->profileService->updateProfile($parentId, $request->validated());
return response()->json([
'ok' => true,
'profile' => $profile,
]);
}
public function events(): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$data = $this->eventService->overview($parentId);
return response()->json([
'ok' => true,
'activeEvents' => $data['activeEvents'],
'charges' => $data['charges'],
'yourStudents' => $data['yourStudents'],
]);
}
public function updateParticipation(ParentEventParticipationRequest $request): JsonResponse
{
$parentId = (int) (auth()->id() ?? 0);
if ($parentId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$this->eventService->updateParticipation($parentId, $request->validated()['participation'] ?? []);
return response()->json(['ok' => true]);
}
}
@@ -0,0 +1,73 @@
<?php
namespace App\Http\Controllers\Api\Reports;
use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Reports\SlipLogListRequest;
use App\Http\Requests\Reports\SlipPreviewRequest;
use App\Http\Requests\Reports\SlipPrintRequest;
use App\Http\Requests\Reports\SlipReprintRequest;
use App\Http\Resources\Reports\LateSlipLogResource;
use App\Services\Reports\SlipPrinterService;
use Illuminate\Http\JsonResponse;
class SlipPrinterController extends BaseApiController
{
public function __construct(private SlipPrinterService $service)
{
parent::__construct();
}
public function print(SlipPrintRequest $request)
{
$userId = (int) (auth()->id() ?? 0);
$result = $this->service->print($request->validated(), $userId);
if (!$result['ok']) {
return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Print failed.'], 422);
}
return response($result['pdf'], 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="' . $result['filename'] . '"',
]);
}
public function preview(SlipPreviewRequest $request): JsonResponse
{
$userId = (int) (auth()->id() ?? 0);
$result = $this->service->preview($request->validated(), $userId);
return response()->json([
'ok' => true,
'text' => $result['text'],
'width' => $result['width'],
]);
}
public function logs(SlipLogListRequest $request): JsonResponse
{
$payload = $request->validated();
$rows = $this->service->logs($payload['school_year'] ?? null, $payload['semester'] ?? null);
return response()->json([
'ok' => true,
'logs' => LateSlipLogResource::collection($rows),
]);
}
public function reprint(SlipReprintRequest $request)
{
$userId = (int) (auth()->id() ?? 0);
$result = $this->service->reprint((int) $request->validated()['id'], $userId);
if (!$result['ok']) {
return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Slip not found.'], 404);
}
return response($result['pdf'], 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="' . $result['filename'] . '"',
]);
}
}
@@ -0,0 +1,61 @@
<?php
namespace App\Http\Controllers\Api\Settings;
use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Settings\ConfigurationStoreRequest;
use App\Http\Requests\Settings\ConfigurationUpdateRequest;
use App\Http\Resources\Settings\ConfigurationResource;
use App\Services\Settings\ConfigurationService;
use Illuminate\Http\JsonResponse;
class ConfigurationAdminController extends BaseApiController
{
public function __construct(private ConfigurationService $service)
{
parent::__construct();
}
public function index(): JsonResponse
{
$configs = $this->service->list();
return response()->json([
'ok' => true,
'configs' => ConfigurationResource::collection($configs),
]);
}
public function store(ConfigurationStoreRequest $request): JsonResponse
{
$config = $this->service->store($request->validated());
return response()->json([
'ok' => true,
'config' => new ConfigurationResource($config->toArray()),
], 201);
}
public function update(ConfigurationUpdateRequest $request, int $id): JsonResponse
{
$config = $this->service->update($id, $request->validated());
if (!$config) {
return response()->json(['ok' => false, 'message' => 'Configuration not found.'], 404);
}
return response()->json([
'ok' => true,
'config' => new ConfigurationResource($config->toArray()),
]);
}
public function destroy(int $id): JsonResponse
{
$deleted = $this->service->delete($id);
if (!$deleted) {
return response()->json(['ok' => false, 'message' => 'Configuration not found.'], 404);
}
return response()->json(['ok' => true]);
}
}
@@ -0,0 +1,143 @@
<?php
namespace App\Http\Controllers\Api\Staff;
use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Teachers\TeacherAbsenceSubmitRequest;
use App\Http\Requests\Teachers\TeacherClassViewRequest;
use App\Http\Requests\Teachers\TeacherSwitchClassRequest;
use App\Http\Resources\Teachers\TeacherAbsenceResource;
use App\Http\Resources\Teachers\TeacherClassResource;
use App\Http\Resources\Teachers\TeacherStudentResource;
use App\Models\User;
use App\Services\Teachers\TeacherAbsenceService;
use App\Services\Teachers\TeacherDashboardService;
use Illuminate\Http\JsonResponse;
class TeacherController extends BaseApiController
{
public function __construct(
private TeacherDashboardService $dashboardService,
private TeacherAbsenceService $absenceService
) {
parent::__construct();
}
public function classes(TeacherClassViewRequest $request): JsonResponse
{
$userId = (int) (auth()->id() ?? 0);
if ($userId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
try {
$data = $this->dashboardService->classView(
$userId,
$request->validated()['class_section_id'] ?? null
);
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 403);
}
$teacher = $this->teacherPayload($data['teacher'] ?? null, $userId);
$studentsBySection = [];
foreach (($data['studentsBySection'] ?? []) as $sectionId => $students) {
$studentsBySection[(string) $sectionId] = TeacherStudentResource::collection($students);
}
return response()->json([
'ok' => true,
'teacher' => $teacher,
'classes' => TeacherClassResource::collection($data['classes'] ?? []),
'students' => TeacherStudentResource::collection($data['students'] ?? []),
'students_by_section' => $studentsBySection,
'assigned_names' => $data['assignedNames'] ?? [],
'active_class_section_id' => $data['active_class_section_id'] ?? null,
]);
}
public function switchClass(TeacherSwitchClassRequest $request): JsonResponse
{
$userId = (int) (auth()->id() ?? 0);
if ($userId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$requested = (int) $request->validated()['class_section_id'];
try {
$data = $this->dashboardService->classView($userId, $requested);
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 403);
}
if (($data['active_class_section_id'] ?? null) !== $requested) {
return response()->json([
'ok' => false,
'message' => 'You are not assigned to that class.',
], 422);
}
return response()->json([
'ok' => true,
'active_class_section_id' => $requested,
]);
}
public function absenceForm(): JsonResponse
{
$userId = (int) (auth()->id() ?? 0);
if ($userId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$data = $this->absenceService->formData($userId);
return response()->json([
'ok' => true,
'teacher_name' => $data['teacher_name'],
'semester' => $data['semester'],
'school_year' => $data['school_year'],
'existing' => TeacherAbsenceResource::collection($data['existing'] ?? []),
'available_dates' => $data['available_dates'] ?? [],
]);
}
public function submitAbsence(TeacherAbsenceSubmitRequest $request): JsonResponse
{
$userId = (int) (auth()->id() ?? 0);
if ($userId <= 0) {
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
}
$result = $this->absenceService->submit($userId, $request->validated());
return response()->json([
'ok' => (bool) ($result['ok'] ?? false),
'message' => $result['message'] ?? '',
'saved' => $result['saved'] ?? 0,
'dates' => $result['dates'] ?? [],
], (int) ($result['status'] ?? 200));
}
private function teacherPayload(?array $teacher, int $userId): ?array
{
if (!$teacher) {
$model = User::query()->find($userId);
$teacher = $model?->toArray();
}
if (!$teacher) {
return null;
}
return [
'id' => (int) ($teacher['id'] ?? 0),
'firstname' => (string) ($teacher['firstname'] ?? ''),
'lastname' => (string) ($teacher['lastname'] ?? ''),
'email' => $teacher['email'] ?? null,
'role' => User::getUserRoleName($userId),
];
}
}
@@ -0,0 +1,156 @@
<?php
namespace App\Http\Controllers\Api\Students;
use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Students\StudentAssignClassRequest;
use App\Http\Requests\Students\StudentAssignmentListRequest;
use App\Http\Requests\Students\StudentAutoDistributeRequest;
use App\Http\Requests\Students\StudentPromotionTotalsRequest;
use App\Http\Requests\Students\StudentRemoveClassRequest;
use App\Http\Requests\Students\StudentSetActiveRequest;
use App\Http\Requests\Students\StudentUpdateRequest;
use App\Http\Resources\Students\StudentAssignmentResource;
use App\Http\Resources\Students\StudentClassSectionResource;
use App\Http\Resources\Students\StudentRemovedResource;
use App\Http\Resources\Students\StudentScoreCardRowResource;
use App\Services\Students\StudentAssignmentService;
use App\Services\Students\StudentAutoDistributionService;
use App\Services\Students\StudentDirectoryService;
use App\Services\Students\StudentProfileService;
use App\Services\Students\StudentScoreCardService;
use App\Services\Students\StudentStatusService;
use Illuminate\Http\JsonResponse;
class StudentController extends BaseApiController
{
public function __construct(
private StudentAssignmentService $assignmentService,
private StudentDirectoryService $directoryService,
private StudentStatusService $statusService,
private StudentAutoDistributionService $autoDistributionService,
private StudentProfileService $profileService,
private StudentScoreCardService $scoreCardService
) {
parent::__construct();
}
public function assignments(StudentAssignmentListRequest $request): JsonResponse
{
$data = $this->directoryService->assignmentData($request->validated()['school_year'] ?? null);
return response()->json([
'ok' => true,
'students' => StudentAssignmentResource::collection($data['students']),
'classes' => StudentClassSectionResource::collection($data['classes']),
'schoolYears' => $data['schoolYears'],
'selectedYear' => $data['selectedYear'],
'currentYear' => $data['currentYear'],
'isCurrentYear' => $data['isCurrentYear'],
]);
}
public function assignClass(StudentAssignClassRequest $request): JsonResponse
{
$payload = $request->validated();
$result = $this->assignmentService->assignClasses(
(int) $payload['student_id'],
$payload['class_section_id'],
(bool) ($payload['is_event_only'] ?? false),
(int) (auth()->id() ?? 0)
);
$status = $result['ok'] ? 200 : 422;
return response()->json($result + ['ok' => (bool) $result['ok']], $status);
}
public function removeClass(StudentRemoveClassRequest $request): JsonResponse
{
$payload = $request->validated();
$result = $this->assignmentService->removeClass(
(int) $payload['student_id'],
(int) $payload['class_section_id'],
(int) (auth()->id() ?? 0)
);
$status = $result['ok'] ? 200 : 422;
return response()->json($result + ['ok' => (bool) $result['ok']], $status);
}
public function removed(StudentAssignmentListRequest $request): JsonResponse
{
$data = $this->directoryService->removedStudents($request->validated()['school_year'] ?? null);
return response()->json([
'ok' => true,
'active_students' => StudentRemovedResource::collection($data['active_students']),
'removed_students' => StudentRemovedResource::collection($data['removed_students']),
'school_year' => $data['school_year'],
]);
}
public function setActive(StudentSetActiveRequest $request): JsonResponse
{
$payload = $request->validated();
$result = $this->statusService->setActive(
(int) $payload['student_id'],
(bool) $payload['is_active'],
(int) (auth()->id() ?? 0)
);
$status = $result['ok'] ? 200 : 422;
return response()->json($result + ['ok' => (bool) $result['ok']], $status);
}
public function autoDistribute(StudentAutoDistributeRequest $request): JsonResponse
{
$payload = $request->validated();
$result = $this->autoDistributionService->autoDistribute(
(int) ($payload['class_id'] ?? 0),
(int) $payload['students_per_section'],
$payload['school_year'] ?? null,
(int) ($payload['class_section_id'] ?? 0),
(int) (auth()->id() ?? 0)
);
$status = $result['ok'] ? 200 : 422;
return response()->json($result + ['ok' => (bool) $result['ok']], $status);
}
public function promotionTotals(StudentPromotionTotalsRequest $request): JsonResponse
{
$data = $this->autoDistributionService->promotionTotals($request->validated()['school_year'] ?? null);
return response()->json([
'ok' => true,
'year' => $data['year'],
'rows' => $data['rows'],
]);
}
public function update(StudentUpdateRequest $request, int $studentId): JsonResponse
{
$result = $this->profileService->updateStudent($studentId, $request->validated());
$status = $result['ok'] ? 200 : 422;
return response()->json($result + ['ok' => (bool) $result['ok']], $status);
}
public function scoreCard(int $studentId): JsonResponse
{
$result = $this->scoreCardService->scoreCard($studentId);
if (!$result['ok']) {
return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Not found.'], 404);
}
return response()->json([
'ok' => true,
'student' => $result['student'],
'rows' => StudentScoreCardRowResource::collection($result['rows']),
]);
}
}
@@ -0,0 +1,78 @@
<?php
namespace App\Http\Controllers\Api\Subjects;
use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\Subjects\SubjectCurriculumStoreRequest;
use App\Http\Requests\Subjects\SubjectCurriculumUpdateRequest;
use App\Http\Resources\Subjects\SubjectClassResource;
use App\Http\Resources\Subjects\SubjectCurriculumResource;
use App\Models\SubjectCurriculum;
use App\Services\Subjects\SubjectCurriculumService;
use Illuminate\Http\JsonResponse;
class SubjectCurriculumController extends BaseApiController
{
public function __construct(private SubjectCurriculumService $service)
{
parent::__construct();
}
public function index(): JsonResponse
{
$data = $this->service->list();
return response()->json([
'ok' => true,
'classes' => SubjectClassResource::collection($data['classes']),
'entries' => SubjectCurriculumResource::collection($data['entries']),
'subject_labels' => $data['subject_labels'],
]);
}
public function show(int $id): JsonResponse
{
$entry = SubjectCurriculum::query()->find($id);
if (!$entry) {
return response()->json(['ok' => false, 'message' => 'Curriculum entry not found.'], 404);
}
return response()->json([
'ok' => true,
'entry' => new SubjectCurriculumResource($entry->toArray()),
]);
}
public function store(SubjectCurriculumStoreRequest $request): JsonResponse
{
$entry = $this->service->store($request->validated());
return response()->json([
'ok' => true,
'entry' => new SubjectCurriculumResource($entry->toArray()),
], 201);
}
public function update(SubjectCurriculumUpdateRequest $request, int $id): JsonResponse
{
$entry = $this->service->update($id, $request->validated());
if (!$entry) {
return response()->json(['ok' => false, 'message' => 'Curriculum entry not found.'], 404);
}
return response()->json([
'ok' => true,
'entry' => new SubjectCurriculumResource($entry->toArray()),
]);
}
public function destroy(int $id): JsonResponse
{
$deleted = $this->service->delete($id);
if (!$deleted) {
return response()->json(['ok' => false, 'message' => 'Curriculum entry not found.'], 404);
}
return response()->json(['ok' => true]);
}
}
@@ -0,0 +1,64 @@
<?php
namespace App\Http\Controllers\Api\System;
use App\Http\Controllers\Api\BaseApiController;
use App\Http\Requests\SchoolIds\SchoolIdAssignRequest;
use App\Http\Resources\SchoolIds\SchoolIdResource;
use App\Services\SchoolIds\SchoolIdAssignmentService;
use App\Services\SchoolIds\SchoolIdGenerationService;
use Illuminate\Http\JsonResponse;
class SchoolIdController extends BaseApiController
{
public function __construct(
private SchoolIdAssignmentService $assignmentService,
private SchoolIdGenerationService $generationService
) {
parent::__construct();
}
public function assign(SchoolIdAssignRequest $request): JsonResponse
{
$payload = $request->validated();
$schoolId = $this->assignmentService->assignToUser((int) $payload['user_id']);
if ($schoolId === null) {
return response()->json(['ok' => false, 'message' => 'User not found.'], 404);
}
return response()->json([
'ok' => true,
'result' => new SchoolIdResource([
'type' => 'user',
'school_id' => $schoolId,
]),
]);
}
public function generateStudent(): JsonResponse
{
$schoolId = $this->generationService->generateStudentId();
return response()->json([
'ok' => true,
'result' => new SchoolIdResource([
'type' => 'student',
'school_id' => $schoolId,
]),
]);
}
public function generateUser(): JsonResponse
{
$schoolId = $this->generationService->generateUserId();
return response()->json([
'ok' => true,
'result' => new SchoolIdResource([
'type' => 'user',
'school_id' => $schoolId,
]),
]);
}
}