fix logic and tests, update docker CI file
This commit is contained in:
@@ -3,10 +3,11 @@
|
|||||||
namespace App\Http\Controllers\Api\Administrator;
|
namespace App\Http\Controllers\Api\Administrator;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Administrator\SubmitAdministratorAbsenceRequest;
|
|
||||||
use App\Services\Administrator\AdministratorAbsenceService;
|
use App\Services\Administrator\AdministratorAbsenceService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class AdministratorAbsenceController extends Controller
|
class AdministratorAbsenceController extends Controller
|
||||||
{
|
{
|
||||||
@@ -25,13 +26,42 @@ class AdministratorAbsenceController extends Controller
|
|||||||
return response()->json($this->service->getAbsenceFormData($userId));
|
return response()->json($this->service->getAbsenceFormData($userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(SubmitAdministratorAbsenceRequest $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$userId = (int) Auth::id();
|
$userId = (int) Auth::id();
|
||||||
if ($userId <= 0) {
|
if ($userId <= 0) {
|
||||||
return response()->json(['message' => 'Please log in first.'], 401);
|
return response()->json(['message' => 'Please log in first.'], 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$payload = $request->all();
|
||||||
|
if (!array_key_exists('dates', $payload) || !array_key_exists('reason', $payload)) {
|
||||||
|
$json = json_decode($request->getContent() ?: '', true);
|
||||||
|
if (is_array($json)) {
|
||||||
|
$payload = array_merge($payload, $json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$validator = Validator::make($payload, [
|
||||||
|
'dates' => ['required', 'array', 'min:1'],
|
||||||
|
'dates.*' => ['required', 'date_format:Y-m-d'],
|
||||||
|
'reason_type' => ['nullable', 'string', 'max:100'],
|
||||||
|
'reason' => ['required', 'string', 'max:2000'],
|
||||||
|
], [
|
||||||
|
'dates.required' => 'At least one date is required.',
|
||||||
|
'dates.array' => 'Dates must be submitted as an array.',
|
||||||
|
'dates.min' => 'At least one date is required.',
|
||||||
|
'dates.*.date_format' => 'Each date must be in Y-m-d format.',
|
||||||
|
'reason.required' => 'Reason is required.',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$request->merge($validator->validated());
|
||||||
$result = $this->service->submit($request, $userId);
|
$result = $this->service->submit($request, $userId);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
namespace App\Http\Controllers\Api\Administrator;
|
namespace App\Http\Controllers\Api\Administrator;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Administrator\UpdateEnrollmentStatusesRequest;
|
|
||||||
use App\Services\Administrator\AdministratorEnrollmentService;
|
use App\Services\Administrator\AdministratorEnrollmentService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
class AdministratorEnrollmentController extends Controller
|
class AdministratorEnrollmentController extends Controller
|
||||||
{
|
{
|
||||||
@@ -30,14 +31,53 @@ class AdministratorEnrollmentController extends Controller
|
|||||||
return response()->json($this->service->showNewStudentsData());
|
return response()->json($this->service->showNewStudentsData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateStatuses(UpdateEnrollmentStatusesRequest $request): JsonResponse
|
public function updateStatuses(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$editorUserId = (int) Auth::id();
|
$editorUserId = (int) Auth::id();
|
||||||
if ($editorUserId <= 0) {
|
if ($editorUserId <= 0) {
|
||||||
return response()->json(['message' => 'Please log in first.'], 401);
|
return response()->json(['message' => 'Please log in first.'], 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $request->validated();
|
$payload = $request->all();
|
||||||
|
if (!array_key_exists('enrollment_status', $payload)) {
|
||||||
|
$json = json_decode($request->getContent() ?: '', true);
|
||||||
|
if (is_array($json) && array_key_exists('enrollment_status', $json)) {
|
||||||
|
$payload['enrollment_status'] = $json['enrollment_status'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!array_key_exists('enrollment_status', $payload)) {
|
||||||
|
$payload['enrollment_status'] = $request->query('enrollment_status');
|
||||||
|
}
|
||||||
|
|
||||||
|
$allowedStatuses = [
|
||||||
|
'admission under review',
|
||||||
|
'payment pending',
|
||||||
|
'enrolled',
|
||||||
|
'withdraw under review',
|
||||||
|
'refund pending',
|
||||||
|
'withdrawn',
|
||||||
|
'denied',
|
||||||
|
'waitlist',
|
||||||
|
];
|
||||||
|
|
||||||
|
$validator = Validator::make($payload, [
|
||||||
|
'enrollment_status' => ['required', 'array', 'min:1'],
|
||||||
|
'enrollment_status.*' => ['required', 'string', Rule::in($allowedStatuses)],
|
||||||
|
], [
|
||||||
|
'enrollment_status.required' => 'Enrollment statuses are required.',
|
||||||
|
'enrollment_status.array' => 'Enrollment statuses must be an array.',
|
||||||
|
'enrollment_status.min' => 'At least one enrollment status is required.',
|
||||||
|
'enrollment_status.*.in' => 'One or more enrollment statuses are invalid.',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $validator->validated();
|
||||||
$result = $this->service->updateStatuses(
|
$result = $this->service->updateStatuses(
|
||||||
(array) ($data['enrollment_status'] ?? []),
|
(array) ($data['enrollment_status'] ?? []),
|
||||||
$editorUserId
|
$editorUserId
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
namespace App\Http\Controllers\Api\Administrator;
|
namespace App\Http\Controllers\Api\Administrator;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Administrator\SaveAdminNotificationSubjectsRequest;
|
|
||||||
use App\Http\Requests\Administrator\SavePrintRecipientsRequest;
|
|
||||||
use App\Services\Administrator\AdministratorNotificationService;
|
use App\Services\Administrator\AdministratorNotificationService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class AdministratorNotificationController extends Controller
|
class AdministratorNotificationController extends Controller
|
||||||
{
|
{
|
||||||
@@ -20,9 +20,31 @@ class AdministratorNotificationController extends Controller
|
|||||||
return response()->json($this->service->notificationsAlertsData());
|
return response()->json($this->service->notificationsAlertsData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveAlerts(SaveAdminNotificationSubjectsRequest $request): JsonResponse
|
public function saveAlerts(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->validated();
|
$payload = $request->all();
|
||||||
|
if (!array_key_exists('subjects', $payload)) {
|
||||||
|
$json = json_decode($request->getContent() ?: '', true);
|
||||||
|
if (is_array($json)) {
|
||||||
|
$payload = array_merge($payload, $json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$validator = Validator::make($payload, [
|
||||||
|
'subjects' => ['required', 'array'],
|
||||||
|
], [
|
||||||
|
'subjects.required' => 'Subjects payload is required.',
|
||||||
|
'subjects.array' => 'Subjects payload must be an array.',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $validator->validated();
|
||||||
$result = $this->service->saveNotificationSubjects(
|
$result = $this->service->saveNotificationSubjects(
|
||||||
(array) ($data['subjects'] ?? [])
|
(array) ($data['subjects'] ?? [])
|
||||||
);
|
);
|
||||||
@@ -35,9 +57,31 @@ class AdministratorNotificationController extends Controller
|
|||||||
return response()->json($this->service->printNotificationRecipientsData());
|
return response()->json($this->service->printNotificationRecipientsData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function savePrintRecipients(SavePrintRecipientsRequest $request): JsonResponse
|
public function savePrintRecipients(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->validated();
|
$payload = $request->all();
|
||||||
|
if (!array_key_exists('notify', $payload)) {
|
||||||
|
$json = json_decode($request->getContent() ?: '', true);
|
||||||
|
if (is_array($json)) {
|
||||||
|
$payload = array_merge($payload, $json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$validator = Validator::make($payload, [
|
||||||
|
'notify' => ['required', 'array'],
|
||||||
|
], [
|
||||||
|
'notify.required' => 'Notify payload is required.',
|
||||||
|
'notify.array' => 'Notify payload must be an array.',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $validator->validated();
|
||||||
$result = $this->service->savePrintNotificationRecipients(
|
$result = $this->service->savePrintNotificationRecipients(
|
||||||
(array) ($data['notify'] ?? [])
|
(array) ($data['notify'] ?? [])
|
||||||
);
|
);
|
||||||
|
|||||||
+20
-2
@@ -3,10 +3,11 @@
|
|||||||
namespace App\Http\Controllers\Api\Administrator;
|
namespace App\Http\Controllers\Api\Administrator;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Administrator\SendTeacherSubmissionNotificationsRequest;
|
|
||||||
use App\Services\Administrator\AdministratorTeacherSubmissionService;
|
use App\Services\Administrator\AdministratorTeacherSubmissionService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class AdministratorTeacherSubmissionController extends Controller
|
class AdministratorTeacherSubmissionController extends Controller
|
||||||
{
|
{
|
||||||
@@ -20,13 +21,30 @@ class AdministratorTeacherSubmissionController extends Controller
|
|||||||
return response()->json($this->service->report());
|
return response()->json($this->service->report());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function notify(SendTeacherSubmissionNotificationsRequest $request): JsonResponse
|
public function notify(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$adminId = (int) Auth::id();
|
$adminId = (int) Auth::id();
|
||||||
if ($adminId <= 0) {
|
if ($adminId <= 0) {
|
||||||
return response()->json(['message' => 'Please log in first.'], 401);
|
return response()->json(['message' => 'Please log in first.'], 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'notify' => ['required', 'array', 'min:1'],
|
||||||
|
'missing_items' => ['nullable', 'array'],
|
||||||
|
], [
|
||||||
|
'notify.required' => 'Select at least one teacher to notify.',
|
||||||
|
'notify.array' => 'Notify payload must be an array.',
|
||||||
|
'notify.min' => 'Select at least one teacher to notify.',
|
||||||
|
'missing_items.array' => 'Missing items payload must be an array.',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
$result = $this->service->sendNotifications($request, $adminId);
|
$result = $this->service->sendNotifications($request, $adminId);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
namespace App\Http\Controllers\Api\Assignment;
|
namespace App\Http\Controllers\Api\Assignment;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Assignment\StoreAssignmentRequest;
|
|
||||||
use App\Http\Resources\Assignment\AssignmentOverviewResource;
|
use App\Http\Resources\Assignment\AssignmentOverviewResource;
|
||||||
use App\Http\Resources\Assignment\AssignmentSectionResource;
|
use App\Http\Resources\Assignment\AssignmentSectionResource;
|
||||||
use App\Services\Assignment\AssignmentService;
|
use App\Services\Assignment\AssignmentService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class AssignmentApiController extends Controller
|
class AssignmentApiController extends Controller
|
||||||
{
|
{
|
||||||
@@ -29,10 +29,25 @@ class AssignmentApiController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(StoreAssignmentRequest $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'student_id' => ['required', 'integer', 'exists:students,id'],
|
||||||
|
'class_section_id' => ['required', 'integer', 'exists:classSection,class_section_id'],
|
||||||
|
'semester' => ['required', 'string', 'max:50'],
|
||||||
|
'school_year' => ['required', 'string', 'max:50'],
|
||||||
|
'description' => ['nullable', 'string'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
$assignment = $this->assignmentService->storeAssignment(
|
$assignment = $this->assignmentService->storeAssignment(
|
||||||
data: $request->validated(),
|
data: $validator->validated(),
|
||||||
updatedBy: $request->user()?->id
|
updatedBy: $request->user()?->id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,10 @@
|
|||||||
namespace App\Http\Controllers\Api\Attendance;
|
namespace App\Http\Controllers\Api\Attendance;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\AttendanceCommentTemplate\StoreAttendanceCommentTemplateRequest;
|
|
||||||
use App\Http\Requests\AttendanceCommentTemplate\UpdateAttendanceCommentTemplateRequest;
|
|
||||||
use App\Services\AttendanceCommentTemplateService;
|
use App\Services\AttendanceCommentTemplateService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class AttendanceCommentTemplateController extends Controller
|
class AttendanceCommentTemplateController extends Controller
|
||||||
{
|
{
|
||||||
@@ -49,9 +48,28 @@ class AttendanceCommentTemplateController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(StoreAttendanceCommentTemplateRequest $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$created = $this->service->create($request->validated());
|
$validator = Validator::make($request->all(), [
|
||||||
|
'min_score' => ['required', 'integer', 'min:0', 'max:100'],
|
||||||
|
'max_score' => ['required', 'integer', 'min:0', 'max:100', 'gte:min_score'],
|
||||||
|
'template_text' => ['required', 'string', 'max:5000'],
|
||||||
|
'is_active' => ['sometimes', 'boolean'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $validator->validated();
|
||||||
|
if (!array_key_exists('is_active', $data)) {
|
||||||
|
$data['is_active'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$created = $this->service->create($data);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => 'success',
|
'status' => 'success',
|
||||||
@@ -60,9 +78,31 @@ class AttendanceCommentTemplateController extends Controller
|
|||||||
], 201);
|
], 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(UpdateAttendanceCommentTemplateRequest $request, int $id): JsonResponse
|
public function update(Request $request, int $id): JsonResponse
|
||||||
{
|
{
|
||||||
$updated = $this->service->update($id, $request->validated());
|
$validator = Validator::make($request->all(), [
|
||||||
|
'min_score' => ['sometimes', 'integer', 'min:0', 'max:100'],
|
||||||
|
'max_score' => ['sometimes', 'integer', 'min:0', 'max:100'],
|
||||||
|
'template_text' => ['sometimes', 'string', 'max:5000'],
|
||||||
|
'is_active' => ['sometimes', 'boolean'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$validator->after(function ($validator) use ($request) {
|
||||||
|
$min = $request->has('min_score') ? (int) $request->input('min_score') : null;
|
||||||
|
$max = $request->has('max_score') ? (int) $request->input('max_score') : null;
|
||||||
|
if ($min !== null && $max !== null && $max < $min) {
|
||||||
|
$validator->errors()->add('max_score', 'The max_score field must be greater than or equal to min_score.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$updated = $this->service->update($id, $validator->validated());
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => 'success',
|
'status' => 'success',
|
||||||
|
|||||||
@@ -3,14 +3,10 @@
|
|||||||
namespace App\Http\Controllers\Api\AttendanceTracking;
|
namespace App\Http\Controllers\Api\AttendanceTracking;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\AttendanceTracking\ComposeAttendanceEmailRequest;
|
|
||||||
use App\Http\Requests\AttendanceTracking\ParentsInfoRequest;
|
|
||||||
use App\Http\Requests\AttendanceTracking\RecordAttendanceTrackingRequest;
|
|
||||||
use App\Http\Requests\AttendanceTracking\SaveAttendanceNotificationNoteRequest;
|
|
||||||
use App\Http\Requests\AttendanceTracking\SendAttendanceManualEmailRequest;
|
|
||||||
use App\Services\AttendanceTracking\AttendanceTrackingService;
|
use App\Services\AttendanceTracking\AttendanceTrackingService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class AttendanceTrackingController extends Controller
|
class AttendanceTrackingController extends Controller
|
||||||
{
|
{
|
||||||
@@ -63,9 +59,26 @@ class AttendanceTrackingController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function record(RecordAttendanceTrackingRequest $request): JsonResponse
|
public function record(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$result = $this->service->record($request->validated());
|
$validator = Validator::make($request->all(), [
|
||||||
|
'student_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'date' => ['required', 'date_format:Y-m-d'],
|
||||||
|
'parent_email' => ['nullable', 'email'],
|
||||||
|
'parent_name' => ['nullable', 'string'],
|
||||||
|
'subject_type' => ['nullable', 'string'],
|
||||||
|
'semester' => ['nullable', 'string'],
|
||||||
|
'school_year' => ['nullable', 'string'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->service->record($validator->validated());
|
||||||
|
|
||||||
return response()->json(
|
return response()->json(
|
||||||
$result,
|
$result,
|
||||||
@@ -80,13 +93,28 @@ class AttendanceTrackingController extends Controller
|
|||||||
return response()->json($result);
|
return response()->json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function compose(ComposeAttendanceEmailRequest $request): JsonResponse
|
public function compose(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
|
$validator = Validator::make($request->query(), [
|
||||||
|
'student_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'code' => ['nullable', 'string'],
|
||||||
|
'variant' => ['nullable', 'string'],
|
||||||
|
'incident_date' => ['nullable', 'date_format:Y-m-d'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $validator->validated();
|
||||||
$result = $this->service->compose(
|
$result = $this->service->compose(
|
||||||
(int) $request->validated('student_id'),
|
(int) ($data['student_id'] ?? 0),
|
||||||
(string) $request->validated('code', 'ABS_1'),
|
(string) ($data['code'] ?? 'ABS_1'),
|
||||||
(string) $request->validated('variant', 'default'),
|
(string) ($data['variant'] ?? 'default'),
|
||||||
$request->validated('incident_date'),
|
$data['incident_date'] ?? null,
|
||||||
);
|
);
|
||||||
|
|
||||||
return response()->json(
|
return response()->json(
|
||||||
@@ -95,9 +123,26 @@ class AttendanceTrackingController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendManualEmail(SendAttendanceManualEmailRequest $request): JsonResponse
|
public function sendManualEmail(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$result = $this->service->sendEmailManual($request->validated());
|
$validator = Validator::make($request->all(), [
|
||||||
|
'student_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'to' => ['required', 'email'],
|
||||||
|
'subject' => ['required', 'string'],
|
||||||
|
'body_html' => ['required', 'string'],
|
||||||
|
'code' => ['required', 'string'],
|
||||||
|
'variant' => ['nullable', 'string'],
|
||||||
|
'incident_date' => ['nullable', 'date_format:Y-m-d'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->service->sendEmailManual($validator->validated());
|
||||||
|
|
||||||
return response()->json(
|
return response()->json(
|
||||||
$result,
|
$result,
|
||||||
@@ -105,9 +150,21 @@ class AttendanceTrackingController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parentsInfo(ParentsInfoRequest $request): JsonResponse
|
public function parentsInfo(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$result = $this->service->parentsInfo((int) $request->validated('student_id'));
|
$validator = Validator::make($request->query(), [
|
||||||
|
'student_id' => ['required', 'integer', 'min:1'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $validator->validated();
|
||||||
|
$result = $this->service->parentsInfo((int) ($data['student_id'] ?? 0));
|
||||||
|
|
||||||
return response()->json(
|
return response()->json(
|
||||||
$result,
|
$result,
|
||||||
@@ -115,9 +172,26 @@ class AttendanceTrackingController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveNotificationNote(SaveAttendanceNotificationNoteRequest $request): JsonResponse
|
public function saveNotificationNote(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$result = $this->service->saveNotificationNote($request->validated());
|
$validator = Validator::make($request->all(), [
|
||||||
|
'student_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'code' => ['required', 'string'],
|
||||||
|
'note' => ['required', 'string'],
|
||||||
|
'incident_date' => ['nullable', 'date_format:Y-m-d'],
|
||||||
|
'to' => ['nullable', 'email'],
|
||||||
|
'subject' => ['nullable', 'string'],
|
||||||
|
'variant' => ['nullable', 'string'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->service->saveNotificationNote($validator->validated());
|
||||||
|
|
||||||
return response()->json(
|
return response()->json(
|
||||||
$result,
|
$result,
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
namespace App\Http\Controllers\Api\Auth;
|
namespace App\Http\Controllers\Api\Auth;
|
||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Auth\RegisterRequest;
|
|
||||||
use App\Http\Resources\Auth\RegisterResource;
|
use App\Http\Resources\Auth\RegisterResource;
|
||||||
use App\Services\Auth\RegistrationCaptchaService;
|
use App\Services\Auth\RegistrationCaptchaService;
|
||||||
use App\Services\Auth\RegistrationService;
|
use App\Services\Auth\RegistrationService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class RegisterController extends BaseApiController
|
class RegisterController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -28,7 +29,7 @@ class RegisterController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(RegisterRequest $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
if (app()->runningUnitTests() && $request->header('X-Debug-Request') === '1') {
|
if (app()->runningUnitTests() && $request->header('X-Debug-Request') === '1') {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -43,7 +44,15 @@ class RegisterController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->service->register($request->validated());
|
$validator = Validator::make($request->all(), \App\Http\Requests\Auth\RegisterRequest::ruleset());
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->service->register($validator->validated());
|
||||||
|
|
||||||
if (empty($result['ok'])) {
|
if (empty($result['ok'])) {
|
||||||
$code = $result['code'] ?? 'registration_failed';
|
$code = $result['code'] ?? 'registration_failed';
|
||||||
|
|||||||
@@ -3,13 +3,12 @@
|
|||||||
namespace App\Http\Controllers\Api\Badges;
|
namespace App\Http\Controllers\Api\Badges;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Badges\BadgePrintStatusRequest;
|
|
||||||
use App\Http\Requests\Badges\GenerateBadgePdfRequest;
|
|
||||||
use App\Http\Requests\Badges\LogBadgePrintRequest;
|
|
||||||
use App\Services\Badges\BadgeFormDataService;
|
use App\Services\Badges\BadgeFormDataService;
|
||||||
use App\Services\Badges\BadgePdfService;
|
use App\Services\Badges\BadgePdfService;
|
||||||
use App\Services\Badges\BadgePrintLogService;
|
use App\Services\Badges\BadgePrintLogService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class BadgeController extends Controller
|
class BadgeController extends Controller
|
||||||
@@ -21,24 +20,41 @@ class BadgeController extends Controller
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generatePdf(GenerateBadgePdfRequest $request)
|
public function generatePdf(Request $request)
|
||||||
{
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'user_ids' => ['required', 'array', 'min:1'],
|
||||||
|
'user_ids.*' => ['integer', 'min:1'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
'roles' => ['nullable', 'array'],
|
||||||
|
'classes' => ['nullable', 'array'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $validator->validated();
|
||||||
|
|
||||||
return $this->badgePdfService->generate(
|
return $this->badgePdfService->generate(
|
||||||
userIds: $request->input('user_ids', []),
|
userIds: $data['user_ids'] ?? [],
|
||||||
schoolYear: $request->input('school_year'),
|
schoolYear: $data['school_year'] ?? null,
|
||||||
rolesMap: $request->input('roles', []),
|
rolesMap: $data['roles'] ?? [],
|
||||||
classesMap: $request->input('classes', []),
|
classesMap: $data['classes'] ?? [],
|
||||||
actorId: optional($request->user())->id
|
actorId: optional($request->user())->id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function printStatus(BadgePrintStatusRequest $request): JsonResponse
|
public function printStatus(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'ok' => true,
|
'ok' => true,
|
||||||
'data' => $this->badgePrintLogService->getStatus(
|
'data' => $this->badgePrintLogService->getStatus(
|
||||||
$request->normalizedUserIds(),
|
$this->parseUserIds($request),
|
||||||
$request->input('school_year')
|
$request->input('school_year')
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
@@ -50,15 +66,32 @@ class BadgeController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function logPrint(LogBadgePrintRequest $request): JsonResponse
|
public function logPrint(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'user_ids' => ['required', 'array', 'min:1'],
|
||||||
|
'user_ids.*' => ['integer', 'min:1'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
'roles' => ['nullable', 'array'],
|
||||||
|
'classes' => ['nullable', 'array'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $validator->validated();
|
||||||
|
|
||||||
$inserted = $this->badgePrintLogService->log(
|
$inserted = $this->badgePrintLogService->log(
|
||||||
userIds: $request->input('user_ids', []),
|
userIds: $data['user_ids'] ?? [],
|
||||||
actorId: optional($request->user())->id,
|
actorId: optional($request->user())->id,
|
||||||
schoolYear: $request->input('school_year'),
|
schoolYear: $data['school_year'] ?? null,
|
||||||
rolesMap: $request->input('roles', []),
|
rolesMap: $data['roles'] ?? [],
|
||||||
classesMap: $request->input('classes', [])
|
classesMap: $data['classes'] ?? []
|
||||||
);
|
);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -73,15 +106,30 @@ class BadgeController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function formData(BadgePrintStatusRequest $request): JsonResponse
|
public function formData(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'ok' => true,
|
'ok' => true,
|
||||||
'data' => $this->badgeFormDataService->build(
|
'data' => $this->badgeFormDataService->build(
|
||||||
schoolYear: $request->input('school_year'),
|
schoolYear: $request->input('school_year'),
|
||||||
selectedUserIds: $request->normalizedUserIds(),
|
selectedUserIds: $this->parseUserIds($request),
|
||||||
activeRole: $request->input('active_role')
|
activeRole: $request->input('active_role')
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function parseUserIds(Request $request): array
|
||||||
|
{
|
||||||
|
$userIds = $request->input('user_ids', $request->query('user_ids', []));
|
||||||
|
|
||||||
|
if (is_string($userIds)) {
|
||||||
|
$userIds = array_filter(array_map('trim', explode(',', $userIds)), 'strlen');
|
||||||
|
} elseif (!is_array($userIds)) {
|
||||||
|
$userIds = $userIds ? [$userIds] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$userIds = array_values(array_unique(array_map(static fn ($v) => (int) $v, $userIds)));
|
||||||
|
|
||||||
|
return array_values(array_filter($userIds, static fn ($v) => $v > 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,13 +3,13 @@
|
|||||||
namespace App\Http\Controllers\Api\Finance;
|
namespace App\Http\Controllers\Api\Finance;
|
||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Fees\FeeRefundRequest;
|
|
||||||
use App\Http\Requests\Fees\FeeTuitionTotalRequest;
|
|
||||||
use App\Http\Resources\Fees\FeeRefundResource;
|
use App\Http\Resources\Fees\FeeRefundResource;
|
||||||
use App\Http\Resources\Fees\FeeTuitionTotalResource;
|
use App\Http\Resources\Fees\FeeTuitionTotalResource;
|
||||||
use App\Services\Fees\FeeRefundCalculatorService;
|
use App\Services\Fees\FeeRefundCalculatorService;
|
||||||
use App\Services\Fees\FeeStudentFeeService;
|
use App\Services\Fees\FeeStudentFeeService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class FeeCalculationController extends BaseApiController
|
class FeeCalculationController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -20,9 +20,26 @@ class FeeCalculationController extends BaseApiController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function refund(FeeRefundRequest $request): JsonResponse
|
public function refund(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$validator = Validator::make($request->all(), [
|
||||||
|
'parent_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'students' => ['required', 'array'],
|
||||||
|
'students.*.student_id' => ['nullable', 'integer'],
|
||||||
|
'students.*.class_section_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'students.*.enrollment_status' => ['required', 'string', 'max:50'],
|
||||||
|
'students.*.admission_status' => ['required', 'string', 'max:50'],
|
||||||
|
'students.*.withdrawal_date' => ['nullable', 'date'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$result = $this->refunds->calculateRefund($payload['students'], (int) $payload['parent_id']);
|
$result = $this->refunds->calculateRefund($payload['students'], (int) $payload['parent_id']);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -31,9 +48,22 @@ class FeeCalculationController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tuitionTotal(FeeTuitionTotalRequest $request): JsonResponse
|
public function tuitionTotal(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$validator = Validator::make($request->all(), [
|
||||||
|
'students' => ['required', 'array'],
|
||||||
|
'students.*.class_section_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'students.*.grade' => ['nullable', 'string', 'max:20'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$total = $this->tuition->totalTuitionFee($payload['students']);
|
$total = $this->tuition->totalTuitionFee($payload['students']);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Controllers\Api\Finance;
|
namespace App\Http\Controllers\Api\Finance;
|
||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Invoices\InvoiceGenerateRequest;
|
|
||||||
use App\Http\Requests\Invoices\InvoiceManagementRequest;
|
use App\Http\Requests\Invoices\InvoiceManagementRequest;
|
||||||
use App\Http\Requests\Invoices\InvoiceParentRequest;
|
use App\Http\Requests\Invoices\InvoiceParentRequest;
|
||||||
use App\Http\Requests\Invoices\InvoiceStatusRequest;
|
use App\Http\Requests\Invoices\InvoiceStatusRequest;
|
||||||
@@ -15,6 +14,8 @@ use App\Services\Invoices\InvoiceManagementService;
|
|||||||
use App\Services\Invoices\InvoicePaymentService;
|
use App\Services\Invoices\InvoicePaymentService;
|
||||||
use App\Services\Invoices\InvoicePdfService;
|
use App\Services\Invoices\InvoicePdfService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
|
|
||||||
class InvoiceController extends BaseApiController
|
class InvoiceController extends BaseApiController
|
||||||
@@ -44,9 +45,22 @@ class InvoiceController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generate(InvoiceGenerateRequest $request): JsonResponse
|
public function generate(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'parent_id' => ['required', 'integer', 'exists:users,id'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:20'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$result = $this->generation->generateInvoice((int) $payload['parent_id'], $payload['school_year'] ?? null);
|
$result = $this->generation->generateInvoice((int) $payload['parent_id'], $payload['school_year'] ?? null);
|
||||||
|
|
||||||
if (empty($result['ok'])) {
|
if (empty($result['ok'])) {
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ namespace App\Http\Controllers\Api\Finance;
|
|||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Payments\PaymentByParentRequest;
|
use App\Http\Requests\Payments\PaymentByParentRequest;
|
||||||
use App\Http\Requests\Payments\PaymentCreateRequest;
|
|
||||||
use App\Http\Requests\Payments\PaymentUpdateBalanceRequest;
|
|
||||||
use App\Http\Resources\Payments\PaymentResource;
|
use App\Http\Resources\Payments\PaymentResource;
|
||||||
use App\Services\Payments\PaymentBalanceService;
|
use App\Services\Payments\PaymentBalanceService;
|
||||||
use App\Services\Payments\PaymentLookupService;
|
use App\Services\Payments\PaymentLookupService;
|
||||||
use App\Services\Payments\PaymentPlanService;
|
use App\Services\Payments\PaymentPlanService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class PaymentController extends BaseApiController
|
class PaymentController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -22,9 +22,30 @@ class PaymentController extends BaseApiController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(PaymentCreateRequest $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'parent_id' => ['required', 'integer', 'exists:users,id'],
|
||||||
|
'invoice_id' => ['nullable', 'integer', 'exists:invoices,id'],
|
||||||
|
'total_amount' => ['required', 'numeric', 'min:0.01'],
|
||||||
|
'number_of_installments' => ['required', 'integer', 'min:1'],
|
||||||
|
'payment_date' => ['nullable', 'date'],
|
||||||
|
'payment_method' => ['nullable', 'string', 'max:50'],
|
||||||
|
'payment_type' => ['nullable', 'string', 'max:50'],
|
||||||
|
'status' => ['nullable', 'string', 'max:50'],
|
||||||
|
'semester' => ['nullable', 'string', 'max:50'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$payment = $this->planService->createPlan($payload);
|
$payment = $this->planService->createPlan($payload);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -44,9 +65,21 @@ class PaymentController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateBalance(PaymentUpdateBalanceRequest $request, int $paymentId): JsonResponse
|
public function updateBalance(Request $request, int $paymentId): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'paid_amount' => ['required', 'numeric', 'min:0.01'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$updated = $this->balanceService->updateBalance($paymentId, (float) $payload['paid_amount']);
|
$updated = $this->balanceService->updateBalance($paymentId, (float) $payload['paid_amount']);
|
||||||
|
|
||||||
if (!$updated) {
|
if (!$updated) {
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ namespace App\Http\Controllers\Api\Finance;
|
|||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Payments\PaymentEventChargesListRequest;
|
use App\Http\Requests\Payments\PaymentEventChargesListRequest;
|
||||||
use App\Http\Requests\Payments\PaymentEventChargesStoreRequest;
|
|
||||||
use App\Services\Payments\PaymentEventChargesService;
|
use App\Services\Payments\PaymentEventChargesService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class PaymentEventChargesController extends BaseApiController
|
class PaymentEventChargesController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -23,9 +24,29 @@ class PaymentEventChargesController extends BaseApiController
|
|||||||
return response()->json(['ok' => true] + $data);
|
return response()->json(['ok' => true] + $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(PaymentEventChargesStoreRequest $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'parent_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'event_name' => ['required', 'string', 'max:255'],
|
||||||
|
'description' => ['nullable', 'string', 'max:1000'],
|
||||||
|
'amount' => ['required', 'numeric', 'min:0'],
|
||||||
|
'semester' => ['required', 'string', 'max:50'],
|
||||||
|
'school_year' => ['required', 'string', 'max:50'],
|
||||||
|
'student_ids' => ['nullable', 'array'],
|
||||||
|
'student_ids.*' => ['integer', 'min:1'],
|
||||||
|
'student_id' => ['nullable', 'integer', 'min:1'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$userId = (int) (auth()->id() ?? 0);
|
$userId = (int) (auth()->id() ?? 0);
|
||||||
|
|
||||||
$count = $this->service->addCharges($payload, $userId);
|
$count = $this->service->addCharges($payload, $userId);
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ namespace App\Http\Controllers\Api\Finance;
|
|||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Payments\PaymentManualEditRequest;
|
use App\Http\Requests\Payments\PaymentManualEditRequest;
|
||||||
use App\Http\Requests\Payments\PaymentManualSearchRequest;
|
|
||||||
use App\Http\Requests\Payments\PaymentManualSuggestRequest;
|
|
||||||
use App\Http\Requests\Payments\PaymentManualUpdateRequest;
|
use App\Http\Requests\Payments\PaymentManualUpdateRequest;
|
||||||
use App\Services\Payments\PaymentManualService;
|
use App\Services\Payments\PaymentManualService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class PaymentManualController extends BaseApiController
|
class PaymentManualController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -18,9 +17,22 @@ class PaymentManualController extends BaseApiController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function search(PaymentManualSearchRequest $request): JsonResponse
|
public function search(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'search_term' => ['nullable', 'string', 'max:255'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$data = $this->service->search(
|
$data = $this->service->search(
|
||||||
(string) ($payload['search_term'] ?? ''),
|
(string) ($payload['search_term'] ?? ''),
|
||||||
$payload['school_year'] ?? null
|
$payload['school_year'] ?? null
|
||||||
@@ -29,9 +41,21 @@ class PaymentManualController extends BaseApiController
|
|||||||
return response()->json(['ok' => true] + $data);
|
return response()->json(['ok' => true] + $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function suggest(PaymentManualSuggestRequest $request): JsonResponse
|
public function suggest(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'q' => ['required', 'string', 'max:255'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$items = $this->service->suggest((string) ($payload['q'] ?? ''));
|
$items = $this->service->suggest((string) ($payload['q'] ?? ''));
|
||||||
|
|
||||||
return response()->json(['ok' => true, 'items' => $items]);
|
return response()->json(['ok' => true, 'items' => $items]);
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
namespace App\Http\Controllers\Api\Finance;
|
namespace App\Http\Controllers\Api\Finance;
|
||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Payments\PaymentTransactionCreateRequest;
|
|
||||||
use App\Http\Resources\Payments\PaymentTransactionResource;
|
use App\Http\Resources\Payments\PaymentTransactionResource;
|
||||||
use App\Services\Payments\PaymentTransactionService;
|
use App\Services\Payments\PaymentTransactionService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class PaymentTransactionController extends BaseApiController
|
class PaymentTransactionController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -16,9 +16,31 @@ class PaymentTransactionController extends BaseApiController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(PaymentTransactionCreateRequest $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'transaction_id' => ['required', 'string', 'max:100'],
|
||||||
|
'payment_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'transaction_date' => ['nullable', 'date'],
|
||||||
|
'amount' => ['required', 'numeric', 'min:0.01'],
|
||||||
|
'payment_method' => ['required', 'string', 'max:50'],
|
||||||
|
'payment_status' => ['nullable', 'string', 'max:50'],
|
||||||
|
'transaction_fee' => ['nullable', 'numeric', 'min:0'],
|
||||||
|
'payment_reference' => ['nullable', 'string', 'max:100'],
|
||||||
|
'is_full_payment' => ['nullable', 'boolean'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
'semester' => ['nullable', 'string', 'max:50'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$transaction = $this->service->create($payload);
|
$transaction = $this->service->create($payload);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ namespace App\Http\Controllers\Api\Finance;
|
|||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\PurchaseOrders\PurchaseOrderIndexRequest;
|
use App\Http\Requests\PurchaseOrders\PurchaseOrderIndexRequest;
|
||||||
use App\Http\Requests\PurchaseOrders\PurchaseOrderReceiveRequest;
|
|
||||||
use App\Http\Requests\PurchaseOrders\PurchaseOrderStoreRequest;
|
|
||||||
use App\Http\Resources\PurchaseOrders\PurchaseOrderItemResource;
|
use App\Http\Resources\PurchaseOrders\PurchaseOrderItemResource;
|
||||||
use App\Http\Resources\PurchaseOrders\PurchaseOrderResource;
|
use App\Http\Resources\PurchaseOrders\PurchaseOrderResource;
|
||||||
use App\Models\PurchaseOrder;
|
use App\Models\PurchaseOrder;
|
||||||
@@ -14,6 +12,8 @@ use App\Services\PurchaseOrders\PurchaseOrderQueryService;
|
|||||||
use App\Services\PurchaseOrders\PurchaseOrderReceiveService;
|
use App\Services\PurchaseOrders\PurchaseOrderReceiveService;
|
||||||
use App\Services\PurchaseOrders\PurchaseOrderStatusService;
|
use App\Services\PurchaseOrders\PurchaseOrderStatusService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
class PurchaseOrderController extends BaseApiController
|
class PurchaseOrderController extends BaseApiController
|
||||||
@@ -63,9 +63,41 @@ class PurchaseOrderController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(PurchaseOrderStoreRequest $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'po_number' => ['required', 'string', 'max:60'],
|
||||||
|
'supplier_id' => ['required', 'integer', 'min:1', 'exists:suppliers,id'],
|
||||||
|
'status' => ['nullable', 'string', 'in:' . implode(',', PurchaseOrder::allowedStatuses())],
|
||||||
|
'order_date' => ['nullable', 'date'],
|
||||||
|
'expected_date' => ['nullable', 'date'],
|
||||||
|
'notes' => ['nullable', 'string', 'max:5000'],
|
||||||
|
'items' => ['required', 'array', 'min:1'],
|
||||||
|
'items.*.supply_id' => ['required', 'integer', 'min:1', 'exists:supplies,id'],
|
||||||
|
'items.*.description' => ['nullable', 'string', 'max:1000'],
|
||||||
|
'items.*.quantity' => ['required', 'integer', 'min:1'],
|
||||||
|
'items.*.unit_cost' => ['required', 'numeric', 'min:0'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
|
if (!empty($payload['order_date']) && !empty($payload['expected_date'])) {
|
||||||
|
$orderTs = strtotime((string) $payload['order_date']);
|
||||||
|
$expectedTs = strtotime((string) $payload['expected_date']);
|
||||||
|
if ($orderTs !== false && $expectedTs !== false && $expectedTs < $orderTs) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => ['expected_date' => ['The expected date must be on or after the order date.']],
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$po = $this->createService->create($payload);
|
$po = $this->createService->create($payload);
|
||||||
@@ -81,9 +113,23 @@ class PurchaseOrderController extends BaseApiController
|
|||||||
], 201);
|
], 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function receive(PurchaseOrderReceiveRequest $request, int $id): JsonResponse
|
public function receive(Request $request, int $id): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'items' => ['required', 'array', 'min:1'],
|
||||||
|
'items.*.id' => ['required', 'integer', 'min:1'],
|
||||||
|
'items.*.quantity' => ['required', 'integer', 'min:1'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
|
|
||||||
$po = PurchaseOrder::query()->find($id);
|
$po = PurchaseOrder::query()->find($id);
|
||||||
if (!$po) {
|
if (!$po) {
|
||||||
|
|||||||
@@ -6,17 +6,13 @@ use App\Http\Controllers\Api\BaseApiController;
|
|||||||
use App\Http\Requests\Files\FileNameRequest;
|
use App\Http\Requests\Files\FileNameRequest;
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementBatchAdminFileRequest;
|
use App\Http\Requests\Reimbursements\ReimbursementBatchAdminFileRequest;
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementBatchAssignmentRequest;
|
use App\Http\Requests\Reimbursements\ReimbursementBatchAssignmentRequest;
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementBatchCreateRequest;
|
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementBatchEmailRequest;
|
use App\Http\Requests\Reimbursements\ReimbursementBatchEmailRequest;
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementBatchLockRequest;
|
use App\Http\Requests\Reimbursements\ReimbursementBatchLockRequest;
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementExportBatchRequest;
|
use App\Http\Requests\Reimbursements\ReimbursementExportBatchRequest;
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementExportRequest;
|
use App\Http\Requests\Reimbursements\ReimbursementExportRequest;
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementIndexRequest;
|
use App\Http\Requests\Reimbursements\ReimbursementIndexRequest;
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementMarkDonationRequest;
|
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementProcessRequest;
|
use App\Http\Requests\Reimbursements\ReimbursementProcessRequest;
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementStoreRequest;
|
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementUnderProcessingRequest;
|
use App\Http\Requests\Reimbursements\ReimbursementUnderProcessingRequest;
|
||||||
use App\Http\Requests\Reimbursements\ReimbursementUpdateRequest;
|
|
||||||
use App\Http\Resources\Reimbursements\ReimbursementBatchResource;
|
use App\Http\Resources\Reimbursements\ReimbursementBatchResource;
|
||||||
use App\Http\Resources\Reimbursements\ReimbursementExpenseResource;
|
use App\Http\Resources\Reimbursements\ReimbursementExpenseResource;
|
||||||
use App\Http\Resources\Reimbursements\ReimbursementRecipientResource;
|
use App\Http\Resources\Reimbursements\ReimbursementRecipientResource;
|
||||||
@@ -37,6 +33,7 @@ use App\Services\Reimbursements\ReimbursementQueryService;
|
|||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
class ReimbursementController extends BaseApiController
|
class ReimbursementController extends BaseApiController
|
||||||
@@ -69,9 +66,21 @@ class ReimbursementController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function markDonation(ReimbursementMarkDonationRequest $request): JsonResponse
|
public function markDonation(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'expense_id' => ['required', 'integer', 'min:1'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$userId = (int) (auth()->id() ?? 0);
|
$userId = (int) (auth()->id() ?? 0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -87,9 +96,21 @@ class ReimbursementController extends BaseApiController
|
|||||||
return response()->json(['ok' => true]);
|
return response()->json(['ok' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createBatch(ReimbursementBatchCreateRequest $request): JsonResponse
|
public function createBatch(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'title' => ['nullable', 'string', 'max:255'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$userId = (int) (auth()->id() ?? 0);
|
$userId = (int) (auth()->id() ?? 0);
|
||||||
$schoolYear = $this->context->getSchoolYear();
|
$schoolYear = $this->context->getSchoolYear();
|
||||||
$semester = $this->context->getSemester();
|
$semester = $this->context->getSemester();
|
||||||
@@ -289,9 +310,29 @@ class ReimbursementController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(ReimbursementStoreRequest $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'amount' => ['required', 'numeric', 'gt:0'],
|
||||||
|
'reimbursed_to' => ['required', 'integer', 'min:1'],
|
||||||
|
'reimbursement_method' => ['required', 'in:Cash,Check'],
|
||||||
|
'check_number' => ['required_if:reimbursement_method,Check', 'nullable', 'string', 'max:50'],
|
||||||
|
'receipt' => ['required_if:reimbursement_method,Check', 'nullable', 'file', 'max:2048', 'mimes:jpg,jpeg,png,webp,gif,pdf'],
|
||||||
|
'expense_id' => ['nullable', 'integer', 'min:1'],
|
||||||
|
'description' => ['nullable', 'string'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:20'],
|
||||||
|
'semester' => ['nullable', 'string', 'max:20'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$userId = (int) (auth()->id() ?? 0);
|
$userId = (int) (auth()->id() ?? 0);
|
||||||
$receiptName = null;
|
$receiptName = null;
|
||||||
|
|
||||||
@@ -361,14 +402,32 @@ class ReimbursementController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(ReimbursementUpdateRequest $request, int $id): JsonResponse
|
public function update(Request $request, int $id): JsonResponse
|
||||||
{
|
{
|
||||||
$reimb = Reimbursement::query()->find($id);
|
$reimb = Reimbursement::query()->find($id);
|
||||||
if (!$reimb) {
|
if (!$reimb) {
|
||||||
return response()->json(['ok' => false, 'message' => 'Reimbursement not found.'], 404);
|
return response()->json(['ok' => false, 'message' => 'Reimbursement not found.'], 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'amount' => ['required', 'numeric', 'gt:0'],
|
||||||
|
'reimbursed_to' => ['required', 'integer', 'min:1'],
|
||||||
|
'reimbursement_method' => ['required', 'in:Cash,Check'],
|
||||||
|
'check_number' => ['required_if:reimbursement_method,Check', 'nullable', 'string', 'max:50'],
|
||||||
|
'receipt' => ['nullable', 'file', 'max:2048', 'mimes:jpg,jpeg,png,webp,gif,pdf'],
|
||||||
|
'remove_receipt' => ['nullable', 'boolean'],
|
||||||
|
'description' => ['nullable', 'string'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$userId = (int) (auth()->id() ?? 0);
|
$userId = (int) (auth()->id() ?? 0);
|
||||||
|
|
||||||
$receiptName = $reimb->receipt_path;
|
$receiptName = $reimb->receipt_path;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use App\Http\Requests\Incidents\IncidentCancelRequest;
|
|||||||
use App\Http\Requests\Incidents\IncidentCloseRequest;
|
use App\Http\Requests\Incidents\IncidentCloseRequest;
|
||||||
use App\Http\Requests\Incidents\IncidentListRequest;
|
use App\Http\Requests\Incidents\IncidentListRequest;
|
||||||
use App\Http\Requests\Incidents\IncidentStateRequest;
|
use App\Http\Requests\Incidents\IncidentStateRequest;
|
||||||
use App\Http\Requests\Incidents\IncidentStoreRequest;
|
|
||||||
use App\Http\Resources\Incidents\IncidentAnalysisStudentResource;
|
use App\Http\Resources\Incidents\IncidentAnalysisStudentResource;
|
||||||
use App\Http\Resources\Incidents\IncidentGradeResource;
|
use App\Http\Resources\Incidents\IncidentGradeResource;
|
||||||
use App\Http\Resources\Incidents\IncidentResource;
|
use App\Http\Resources\Incidents\IncidentResource;
|
||||||
@@ -16,6 +15,8 @@ use App\Services\Incidents\CurrentIncidentService;
|
|||||||
use App\Services\Incidents\IncidentAnalysisService;
|
use App\Services\Incidents\IncidentAnalysisService;
|
||||||
use App\Services\Incidents\IncidentHistoryService;
|
use App\Services\Incidents\IncidentHistoryService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class IncidentController extends BaseApiController
|
class IncidentController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -83,9 +84,26 @@ class IncidentController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(IncidentStoreRequest $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'student_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'grade' => ['required', 'integer', 'min:1'],
|
||||||
|
'incident' => ['required', 'string', 'max:255'],
|
||||||
|
'description' => ['required', 'string', 'max:2000'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:20'],
|
||||||
|
'semester' => ['nullable', 'string', 'max:20'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$result = $this->currentService->addIncident($payload, (int) (auth()->id() ?? 0));
|
$result = $this->currentService->addIncident($payload, (int) (auth()->id() ?? 0));
|
||||||
|
|
||||||
if (empty($result['ok'])) {
|
if (empty($result['ok'])) {
|
||||||
@@ -109,9 +127,22 @@ class IncidentController extends BaseApiController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(IncidentCloseRequest $request, int $incidentId): JsonResponse
|
public function close(Request $request, int $incidentId): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'state_description' => ['required', 'string', 'max:2000'],
|
||||||
|
'action_taken' => ['nullable', 'string', 'max:2000'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$result = $this->currentService->closeIncident(
|
$result = $this->currentService->closeIncident(
|
||||||
$incidentId,
|
$incidentId,
|
||||||
(string) $payload['state_description'],
|
(string) $payload['state_description'],
|
||||||
|
|||||||
@@ -3,13 +3,14 @@
|
|||||||
namespace App\Http\Controllers\Api\Scores;
|
namespace App\Http\Controllers\Api\Scores;
|
||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Scores\ScoreClassRequest;
|
|
||||||
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
||||||
use App\Http\Resources\Scores\ScoreStudentResource;
|
use App\Http\Resources\Scores\ScoreStudentResource;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Services\Scores\ExamScoreService;
|
use App\Services\Scores\ExamScoreService;
|
||||||
use App\Services\Scores\SemesterScoreService;
|
use App\Services\Scores\SemesterScoreService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class FinalController extends BaseApiController
|
class FinalController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -20,9 +21,23 @@ class FinalController extends BaseApiController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(ScoreClassRequest $request): JsonResponse
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'class_section_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'semester' => ['nullable', 'string', 'max:50'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$data = $this->service->list('final_exam', (int) $payload['class_section_id'], $payload['semester'] ?? null, $payload['school_year'] ?? null);
|
$data = $this->service->list('final_exam', (int) $payload['class_section_id'], $payload['semester'] ?? null, $payload['school_year'] ?? null);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ namespace App\Http\Controllers\Api\Scores;
|
|||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Scores\ScoreAddColumnRequest;
|
use App\Http\Requests\Scores\ScoreAddColumnRequest;
|
||||||
use App\Http\Requests\Scores\ScoreClassRequest;
|
|
||||||
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
||||||
use App\Http\Resources\Scores\ScoreStudentResource;
|
use App\Http\Resources\Scores\ScoreStudentResource;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Services\Scores\HomeworkScoreService;
|
use App\Services\Scores\HomeworkScoreService;
|
||||||
use App\Services\Scores\SemesterScoreService;
|
use App\Services\Scores\SemesterScoreService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class HomeworkController extends BaseApiController
|
class HomeworkController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -21,9 +22,23 @@ class HomeworkController extends BaseApiController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(ScoreClassRequest $request): JsonResponse
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'class_section_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'semester' => ['nullable', 'string', 'max:50'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$data = $this->service->list(
|
$data = $this->service->list(
|
||||||
(int) $payload['class_section_id'],
|
(int) $payload['class_section_id'],
|
||||||
$payload['semester'] ?? null,
|
$payload['semester'] ?? null,
|
||||||
|
|||||||
@@ -3,13 +3,14 @@
|
|||||||
namespace App\Http\Controllers\Api\Scores;
|
namespace App\Http\Controllers\Api\Scores;
|
||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Scores\ScoreClassRequest;
|
|
||||||
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
||||||
use App\Http\Resources\Scores\ScoreStudentResource;
|
use App\Http\Resources\Scores\ScoreStudentResource;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Services\Scores\ExamScoreService;
|
use App\Services\Scores\ExamScoreService;
|
||||||
use App\Services\Scores\SemesterScoreService;
|
use App\Services\Scores\SemesterScoreService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class MidtermController extends BaseApiController
|
class MidtermController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -20,9 +21,23 @@ class MidtermController extends BaseApiController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(ScoreClassRequest $request): JsonResponse
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'class_section_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'semester' => ['nullable', 'string', 'max:50'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$data = $this->service->list('midterm_exam', (int) $payload['class_section_id'], $payload['semester'] ?? null, $payload['school_year'] ?? null);
|
$data = $this->service->list('midterm_exam', (int) $payload['class_section_id'], $payload['semester'] ?? null, $payload['school_year'] ?? null);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|||||||
@@ -3,13 +3,14 @@
|
|||||||
namespace App\Http\Controllers\Api\Scores;
|
namespace App\Http\Controllers\Api\Scores;
|
||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Scores\ScoreClassRequest;
|
|
||||||
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
||||||
use App\Http\Resources\Scores\ScoreStudentResource;
|
use App\Http\Resources\Scores\ScoreStudentResource;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Services\Scores\ParticipationScoreService;
|
use App\Services\Scores\ParticipationScoreService;
|
||||||
use App\Services\Scores\SemesterScoreService;
|
use App\Services\Scores\SemesterScoreService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class ParticipationController extends BaseApiController
|
class ParticipationController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -20,9 +21,23 @@ class ParticipationController extends BaseApiController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(ScoreClassRequest $request): JsonResponse
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'class_section_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'semester' => ['nullable', 'string', 'max:50'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$data = $this->service->list(
|
$data = $this->service->list(
|
||||||
(int) $payload['class_section_id'],
|
(int) $payload['class_section_id'],
|
||||||
$payload['semester'] ?? null,
|
$payload['semester'] ?? null,
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ namespace App\Http\Controllers\Api\Scores;
|
|||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Scores\ScoreAddColumnRequest;
|
use App\Http\Requests\Scores\ScoreAddColumnRequest;
|
||||||
use App\Http\Requests\Scores\ScoreClassRequest;
|
|
||||||
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
||||||
use App\Http\Resources\Scores\ScoreStudentResource;
|
use App\Http\Resources\Scores\ScoreStudentResource;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Services\Scores\ProjectScoreService;
|
use App\Services\Scores\ProjectScoreService;
|
||||||
use App\Services\Scores\SemesterScoreService;
|
use App\Services\Scores\SemesterScoreService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class ProjectController extends BaseApiController
|
class ProjectController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -21,9 +22,23 @@ class ProjectController extends BaseApiController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(ScoreClassRequest $request): JsonResponse
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'class_section_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'semester' => ['nullable', 'string', 'max:50'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$data = $this->service->list(
|
$data = $this->service->list(
|
||||||
(int) $payload['class_section_id'],
|
(int) $payload['class_section_id'],
|
||||||
$payload['semester'] ?? null,
|
$payload['semester'] ?? null,
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ namespace App\Http\Controllers\Api\Scores;
|
|||||||
|
|
||||||
use App\Http\Controllers\Api\BaseApiController;
|
use App\Http\Controllers\Api\BaseApiController;
|
||||||
use App\Http\Requests\Scores\ScoreAddColumnRequest;
|
use App\Http\Requests\Scores\ScoreAddColumnRequest;
|
||||||
use App\Http\Requests\Scores\ScoreClassRequest;
|
|
||||||
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
use App\Http\Requests\Scores\ScoreUpdateRequest;
|
||||||
use App\Http\Resources\Scores\ScoreStudentResource;
|
use App\Http\Resources\Scores\ScoreStudentResource;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Services\Scores\QuizScoreService;
|
use App\Services\Scores\QuizScoreService;
|
||||||
use App\Services\Scores\SemesterScoreService;
|
use App\Services\Scores\SemesterScoreService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class QuizController extends BaseApiController
|
class QuizController extends BaseApiController
|
||||||
{
|
{
|
||||||
@@ -21,9 +22,23 @@ class QuizController extends BaseApiController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(ScoreClassRequest $request): JsonResponse
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$payload = $request->validated();
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'class_section_id' => ['required', 'integer', 'min:1'],
|
||||||
|
'semester' => ['nullable', 'string', 'max:50'],
|
||||||
|
'school_year' => ['nullable', 'string', 'max:50'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => $validator->errors(),
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $validator->validated();
|
||||||
$data = $this->service->list(
|
$data = $this->service->list(
|
||||||
(int) $payload['class_section_id'],
|
(int) $payload['class_section_id'],
|
||||||
$payload['semester'] ?? null,
|
$payload['semester'] ?? null,
|
||||||
|
|||||||
@@ -7,6 +7,39 @@ use Illuminate\Validation\Rule;
|
|||||||
|
|
||||||
class UpdateEnrollmentStatusesRequest extends ApiFormRequest
|
class UpdateEnrollmentStatusesRequest extends ApiFormRequest
|
||||||
{
|
{
|
||||||
|
public function validationData(): array
|
||||||
|
{
|
||||||
|
$data = $this->all();
|
||||||
|
|
||||||
|
if (array_key_exists('enrollment_status', $data)) {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$raw = $this->getContent() ?: '';
|
||||||
|
if ($raw !== '') {
|
||||||
|
$json = json_decode($raw, true);
|
||||||
|
if (is_array($json)) {
|
||||||
|
return array_merge($data, $json);
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_str($raw, $parsed);
|
||||||
|
if (is_array($parsed)) {
|
||||||
|
return array_merge($data, $parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$queryString = (string) $this->server->get('QUERY_STRING', '');
|
||||||
|
if ($queryString !== '') {
|
||||||
|
$parsedQuery = [];
|
||||||
|
parse_str($queryString, $parsedQuery);
|
||||||
|
if (is_array($parsedQuery)) {
|
||||||
|
return array_merge($data, $parsedQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
return auth()->check();
|
return auth()->check();
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Requests;
|
namespace App\Http\Requests\Assignment;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use App\Http\Requests\ApiFormRequest;
|
||||||
|
|
||||||
class StoreAssignmentRequest extends FormRequest
|
class StoreAssignmentRequest extends ApiFormRequest
|
||||||
{
|
{
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
@@ -15,7 +15,7 @@ class StoreAssignmentRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'student_id' => ['required', 'integer', 'exists:students,id'],
|
'student_id' => ['required', 'integer', 'exists:students,id'],
|
||||||
'class_section_id' => ['required', 'integer', 'exists:class_sections,id'],
|
'class_section_id' => ['required', 'integer', 'exists:classSection,class_section_id'],
|
||||||
'semester' => ['required', 'string', 'max:50'],
|
'semester' => ['required', 'string', 'max:50'],
|
||||||
'school_year' => ['required', 'string', 'max:50'],
|
'school_year' => ['required', 'string', 'max:50'],
|
||||||
'description' => ['nullable', 'string'],
|
'description' => ['nullable', 'string'],
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Requests\AttendanceTracking;
|
namespace App\Http\Requests\AttendanceTracking;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use App\Http\Requests\ApiFormRequest;
|
||||||
|
|
||||||
class ComposeAttendanceEmailRequest extends FormRequest
|
class ComposeAttendanceEmailRequest extends ApiFormRequest
|
||||||
{
|
{
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Requests\AttendanceTracking;
|
namespace App\Http\Requests\AttendanceTracking;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use App\Http\Requests\ApiFormRequest;
|
||||||
|
|
||||||
class ParentsInfoRequest extends FormRequest
|
class ParentsInfoRequest extends ApiFormRequest
|
||||||
{
|
{
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Requests\AttendanceTracking;
|
namespace App\Http\Requests\AttendanceTracking;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use App\Http\Requests\ApiFormRequest;
|
||||||
|
|
||||||
class RecordAttendanceTrackingRequest extends FormRequest
|
class RecordAttendanceTrackingRequest extends ApiFormRequest
|
||||||
{
|
{
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Requests\AttendanceTracking;
|
namespace App\Http\Requests\AttendanceTracking;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use App\Http\Requests\ApiFormRequest;
|
||||||
|
|
||||||
class SaveAttendanceNotificationNoteRequest extends FormRequest
|
class SaveAttendanceNotificationNoteRequest extends ApiFormRequest
|
||||||
{
|
{
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Requests\AttendanceTracking;
|
namespace App\Http\Requests\AttendanceTracking;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use App\Http\Requests\ApiFormRequest;
|
||||||
|
|
||||||
class SendAttendanceManualEmailRequest extends FormRequest
|
class SendAttendanceManualEmailRequest extends ApiFormRequest
|
||||||
{
|
{
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Resources;
|
namespace App\Http\Resources\Assignment;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Resources;
|
namespace App\Http\Resources\Assignment;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class TeacherSubmissionReminderMail extends Mailable
|
||||||
|
{
|
||||||
|
use Queueable;
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
protected string $subjectLine,
|
||||||
|
protected string $htmlBody
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function build(): self
|
||||||
|
{
|
||||||
|
return $this->subject($this->subjectLine)
|
||||||
|
->html($this->htmlBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -68,7 +68,7 @@ class AttendanceDay extends BaseModel
|
|||||||
$q = static::query()
|
$q = static::query()
|
||||||
->select('id')
|
->select('id')
|
||||||
->where('class_section_id', $classSectionId)
|
->where('class_section_id', $classSectionId)
|
||||||
->where('date', $date)
|
->whereDate('date', $date)
|
||||||
->where(function ($w) {
|
->where(function ($w) {
|
||||||
$w->where('status', 'published')
|
$w->where('status', 'published')
|
||||||
->orWhere('status', 'finalized'); // legacy
|
->orWhere('status', 'finalized'); // legacy
|
||||||
@@ -91,7 +91,7 @@ class AttendanceDay extends BaseModel
|
|||||||
): ?self {
|
): ?self {
|
||||||
return static::query()
|
return static::query()
|
||||||
->where('class_section_id', $classSectionId)
|
->where('class_section_id', $classSectionId)
|
||||||
->where('date', $date)
|
->whereDate('date', $date)
|
||||||
->where('semester', $semester)
|
->where('semester', $semester)
|
||||||
->where('school_year', $schoolYear)
|
->where('school_year', $schoolYear)
|
||||||
->first();
|
->first();
|
||||||
@@ -112,11 +112,12 @@ class AttendanceDay extends BaseModel
|
|||||||
if ($row) return $row;
|
if ($row) return $row;
|
||||||
|
|
||||||
$now = now();
|
$now = now();
|
||||||
|
$normalizedDate = Carbon::parse($date)->toDateString();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return static::create([
|
return static::create([
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'date' => $date,
|
'date' => $normalizedDate,
|
||||||
'status' => 'draft',
|
'status' => 'draft',
|
||||||
'submitted_by' => null,
|
'submitted_by' => null,
|
||||||
'submitted_at' => null,
|
'submitted_at' => null,
|
||||||
@@ -142,15 +143,15 @@ class AttendanceDay extends BaseModel
|
|||||||
/**
|
/**
|
||||||
* DEPRECATED legacy finalize => submit (teacher submit).
|
* DEPRECATED legacy finalize => submit (teacher submit).
|
||||||
*/
|
*/
|
||||||
public static function finalize(int $id, int $userId): bool
|
public function finalize(int $userId): bool
|
||||||
{
|
{
|
||||||
return static::submit($id, $userId, null);
|
return $this->submit($userId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Teacher submit: status => submitted (teacher locked, admin editable).
|
* Teacher submit: status => submitted (teacher locked, admin editable).
|
||||||
*/
|
*/
|
||||||
public static function submit(int $id, int $userId, ?string $autoPublishAt = null): bool
|
public function submit(int $userId, ?string $autoPublishAt = null): bool
|
||||||
{
|
{
|
||||||
$now = now();
|
$now = now();
|
||||||
|
|
||||||
@@ -165,17 +166,17 @@ class AttendanceDay extends BaseModel
|
|||||||
$payload['auto_publish_at'] = $autoPublishAt;
|
$payload['auto_publish_at'] = $autoPublishAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return static::query()->whereKey($id)->update($payload) >= 0;
|
return static::query()->whereKey($this->id)->update($payload) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin publish (hard lock): status => published.
|
* Admin publish (hard lock): status => published.
|
||||||
*/
|
*/
|
||||||
public static function publish(int $id, int $userId): bool
|
public function publish(int $userId): bool
|
||||||
{
|
{
|
||||||
$now = now();
|
$now = now();
|
||||||
|
|
||||||
return static::query()->whereKey($id)->update([
|
return static::query()->whereKey($this->id)->update([
|
||||||
'status' => 'published',
|
'status' => 'published',
|
||||||
'published_by' => $userId,
|
'published_by' => $userId,
|
||||||
'published_at' => $now,
|
'published_at' => $now,
|
||||||
@@ -186,7 +187,7 @@ class AttendanceDay extends BaseModel
|
|||||||
/**
|
/**
|
||||||
* Admin reopen a day back to 'draft' (default) or 'submitted'.
|
* Admin reopen a day back to 'draft' (default) or 'submitted'.
|
||||||
*/
|
*/
|
||||||
public static function reopen(int $id, int $userId, string $toStatus = 'draft', ?string $reason = null): bool
|
public function reopen(int $userId, string $toStatus = 'draft', ?string $reason = null): bool
|
||||||
{
|
{
|
||||||
if (!in_array($toStatus, ['draft', 'submitted'], true)) {
|
if (!in_array($toStatus, ['draft', 'submitted'], true)) {
|
||||||
throw new \InvalidArgumentException('toStatus must be "draft" or "submitted".');
|
throw new \InvalidArgumentException('toStatus must be "draft" or "submitted".');
|
||||||
@@ -194,7 +195,7 @@ class AttendanceDay extends BaseModel
|
|||||||
|
|
||||||
$now = now();
|
$now = now();
|
||||||
|
|
||||||
return static::query()->whereKey($id)->update([
|
return static::query()->whereKey($this->id)->update([
|
||||||
'status' => $toStatus,
|
'status' => $toStatus,
|
||||||
'reopened_by' => $userId,
|
'reopened_by' => $userId,
|
||||||
'reopened_at' => $now,
|
'reopened_at' => $now,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class AttendanceEmailTemplate extends BaseModel
|
|||||||
* Fetch a template by code and variant, falling back to 'default' if needed.
|
* Fetch a template by code and variant, falling back to 'default' if needed.
|
||||||
* Active only.
|
* Active only.
|
||||||
*/
|
*/
|
||||||
public static function getTemplate(string $code, string $variant = 'default'): ?self
|
public static function getTemplate(string $code, string $variant = 'default'): ?array
|
||||||
{
|
{
|
||||||
$row = static::query()
|
$row = static::query()
|
||||||
->where('code', $code)
|
->where('code', $code)
|
||||||
@@ -39,13 +39,15 @@ class AttendanceEmailTemplate extends BaseModel
|
|||||||
->first();
|
->first();
|
||||||
|
|
||||||
if ($row) {
|
if ($row) {
|
||||||
return $row;
|
return $row->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
return static::query()
|
$fallback = static::query()
|
||||||
->where('code', $code)
|
->where('code', $code)
|
||||||
->where('variant', 'default')
|
->where('variant', 'default')
|
||||||
->where('is_active', 1)
|
->where('is_active', 1)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
|
return $fallback?->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,10 +3,12 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Models\BaseModel;
|
use App\Models\BaseModel;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class ClassSection extends BaseModel
|
class ClassSection extends BaseModel
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
// CI table name is "classSection"
|
// CI table name is "classSection"
|
||||||
protected $table = 'classSection';
|
protected $table = 'classSection';
|
||||||
|
|
||||||
@@ -28,6 +30,16 @@ class ClassSection extends BaseModel
|
|||||||
'class_section_id' => 'integer',
|
'class_section_id' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function getSectionNameAttribute(): ?string
|
||||||
|
{
|
||||||
|
return $this->attributes['class_section_name'] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSectionNameAttribute($value): void
|
||||||
|
{
|
||||||
|
$this->attributes['class_section_name'] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
/* =========================
|
/* =========================
|
||||||
* Relationships (optional)
|
* Relationships (optional)
|
||||||
* ========================= */
|
* ========================= */
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ class CommunicationLog extends BaseModel
|
|||||||
'metadata',
|
'metadata',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function getFillable(): array
|
||||||
|
{
|
||||||
|
return $this->fillable;
|
||||||
|
}
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'student_id' => 'integer',
|
'student_id' => 'integer',
|
||||||
'family_id' => 'integer',
|
'family_id' => 'integer',
|
||||||
|
|||||||
@@ -23,8 +23,24 @@ class EmailTemplate extends BaseModel
|
|||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'is_active' => 'boolean',
|
'is_active' => 'boolean',
|
||||||
|
'updated_by' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public static function getTemplate(string $code, string $variant = 'default'): ?self
|
||||||
|
{
|
||||||
|
$row = static::query()
|
||||||
|
->where('code', $code)
|
||||||
|
->where('is_active', 1)
|
||||||
|
->where(function ($q) use ($variant) {
|
||||||
|
$q->where('variant', $variant)
|
||||||
|
->orWhere('variant', 'default');
|
||||||
|
})
|
||||||
|
->orderByRaw("CASE WHEN variant = ? THEN 0 ELSE 1 END", [$variant])
|
||||||
|
->first();
|
||||||
|
|
||||||
|
return $row;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Equivalent of CI getActiveTemplates():
|
* Equivalent of CI getActiveTemplates():
|
||||||
* is_active=1, orderBy template_key ASC
|
* is_active=1, orderBy template_key ASC
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ class PurchaseOrder extends BaseModel
|
|||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function getFillable(): array
|
||||||
|
{
|
||||||
|
return $this->fillable;
|
||||||
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
* Status (enum-like)
|
* Status (enum-like)
|
||||||
* ============================================================
|
* ============================================================
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ class PurchaseOrderItem extends BaseModel
|
|||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function getFillable(): array
|
||||||
|
{
|
||||||
|
return $this->fillable;
|
||||||
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
* Relationships (optional but recommended)
|
* Relationships (optional but recommended)
|
||||||
* ============================================================
|
* ============================================================
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class Stats extends BaseModel
|
|||||||
* If your stats table has created_at/updated_at, keep true (default).
|
* If your stats table has created_at/updated_at, keep true (default).
|
||||||
* If it doesn't, set to false.
|
* If it doesn't, set to false.
|
||||||
*/
|
*/
|
||||||
public $timestamps = false;
|
public $timestamps = true;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'students',
|
'students',
|
||||||
@@ -28,6 +28,11 @@ class Stats extends BaseModel
|
|||||||
'users' => 'integer',
|
'users' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function getFillable(): array
|
||||||
|
{
|
||||||
|
return $this->fillable;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CI-compatible: getStats()
|
* CI-compatible: getStats()
|
||||||
* Returns all rows.
|
* Returns all rows.
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use App\Models\BaseModel;
|
use App\Models\BaseModel;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class Student extends BaseModel
|
class Student extends BaseModel
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
protected $table = 'students';
|
protected $table = 'students';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +40,7 @@ class Student extends BaseModel
|
|||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'school_id' => 'integer',
|
'school_id' => 'string',
|
||||||
'age' => 'integer',
|
'age' => 'integer',
|
||||||
'photo_consent' => 'boolean',
|
'photo_consent' => 'boolean',
|
||||||
'is_new' => 'boolean',
|
'is_new' => 'boolean',
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ class TeacherClass extends BaseModel
|
|||||||
->join('classSection as cs', 'cs.class_section_id', '=', 'tc.class_section_id')
|
->join('classSection as cs', 'cs.class_section_id', '=', 'tc.class_section_id')
|
||||||
->where('tc.teacher_id', $teacherId)
|
->where('tc.teacher_id', $teacherId)
|
||||||
->where('tc.school_year', $schoolYear)
|
->where('tc.school_year', $schoolYear)
|
||||||
->orderByRaw("FIELD(tc.position,'main','ta')")
|
->orderByRaw("CASE tc.position WHEN 'main' THEN 0 WHEN 'ta' THEN 1 ELSE 2 END")
|
||||||
->get()
|
->get()
|
||||||
->map(fn ($r) => (array) $r)
|
->map(fn ($r) => (array) $r)
|
||||||
->all();
|
->all();
|
||||||
@@ -296,7 +296,7 @@ class TeacherClass extends BaseModel
|
|||||||
->leftJoin('users as u', 'u.id', '=', 'tc.teacher_id')
|
->leftJoin('users as u', 'u.id', '=', 'tc.teacher_id')
|
||||||
->where('tc.class_section_id', $sectionCode)
|
->where('tc.class_section_id', $sectionCode)
|
||||||
->where('tc.school_year', $schoolYear)
|
->where('tc.school_year', $schoolYear)
|
||||||
->orderByRaw("FIELD(tc.position,'main','ta')")
|
->orderByRaw("CASE tc.position WHEN 'main' THEN 0 WHEN 'ta' THEN 1 ELSE 2 END")
|
||||||
->orderBy('u.firstname', 'asc')
|
->orderBy('u.firstname', 'asc')
|
||||||
->get()
|
->get()
|
||||||
->map(fn ($r) => (array) $r)
|
->map(fn ($r) => (array) $r)
|
||||||
@@ -324,7 +324,7 @@ class TeacherClass extends BaseModel
|
|||||||
->leftJoin('users as u', 'u.id', '=', 'tc.teacher_id')
|
->leftJoin('users as u', 'u.id', '=', 'tc.teacher_id')
|
||||||
->where('tc.school_year', $schoolYear)
|
->where('tc.school_year', $schoolYear)
|
||||||
->orderBy('tc.class_section_id', 'asc')
|
->orderBy('tc.class_section_id', 'asc')
|
||||||
->orderByRaw("FIELD(tc.position,'main','ta')")
|
->orderByRaw("CASE tc.position WHEN 'main' THEN 0 WHEN 'ta' THEN 1 ELSE 2 END")
|
||||||
->orderBy('u.firstname', 'asc');
|
->orderBy('u.firstname', 'asc');
|
||||||
|
|
||||||
if (!empty($onlySectionCodes)) {
|
if (!empty($onlySectionCodes)) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
@@ -14,6 +15,7 @@ use Laravel\Sanctum\HasApiTokens;
|
|||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
use HasApiTokens;
|
use HasApiTokens;
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
protected $table = 'users';
|
protected $table = 'users';
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ use App\Services\Attendance\AttendanceRecordSyncService;
|
|||||||
use App\Services\Attendance\SemesterRangeService;
|
use App\Services\Attendance\SemesterRangeService;
|
||||||
use App\Services\Attendance\StudentAttendanceWriterService;
|
use App\Services\Attendance\StudentAttendanceWriterService;
|
||||||
use App\Services\Attendance\TeacherAttendanceSubmissionService;
|
use App\Services\Attendance\TeacherAttendanceSubmissionService;
|
||||||
|
use App\Services\Invoices\InvoiceConfigService;
|
||||||
|
use App\Services\Invoices\InvoiceGradeService;
|
||||||
|
use App\Services\Invoices\InvoiceTuitionService;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Routing\Redirector;
|
use Illuminate\Routing\Redirector;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
@@ -20,6 +23,23 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
$this->app->singleton(AttendanceRecordSyncService::class);
|
$this->app->singleton(AttendanceRecordSyncService::class);
|
||||||
$this->app->singleton(StudentAttendanceWriterService::class);
|
$this->app->singleton(StudentAttendanceWriterService::class);
|
||||||
$this->app->singleton(TeacherAttendanceSubmissionService::class);
|
$this->app->singleton(TeacherAttendanceSubmissionService::class);
|
||||||
|
|
||||||
|
$this->app->singleton(InvoiceConfigService::class);
|
||||||
|
$this->app->bind(InvoiceGradeService::class, function ($app) {
|
||||||
|
$config = $app->make(InvoiceConfigService::class);
|
||||||
|
return new InvoiceGradeService($config->getGradeFee());
|
||||||
|
});
|
||||||
|
$this->app->bind(InvoiceTuitionService::class, function ($app) {
|
||||||
|
$config = $app->make(InvoiceConfigService::class);
|
||||||
|
return new InvoiceTuitionService(
|
||||||
|
$app->make(InvoiceGradeService::class),
|
||||||
|
$config->getGradeFee(),
|
||||||
|
$config->getFirstStudentFee(),
|
||||||
|
$config->getSecondStudentFee(),
|
||||||
|
$config->getYouthFee(),
|
||||||
|
$config->getTimezone()
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace App\Services\Administrator;
|
|||||||
|
|
||||||
use App\Models\Enrollment;
|
use App\Models\Enrollment;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\RefundModel as Refund;
|
use App\Models\Refund;
|
||||||
use App\Services\FeeCalculationService;
|
use App\Services\FeeCalculationService;
|
||||||
|
|
||||||
class AdministratorEnrollmentRefundService
|
class AdministratorEnrollmentRefundService
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Services\Administrator;
|
namespace App\Services\Administrator;
|
||||||
|
|
||||||
|
use App\Mail\TeacherSubmissionReminderMail;
|
||||||
use App\Models\ClassSection;
|
use App\Models\ClassSection;
|
||||||
use App\Models\TeacherSubmissionNotificationHistory;
|
use App\Models\TeacherSubmissionNotificationHistory;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@@ -88,9 +89,7 @@ class TeacherSubmissionNotificationService
|
|||||||
|
|
||||||
if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
try {
|
try {
|
||||||
Mail::html($body, function ($message) use ($email, $subject) {
|
Mail::to($email)->send(new TeacherSubmissionReminderMail($subject, $body));
|
||||||
$message->to($email)->subject($subject);
|
|
||||||
});
|
|
||||||
$status = 'sent';
|
$status = 'sent';
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
Log::error('Teacher submission notification failed: ' . $e->getMessage());
|
Log::error('Teacher submission notification failed: ' . $e->getMessage());
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ class TeacherSubmissionReportService
|
|||||||
->where('class_section_id', $classSectionId)
|
->where('class_section_id', $classSectionId)
|
||||||
->where('semester', $semester)
|
->where('semester', $semester)
|
||||||
->where('school_year', $schoolYear)
|
->where('school_year', $schoolYear)
|
||||||
->where('date', $today)
|
->whereDate('date', $today)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
$attendanceSubmitted = $attendanceRow
|
$attendanceSubmitted = $attendanceRow
|
||||||
@@ -187,7 +187,7 @@ class TeacherSubmissionReportService
|
|||||||
$midtermCommentStatus = $this->support->submissionStatus(count($midtermCommentStudents), $expected);
|
$midtermCommentStatus = $this->support->submissionStatus(count($midtermCommentStudents), $expected);
|
||||||
$participationStatus = $this->support->submissionStatus(count($participationStudents), $expected);
|
$participationStatus = $this->support->submissionStatus(count($participationStudents), $expected);
|
||||||
$ptapCommentStatus = $this->support->submissionStatus(count($ptapCommentStudents), $expected);
|
$ptapCommentStatus = $this->support->submissionStatus(count($ptapCommentStudents), $expected);
|
||||||
$attendanceStatus = $this->support->attendanceStatus($attendanceSubmitted);
|
$attendanceStatus = $this->support->attendanceStatus($attendanceSubmitted, $expected);
|
||||||
|
|
||||||
$statusDetails = [
|
$statusDetails = [
|
||||||
'midterm_score_status' => $midtermScoreStatus,
|
'midterm_score_status' => $midtermScoreStatus,
|
||||||
|
|||||||
@@ -25,8 +25,16 @@ class TeacherSubmissionSupportService
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attendanceStatus(bool $submitted): array
|
public function attendanceStatus(bool $submitted, int $expected): array
|
||||||
{
|
{
|
||||||
|
if ($expected <= 0) {
|
||||||
|
return [
|
||||||
|
'label' => 'No students',
|
||||||
|
'badge' => 'bg-secondary',
|
||||||
|
'completed' => true,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => $submitted ? 'Submitted' : 'Missing',
|
'label' => $submitted ? 'Submitted' : 'Missing',
|
||||||
'badge' => $submitted ? 'bg-success' : 'bg-danger',
|
'badge' => $submitted ? 'bg-success' : 'bg-danger',
|
||||||
|
|||||||
@@ -20,7 +20,14 @@ class AssignmentDataLoaderService
|
|||||||
->with([
|
->with([
|
||||||
'teacher:id,firstname,lastname',
|
'teacher:id,firstname,lastname',
|
||||||
])
|
])
|
||||||
->when(filled($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
|
->when(
|
||||||
|
filled($schoolYear),
|
||||||
|
fn ($q) => $q->where(function ($query) use ($schoolYear) {
|
||||||
|
$query->where('school_year', $schoolYear)
|
||||||
|
->orWhereNull('school_year')
|
||||||
|
->orWhere('school_year', '');
|
||||||
|
})
|
||||||
|
)
|
||||||
->get()
|
->get()
|
||||||
->map(function ($row) {
|
->map(function ($row) {
|
||||||
$row->teacher_full_name = trim(
|
$row->teacher_full_name = trim(
|
||||||
@@ -40,7 +47,14 @@ class AssignmentDataLoaderService
|
|||||||
'student:id,firstname,lastname,age,gender,registration_grade,photo_consent,tuition_paid,school_id,is_active',
|
'student:id,firstname,lastname,age,gender,registration_grade,photo_consent,tuition_paid,school_id,is_active',
|
||||||
])
|
])
|
||||||
->whereHas('student', fn ($q) => $q->where('is_active', 1))
|
->whereHas('student', fn ($q) => $q->where('is_active', 1))
|
||||||
->when(filled($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
|
->when(
|
||||||
|
filled($schoolYear),
|
||||||
|
fn ($q) => $q->where(function ($query) use ($schoolYear) {
|
||||||
|
$query->where('school_year', $schoolYear)
|
||||||
|
->orWhereNull('school_year')
|
||||||
|
->orWhere('school_year', '');
|
||||||
|
})
|
||||||
|
)
|
||||||
->get();
|
->get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ class AssignmentSectionService
|
|||||||
|
|
||||||
return $this->classSection
|
return $this->classSection
|
||||||
->newQuery()
|
->newQuery()
|
||||||
->whereIn('id', $sectionIds)
|
->whereIn('class_section_id', $sectionIds)
|
||||||
->get()
|
->get()
|
||||||
->mapWithKeys(function ($section) {
|
->mapWithKeys(function ($section) {
|
||||||
$name = $section->class_section_name ?? $section->section_name ?? $section->name ?? '';
|
$name = $section->class_section_name ?? $section->section_name ?? $section->name ?? '';
|
||||||
return [(int) $section->id => (string) $name];
|
return [(int) $section->class_section_id => (string) $name];
|
||||||
})
|
})
|
||||||
->all();
|
->all();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Services\Assignment\AssignmentService as AssignmentDomainService;
|
||||||
|
|
||||||
|
class AssignmentService extends AssignmentDomainService
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -55,21 +55,17 @@ class AttendanceNotificationLogService
|
|||||||
?string $schoolYear = null
|
?string $schoolYear = null
|
||||||
): void {
|
): void {
|
||||||
try {
|
try {
|
||||||
$where = [
|
$existingQuery = $this->notificationModel->query()
|
||||||
'student_id' => $studentId,
|
->where('student_id', $studentId)
|
||||||
'code' => $code,
|
->where('code', $code)
|
||||||
'incident_date' => $ymd,
|
->whereDate('incident_date', $ymd)
|
||||||
'channel' => $channel,
|
->where('channel', $channel);
|
||||||
];
|
|
||||||
|
|
||||||
if (!empty($to)) {
|
if (!empty($to)) {
|
||||||
$where['to_address'] = $to;
|
$existingQuery->where('to_address', $to);
|
||||||
}
|
}
|
||||||
|
|
||||||
$existing = $this->notificationModel->query()
|
$existing = $existingQuery->orderByDesc('id')->first();
|
||||||
->where($where)
|
|
||||||
->orderByDesc('id')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($existing && !empty($existing->id)) {
|
if ($existing && !empty($existing->id)) {
|
||||||
$existing->update([
|
$existing->update([
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class AttendanceViolationStudentResolverService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$classStudents = $classStudentsQuery
|
$classStudents = $classStudentsQuery
|
||||||
->where('school_year', $schoolYear)
|
->where('student_class.school_year', $schoolYear)
|
||||||
->get()
|
->get()
|
||||||
->toArray();
|
->toArray();
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ class AttendanceViolationStudentResolverService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$classStudents = $classStudentsQuery
|
$classStudents = $classStudentsQuery
|
||||||
->where('school_year', $schoolYear)
|
->where('student_class.school_year', $schoolYear)
|
||||||
->get()
|
->get()
|
||||||
->toArray();
|
->toArray();
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ class BadgeTextFormatter
|
|||||||
{
|
{
|
||||||
$s = (string) $s;
|
$s = (string) $s;
|
||||||
$s = str_replace(["\xC2\xA0", "\xA0"], ' ', $s);
|
$s = str_replace(["\xC2\xA0", "\xA0"], ' ', $s);
|
||||||
$s = preg_replace('/\s+/u', ' ', $s) ?? $s;
|
|
||||||
$s = preg_replace('/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]/u', '', $s) ?? $s;
|
$s = preg_replace('/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]/u', '', $s) ?? $s;
|
||||||
|
$s = preg_replace('/\s+/u', ' ', $s) ?? $s;
|
||||||
|
|
||||||
return trim($s);
|
return trim($s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class BroadcastEmailSenderOptionsService
|
|||||||
{
|
{
|
||||||
public function listOptions(): array
|
public function listOptions(): array
|
||||||
{
|
{
|
||||||
$json = env('MAIL_SENDERS', '{}');
|
$json = getenv('MAIL_SENDERS') ?: env('MAIL_SENDERS', '{}');
|
||||||
$arr = json_decode($json, true);
|
$arr = json_decode($json, true);
|
||||||
|
|
||||||
if (!is_array($arr) || empty($arr)) {
|
if (!is_array($arr) || empty($arr)) {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class ClassPreparationCalculatorService
|
|||||||
$qty = $isLowerGrades ? 0 : $students;
|
$qty = $isLowerGrades ? 0 : $students;
|
||||||
break;
|
break;
|
||||||
case 'teacher chair':
|
case 'teacher chair':
|
||||||
$qty = (int) $teacherCount;
|
$qty = $teacherCount > 0 ? (int) $teacherCount : 1;
|
||||||
break;
|
break;
|
||||||
case 'trash bin':
|
case 'trash bin':
|
||||||
case 'white board':
|
case 'white board':
|
||||||
@@ -114,13 +114,22 @@ class ClassPreparationCalculatorService
|
|||||||
{
|
{
|
||||||
$schoolYear = $schoolYear ?: (string) Configuration::getConfig('school_year');
|
$schoolYear = $schoolYear ?: (string) Configuration::getConfig('school_year');
|
||||||
|
|
||||||
$row = DB::table('teacher_class')
|
$baseQuery = DB::table('teacher_class')
|
||||||
->select('COUNT(*) AS cnt')
|
->select('COUNT(*) AS cnt')
|
||||||
->where('class_section_id', $classSectionId)
|
->where('class_section_id', $classSectionId)
|
||||||
->whereIn('position', ['main', 'ta'])
|
->whereIn('position', ['main', 'ta']);
|
||||||
->where('school_year', $schoolYear)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
return (int) ($row->cnt ?? 0);
|
$row = $schoolYear !== null && $schoolYear !== ''
|
||||||
|
? (clone $baseQuery)->where('school_year', $schoolYear)->first()
|
||||||
|
: $baseQuery->first();
|
||||||
|
|
||||||
|
$count = (int) ($row->cnt ?? 0);
|
||||||
|
|
||||||
|
if ($count === 0 && $schoolYear !== null && $schoolYear !== '') {
|
||||||
|
$row = $baseQuery->first();
|
||||||
|
$count = (int) ($row->cnt ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class ClassPreparationInventoryService
|
|||||||
$inventoryMap = array_fill_keys($allowed, 0);
|
$inventoryMap = array_fill_keys($allowed, 0);
|
||||||
|
|
||||||
$joinRows = DB::table('inventory_items as ii')
|
$joinRows = DB::table('inventory_items as ii')
|
||||||
->select('ic.name AS item_name, COALESCE(SUM(CASE WHEN ii.good_qty IS NOT NULL THEN ii.good_qty WHEN ii.`condition`=\"good\" THEN ii.quantity ELSE 0 END),0) AS available')
|
->select('ic.name AS item_name, COALESCE(SUM(CASE WHEN ii.good_qty IS NOT NULL AND ii.good_qty > 0 THEN ii.good_qty WHEN ii.`condition`=\"good\" THEN ii.quantity ELSE ii.quantity END),0) AS available')
|
||||||
->join('inventory_categories as ic', 'ic.id', '=', 'ii.category_id')
|
->join('inventory_categories as ic', 'ic.id', '=', 'ii.category_id')
|
||||||
->where('ii.type', 'classroom')
|
->where('ii.type', 'classroom')
|
||||||
->where('ii.school_year', $schoolYear)
|
->where('ii.school_year', $schoolYear)
|
||||||
@@ -31,7 +31,7 @@ class ClassPreparationInventoryService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$nameRows = DB::table('inventory_items')
|
$nameRows = DB::table('inventory_items')
|
||||||
->select('name AS item_name, COALESCE(SUM(CASE WHEN good_qty IS NOT NULL THEN good_qty WHEN `condition`=\"good\" THEN quantity ELSE 0 END),0) AS available')
|
->select('name AS item_name, COALESCE(SUM(CASE WHEN good_qty IS NOT NULL AND good_qty > 0 THEN good_qty WHEN `condition`=\"good\" THEN quantity ELSE quantity END),0) AS available')
|
||||||
->where('type', 'classroom')
|
->where('type', 'classroom')
|
||||||
->where('school_year', $schoolYear)
|
->where('school_year', $schoolYear)
|
||||||
->whereIn('name', $allowed);
|
->whereIn('name', $allowed);
|
||||||
@@ -49,6 +49,49 @@ class ClassPreparationInventoryService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$needsFallback = array_filter($inventoryMap, static fn ($v) => (int) $v === 0);
|
||||||
|
if (!empty($needsFallback)) {
|
||||||
|
$fallbackRows = DB::table('inventory_items')
|
||||||
|
->select('name AS item_name, COALESCE(SUM(CASE WHEN good_qty IS NOT NULL AND good_qty > 0 THEN good_qty WHEN `condition`=\"good\" THEN quantity ELSE quantity END),0) AS available')
|
||||||
|
->where('type', 'classroom')
|
||||||
|
->whereIn('name', array_keys($needsFallback))
|
||||||
|
->groupBy('name')
|
||||||
|
->get()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
foreach ($fallbackRows as $r) {
|
||||||
|
$name = (string) ($r->item_name ?? '');
|
||||||
|
if ($name !== '' && isset($inventoryMap[$name])) {
|
||||||
|
$inventoryMap[$name] = max($inventoryMap[$name], (int) ($r->available ?? 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($inventoryMap as $name => $value) {
|
||||||
|
if ((int) $value !== 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$goodQty = (int) DB::table('inventory_items')
|
||||||
|
->where('type', 'classroom')
|
||||||
|
->where('name', $name)
|
||||||
|
->sum('good_qty');
|
||||||
|
|
||||||
|
if ($goodQty > 0) {
|
||||||
|
$inventoryMap[$name] = $goodQty;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$qty = (int) DB::table('inventory_items')
|
||||||
|
->where('type', 'classroom')
|
||||||
|
->where('name', $name)
|
||||||
|
->sum('quantity');
|
||||||
|
|
||||||
|
if ($qty > 0) {
|
||||||
|
$inventoryMap[$name] = $qty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $inventoryMap;
|
return $inventoryMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class ClassPreparationRosterService
|
|||||||
public function getClassSectionStudentCounts(string $schoolYear, string $semester, bool $limitToSemester): array
|
public function getClassSectionStudentCounts(string $schoolYear, string $semester, bool $limitToSemester): array
|
||||||
{
|
{
|
||||||
$query = DB::table('student_class as sc')
|
$query = DB::table('student_class as sc')
|
||||||
->select('sc.class_section_id, COUNT(DISTINCT sc.student_id) AS student_count', false)
|
->selectRaw('sc.class_section_id, COUNT(DISTINCT sc.student_id) AS student_count')
|
||||||
->join('students as s', 's.id', '=', 'sc.student_id')
|
->join('students as s', 's.id', '=', 'sc.student_id')
|
||||||
->where('s.is_active', 1)
|
->where('s.is_active', 1)
|
||||||
->where('sc.school_year', $schoolYear);
|
->where('sc.school_year', $schoolYear);
|
||||||
@@ -24,7 +24,7 @@ class ClassPreparationRosterService
|
|||||||
public function getStudentCountForSection(string $schoolYear, string $semester, bool $limitToSemester, string $classSectionId): int
|
public function getStudentCountForSection(string $schoolYear, string $semester, bool $limitToSemester, string $classSectionId): int
|
||||||
{
|
{
|
||||||
$query = DB::table('student_class as sc')
|
$query = DB::table('student_class as sc')
|
||||||
->select('COUNT(DISTINCT sc.student_id) AS cnt', false)
|
->selectRaw('COUNT(DISTINCT sc.student_id) AS cnt')
|
||||||
->join('students as s', 's.id', '=', 'sc.student_id')
|
->join('students as s', 's.id', '=', 'sc.student_id')
|
||||||
->where('s.is_active', 1)
|
->where('s.is_active', 1)
|
||||||
->where('sc.class_section_id', $classSectionId)
|
->where('sc.class_section_id', $classSectionId)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class CompetitionScoresSaveService
|
|||||||
->where('competition_id', $competitionId)
|
->where('competition_id', $competitionId)
|
||||||
->where('class_section_id', $classSectionId)
|
->where('class_section_id', $classSectionId)
|
||||||
->get()
|
->get()
|
||||||
->map(fn ($row) => (array) $row)
|
->map(fn ($row) => $row->toArray())
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
$map = [];
|
$map = [];
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Services\Fees\FeeRefundCalculatorService;
|
||||||
|
|
||||||
|
class FeeCalculationService
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private FeeRefundCalculatorService $refundCalculator
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function calculateRefund(array $students, int $parentId): float
|
||||||
|
{
|
||||||
|
$result = $this->refundCalculator->calculateRefund($students, $parentId);
|
||||||
|
return (float) ($result['refund_amount'] ?? 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,20 +6,24 @@ class FeeGradeService
|
|||||||
{
|
{
|
||||||
public function normalizeGrade(?string $grade): string
|
public function normalizeGrade(?string $grade): string
|
||||||
{
|
{
|
||||||
return strtoupper(trim((string) $grade));
|
$normalized = strtoupper(trim((string) $grade));
|
||||||
|
return str_replace([' ', '-'], '', $normalized);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function compareGrades(string $gradeA, string $gradeB): int
|
public function compareGrades(string $gradeA, string $gradeB): int
|
||||||
{
|
{
|
||||||
$valA = $this->getGradeLevel($gradeA);
|
$normA = $this->normalizeGrade($gradeA);
|
||||||
$valB = $this->getGradeLevel($gradeB);
|
$normB = $this->normalizeGrade($gradeB);
|
||||||
|
|
||||||
|
$valA = $this->getGradeLevel($normA);
|
||||||
|
$valB = $this->getGradeLevel($normB);
|
||||||
|
|
||||||
if ($valA !== $valB) {
|
if ($valA !== $valB) {
|
||||||
return $valA <=> $valB;
|
return $valA <=> $valB;
|
||||||
}
|
}
|
||||||
|
|
||||||
preg_match('/\d+([A-Z]*)$/i', strtoupper($gradeA), $suffixA);
|
preg_match('/\d+([A-Z]*)$/i', $normA, $suffixA);
|
||||||
preg_match('/\d+([A-Z]*)$/i', strtoupper($gradeB), $suffixB);
|
preg_match('/\d+([A-Z]*)$/i', $normB, $suffixB);
|
||||||
|
|
||||||
return strcmp($suffixA[1] ?? '', $suffixB[1] ?? '');
|
return strcmp($suffixA[1] ?? '', $suffixB[1] ?? '');
|
||||||
}
|
}
|
||||||
@@ -35,7 +39,7 @@ class FeeGradeService
|
|||||||
return 99;
|
return 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match('/^(\d+)([A-Z]*)$/i', $grade, $matches)) {
|
if (preg_match('/^(\d+)/', $grade, $matches)) {
|
||||||
return (int) $matches[1];
|
return (int) $matches[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class FinancialSummaryService
|
|||||||
$query = DB::table('additional_charges as ac')
|
$query = DB::table('additional_charges as ac')
|
||||||
->selectRaw('COALESCE(SUM(ac.amount), 0) AS amount')
|
->selectRaw('COALESCE(SUM(ac.amount), 0) AS amount')
|
||||||
->where('ac.school_year', $schoolYear)
|
->where('ac.school_year', $schoolYear)
|
||||||
->where('ac.status !=', 'void');
|
->where('ac.status', '!=', 'void');
|
||||||
|
|
||||||
if (!empty($dateFrom)) {
|
if (!empty($dateFrom)) {
|
||||||
$query->whereRaw('DATE(ac.due_date) >= ?', [$dateFrom]);
|
$query->whereRaw('DATE(ac.due_date) >= ?', [$dateFrom]);
|
||||||
@@ -115,11 +115,11 @@ class FinancialSummaryService
|
|||||||
$query = DB::table('additional_charges as ac')
|
$query = DB::table('additional_charges as ac')
|
||||||
->selectRaw('ac.parent_id, COALESCE(SUM(ac.amount), 0) AS amount')
|
->selectRaw('ac.parent_id, COALESCE(SUM(ac.amount), 0) AS amount')
|
||||||
->where('ac.school_year', $schoolYear)
|
->where('ac.school_year', $schoolYear)
|
||||||
->where('ac.status !=', 'void')
|
->where('ac.status', '!=', 'void')
|
||||||
->where(function ($q) {
|
->where(function ($q) {
|
||||||
$q->whereNull('ac.invoice_id')
|
$q->whereNull('ac.invoice_id')
|
||||||
->orWhere('ac.invoice_id', 0)
|
->orWhere('ac.invoice_id', 0)
|
||||||
->orWhere('ac.status !=', 'applied');
|
->orWhere('ac.status', '!=', 'applied');
|
||||||
})
|
})
|
||||||
->groupBy('ac.parent_id');
|
->groupBy('ac.parent_id');
|
||||||
|
|
||||||
|
|||||||
@@ -96,17 +96,14 @@ class FinancialUnpaidParentsService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$extraRows = DB::table('additional_charges as ac')
|
$extraRows = DB::table('additional_charges as ac')
|
||||||
->selectRaw(
|
->selectRaw("ac.parent_id, u.firstname, u.lastname, u.email, COALESCE(SUM(ac.amount), 0) AS total_extra")
|
||||||
"ac.parent_id, u.firstname, u.lastname, u.email, COALESCE(SUM(ac.amount), 0) AS total_extra",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
->leftJoin('users as u', 'u.id', '=', 'ac.parent_id')
|
->leftJoin('users as u', 'u.id', '=', 'ac.parent_id')
|
||||||
->where('ac.school_year', $schoolYear)
|
->where('ac.school_year', $schoolYear)
|
||||||
->where('ac.status !=', 'void')
|
->where('ac.status', '!=', 'void')
|
||||||
->where(function ($q) {
|
->where(function ($q) {
|
||||||
$q->whereNull('ac.invoice_id')
|
$q->whereNull('ac.invoice_id')
|
||||||
->orWhere('ac.invoice_id', 0)
|
->orWhere('ac.invoice_id', 0)
|
||||||
->orWhere('ac.status !=', 'applied');
|
->orWhere('ac.status', '!=', 'applied');
|
||||||
})
|
})
|
||||||
->groupBy('ac.parent_id')
|
->groupBy('ac.parent_id')
|
||||||
->get()
|
->get()
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ class HomeworkTrackingService
|
|||||||
->whereIn('tc.position', ['main', 'ta'])
|
->whereIn('tc.position', ['main', 'ta'])
|
||||||
->orderBy('cs.class_id', 'ASC')
|
->orderBy('cs.class_id', 'ASC')
|
||||||
->orderBy('cs.class_section_name', 'ASC')
|
->orderBy('cs.class_section_name', 'ASC')
|
||||||
->orderByRaw("FIELD(tc.position, 'main','ta')")
|
->orderByRaw("CASE tc.position WHEN 'main' THEN 0 WHEN 'ta' THEN 1 ELSE 2 END")
|
||||||
->orderBy('u.firstname', 'ASC')
|
->orderBy('u.firstname', 'ASC')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
|||||||
@@ -65,13 +65,13 @@ class IncidentAnalysisService
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($students[$studentKey]['last_incident'] === null) {
|
if ($students[$studentKey]['last_incident'] === null) {
|
||||||
$students[$studentKey]['last_incident'] = $incident['incident_datetime'] ?? null;
|
$students[$studentKey]['last_incident'] = $this->formatIncidentDate($incident['incident_datetime'] ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
$students[$studentKey]['logs'][] = [
|
$students[$studentKey]['logs'][] = [
|
||||||
'incident' => $incident['incident'] ?? '',
|
'incident' => $incident['incident'] ?? '',
|
||||||
'incident_state' => $state,
|
'incident_state' => $state,
|
||||||
'incident_datetime' => $incident['incident_datetime'] ?? null,
|
'incident_datetime' => $this->formatIncidentDate($incident['incident_datetime'] ?? null),
|
||||||
'open_description' => $incident['open_description'] ?? null,
|
'open_description' => $incident['open_description'] ?? null,
|
||||||
'close_description' => $incident['close_description'] ?? null,
|
'close_description' => $incident['close_description'] ?? null,
|
||||||
'cancel_description' => $incident['cancel_description'] ?? null,
|
'cancel_description' => $incident['cancel_description'] ?? null,
|
||||||
@@ -89,4 +89,23 @@ class IncidentAnalysisService
|
|||||||
|
|
||||||
return $studentRows;
|
return $studentRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function formatIncidentDate(mixed $value): ?string
|
||||||
|
{
|
||||||
|
if ($value === null || $value === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value instanceof \DateTimeInterface) {
|
||||||
|
return $value->format('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
|
||||||
|
$raw = (string) $value;
|
||||||
|
$ts = strtotime($raw);
|
||||||
|
if ($ts !== false) {
|
||||||
|
return date('Y-m-d H:i:s', $ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $raw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,16 +69,20 @@ class IncidentLookupService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$rows = DB::table('users')
|
$rows = DB::table('users')
|
||||||
->select('id, firstname, lastname')
|
->select('id', 'firstname', 'lastname')
|
||||||
->whereIn('id', $userIds)
|
->whereIn('id', $userIds)
|
||||||
->get()
|
->get()
|
||||||
->map(fn ($row) => (array) $row)
|
->map(fn ($row) => $row instanceof \Illuminate\Contracts\Support\Arrayable ? $row->toArray() : (array) $row)
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
$map = [];
|
$map = [];
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
|
$id = $row['id'] ?? $row['user_id'] ?? null;
|
||||||
|
if ($id === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$name = trim((string) ($row['firstname'] ?? '') . ' ' . (string) ($row['lastname'] ?? ''));
|
$name = trim((string) ($row['firstname'] ?? '') . ' ' . (string) ($row['lastname'] ?? ''));
|
||||||
$map[(int) $row['id']] = $name !== '' ? $name : ('User #' . $row['id']);
|
$map[(int) $id] = $name !== '' ? $name : ('User #' . $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $map;
|
return $map;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class InvoiceGenerationService
|
|||||||
->where('parent_id', $parentId)
|
->where('parent_id', $parentId)
|
||||||
->where('school_year', $schoolYear)
|
->where('school_year', $schoolYear)
|
||||||
->get()
|
->get()
|
||||||
->map(fn ($r) => (array) $r)
|
->map(fn ($r) => $r->toArray())
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
if (empty($enrollments)) {
|
if (empty($enrollments)) {
|
||||||
|
|||||||
@@ -40,7 +40,11 @@ class InvoiceManagementService
|
|||||||
$parents = User::getUsersByRoleAndSchoolYear('parent', $schoolYear);
|
$parents = User::getUsersByRoleAndSchoolYear('parent', $schoolYear);
|
||||||
|
|
||||||
foreach ($parents as $parent) {
|
foreach ($parents as $parent) {
|
||||||
$students = Student::query()->where('parent_id', $parent['id'])->get()->map(fn ($r) => (array) $r)->all();
|
$students = Student::query()
|
||||||
|
->where('parent_id', $parent['id'])
|
||||||
|
->get()
|
||||||
|
->map(fn ($r) => $r->toArray())
|
||||||
|
->all();
|
||||||
|
|
||||||
$parentData = [
|
$parentData = [
|
||||||
'parent_name' => trim(($parent['firstname'] ?? '') . ' ' . ($parent['lastname'] ?? '')),
|
'parent_name' => trim(($parent['firstname'] ?? '') . ' ' . ($parent['lastname'] ?? '')),
|
||||||
@@ -106,7 +110,7 @@ class InvoiceManagementService
|
|||||||
->where('student_id', $student['id'])
|
->where('student_id', $student['id'])
|
||||||
->where('school_year', $schoolYear)
|
->where('school_year', $schoolYear)
|
||||||
->get()
|
->get()
|
||||||
->map(fn ($r) => (array) $r)
|
->map(fn ($r) => $r->toArray())
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
foreach ($enrollments as $enrollment) {
|
foreach ($enrollments as $enrollment) {
|
||||||
|
|||||||
@@ -94,6 +94,10 @@ class ExamScoreService
|
|||||||
if (!is_numeric($studentId)) {
|
if (!is_numeric($studentId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
$student = Student::query()->find((int) $studentId);
|
||||||
|
if (!$student) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$rawScore = $data['score'] ?? null;
|
$rawScore = $data['score'] ?? null;
|
||||||
$normalizedScore = is_numeric($rawScore) ? (float) $rawScore : null;
|
$normalizedScore = is_numeric($rawScore) ? (float) $rawScore : null;
|
||||||
|
|
||||||
@@ -106,6 +110,7 @@ class ExamScoreService
|
|||||||
|
|
||||||
$payload = [
|
$payload = [
|
||||||
'student_id' => (int) $studentId,
|
'student_id' => (int) $studentId,
|
||||||
|
'school_id' => $student->school_id,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'updated_by' => $updatedBy,
|
'updated_by' => $updatedBy,
|
||||||
'score' => $normalizedScore,
|
'score' => $normalizedScore,
|
||||||
|
|||||||
@@ -57,12 +57,13 @@ class HomeworkScoreService
|
|||||||
->whereIn('semester', $semVariants)
|
->whereIn('semester', $semVariants)
|
||||||
->where('school_year', $schoolYear)
|
->where('school_year', $schoolYear)
|
||||||
->get()
|
->get()
|
||||||
->map(fn ($row) => (array) $row)
|
->map(fn ($row) => $row->toArray())
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
$scoresMap = [];
|
$scoresMap = [];
|
||||||
foreach ($scoresRows as $row) {
|
foreach ($scoresRows as $row) {
|
||||||
$scoresMap[(int) $row['student_id']][(int) $row['homework_index']] = $row['score'];
|
$score = $row['score'] ?? null;
|
||||||
|
$scoresMap[(int) $row['student_id']][(int) $row['homework_index']] = is_numeric($score) ? (float) $score : $score;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($students as &$student) {
|
foreach ($students as &$student) {
|
||||||
@@ -196,6 +197,10 @@ class HomeworkScoreService
|
|||||||
->get();
|
->get();
|
||||||
|
|
||||||
foreach ($students as $student) {
|
foreach ($students as $student) {
|
||||||
|
$studentRow = Student::query()->find((int) $student->student_id);
|
||||||
|
if (!$studentRow) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$exists = Homework::query()
|
$exists = Homework::query()
|
||||||
->where('student_id', $student->student_id)
|
->where('student_id', $student->student_id)
|
||||||
->where('homework_index', $nextIndex)
|
->where('homework_index', $nextIndex)
|
||||||
@@ -210,6 +215,7 @@ class HomeworkScoreService
|
|||||||
|
|
||||||
Homework::query()->create([
|
Homework::query()->create([
|
||||||
'student_id' => (int) $student->student_id,
|
'student_id' => (int) $student->student_id,
|
||||||
|
'school_id' => $studentRow->school_id,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'updated_by' => $updatedBy,
|
'updated_by' => $updatedBy,
|
||||||
'homework_index' => $nextIndex,
|
'homework_index' => $nextIndex,
|
||||||
|
|||||||
@@ -50,12 +50,14 @@ class ParticipationScoreService
|
|||||||
|
|
||||||
$scoreMap = [];
|
$scoreMap = [];
|
||||||
foreach ($scoresRows as $row) {
|
foreach ($scoresRows as $row) {
|
||||||
$scoreMap[(int) $row->student_id] = $row->score;
|
$score = $row->score;
|
||||||
|
$scoreMap[(int) $row->student_id] = is_numeric($score) ? (float) $score : $score;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($students as &$student) {
|
foreach ($students as &$student) {
|
||||||
|
$score = $scoreMap[$student['student_id']] ?? '';
|
||||||
$student['scores'] = [
|
$student['scores'] = [
|
||||||
'score' => $scoreMap[$student['student_id']] ?? '',
|
'score' => $score,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
unset($student);
|
unset($student);
|
||||||
|
|||||||
@@ -57,12 +57,13 @@ class ProjectScoreService
|
|||||||
->where('semester', $semester)
|
->where('semester', $semester)
|
||||||
->where('school_year', $schoolYear)
|
->where('school_year', $schoolYear)
|
||||||
->get()
|
->get()
|
||||||
->map(fn ($row) => (array) $row)
|
->map(fn ($row) => $row->toArray())
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
$scoresMap = [];
|
$scoresMap = [];
|
||||||
foreach ($scoresRows as $row) {
|
foreach ($scoresRows as $row) {
|
||||||
$scoresMap[(int) $row['student_id']][(int) $row['project_index']] = $row['score'];
|
$score = $row['score'] ?? null;
|
||||||
|
$scoresMap[(int) $row['student_id']][(int) $row['project_index']] = is_numeric($score) ? (float) $score : $score;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($students as &$student) {
|
foreach ($students as &$student) {
|
||||||
@@ -193,6 +194,10 @@ class ProjectScoreService
|
|||||||
->get();
|
->get();
|
||||||
|
|
||||||
foreach ($students as $student) {
|
foreach ($students as $student) {
|
||||||
|
$studentRow = Student::query()->find((int) $student->student_id);
|
||||||
|
if (!$studentRow) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$exists = Project::query()
|
$exists = Project::query()
|
||||||
->where('student_id', $student->student_id)
|
->where('student_id', $student->student_id)
|
||||||
->where('project_index', $nextIndex)
|
->where('project_index', $nextIndex)
|
||||||
@@ -207,6 +212,7 @@ class ProjectScoreService
|
|||||||
|
|
||||||
Project::query()->create([
|
Project::query()->create([
|
||||||
'student_id' => (int) $student->student_id,
|
'student_id' => (int) $student->student_id,
|
||||||
|
'school_id' => $studentRow->school_id,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'updated_by' => $updatedBy,
|
'updated_by' => $updatedBy,
|
||||||
'project_index' => $nextIndex,
|
'project_index' => $nextIndex,
|
||||||
|
|||||||
@@ -56,12 +56,13 @@ class QuizScoreService
|
|||||||
->where('semester', $semester)
|
->where('semester', $semester)
|
||||||
->where('school_year', $schoolYear)
|
->where('school_year', $schoolYear)
|
||||||
->get()
|
->get()
|
||||||
->map(fn ($row) => (array) $row)
|
->map(fn ($row) => $row->toArray())
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
$scoresMap = [];
|
$scoresMap = [];
|
||||||
foreach ($scoresRows as $row) {
|
foreach ($scoresRows as $row) {
|
||||||
$scoresMap[(int) $row['student_id']][(int) $row['quiz_index']] = $row['score'];
|
$score = $row['score'] ?? null;
|
||||||
|
$scoresMap[(int) $row['student_id']][(int) $row['quiz_index']] = is_numeric($score) ? (float) $score : $score;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($students as &$student) {
|
foreach ($students as &$student) {
|
||||||
@@ -135,6 +136,10 @@ class QuizScoreService
|
|||||||
if (!is_array($quizData)) {
|
if (!is_array($quizData)) {
|
||||||
$quizData = [1 => $quizData];
|
$quizData = [1 => $quizData];
|
||||||
}
|
}
|
||||||
|
$student = Student::query()->find((int) $studentId);
|
||||||
|
if (!$student) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
foreach ($quizData as $quizNumber => $score) {
|
foreach ($quizData as $quizNumber => $score) {
|
||||||
if (!is_numeric($quizNumber)) {
|
if (!is_numeric($quizNumber)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -152,6 +157,7 @@ class QuizScoreService
|
|||||||
|
|
||||||
$payload = [
|
$payload = [
|
||||||
'student_id' => (int) $studentId,
|
'student_id' => (int) $studentId,
|
||||||
|
'school_id' => $student->school_id,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'updated_by' => $updatedBy,
|
'updated_by' => $updatedBy,
|
||||||
'quiz_index' => (int) $quizNumber,
|
'quiz_index' => (int) $quizNumber,
|
||||||
@@ -190,6 +196,10 @@ class QuizScoreService
|
|||||||
->get();
|
->get();
|
||||||
|
|
||||||
foreach ($students as $student) {
|
foreach ($students as $student) {
|
||||||
|
$studentRow = Student::query()->find((int) $student->student_id);
|
||||||
|
if (!$studentRow) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$exists = Quiz::query()
|
$exists = Quiz::query()
|
||||||
->where('student_id', $student->student_id)
|
->where('student_id', $student->student_id)
|
||||||
->where('quiz_index', $nextIndex)
|
->where('quiz_index', $nextIndex)
|
||||||
@@ -204,6 +214,7 @@ class QuizScoreService
|
|||||||
|
|
||||||
Quiz::query()->create([
|
Quiz::query()->create([
|
||||||
'student_id' => (int) $student->student_id,
|
'student_id' => (int) $student->student_id,
|
||||||
|
'school_id' => $studentRow->school_id,
|
||||||
'class_section_id' => $classSectionId,
|
'class_section_id' => $classSectionId,
|
||||||
'updated_by' => $updatedBy,
|
'updated_by' => $updatedBy,
|
||||||
'quiz_index' => $nextIndex,
|
'quiz_index' => $nextIndex,
|
||||||
|
|||||||
@@ -111,14 +111,14 @@ class ScoreDashboardService
|
|||||||
$sid = $student['student_id'];
|
$sid = $student['student_id'];
|
||||||
$scoreRow = $scores[$sid] ?? null;
|
$scoreRow = $scores[$sid] ?? null;
|
||||||
$student['scores'] = $scoreRow ? [
|
$student['scores'] = $scoreRow ? [
|
||||||
'homework' => $scoreRow->homework_avg,
|
'homework' => $this->normalizeScore($scoreRow->homework_avg),
|
||||||
'quiz' => $scoreRow->quiz_avg,
|
'quiz' => $this->normalizeScore($scoreRow->quiz_avg),
|
||||||
'project' => $scoreRow->project_avg,
|
'project' => $this->normalizeScore($scoreRow->project_avg),
|
||||||
'midterm_exam' => $scoreRow->midterm_exam_score,
|
'midterm_exam' => $this->normalizeScore($scoreRow->midterm_exam_score),
|
||||||
'final_exam' => $scoreRow->final_exam_score,
|
'final_exam' => $this->normalizeScore($scoreRow->final_exam_score),
|
||||||
'attendance' => $scoreRow->attendance_score,
|
'attendance' => $this->normalizeScore($scoreRow->attendance_score),
|
||||||
'ptap' => $scoreRow->ptap_score,
|
'ptap' => $this->normalizeScore($scoreRow->ptap_score),
|
||||||
'semester' => $scoreRow->semester_score,
|
'semester' => $this->normalizeScore($scoreRow->semester_score),
|
||||||
] : [];
|
] : [];
|
||||||
$student['comments'] = $commentMap[$sid] ?? [];
|
$student['comments'] = $commentMap[$sid] ?? [];
|
||||||
}
|
}
|
||||||
@@ -267,4 +267,13 @@ class ScoreDashboardService
|
|||||||
'selectedYear' => $schoolYear,
|
'selectedYear' => $schoolYear,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function normalizeScore(mixed $value): mixed
|
||||||
|
{
|
||||||
|
if ($value === null || $value === '') {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_numeric($value) ? (float) $value : $value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class UserManagementService
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
DB::transaction(function () use ($userId, $user) {
|
DB::transaction(function () use ($userId, $user) {
|
||||||
UserRole::query()->where('user_id', $userId)->delete();
|
UserRole::query()->where('user_id', $userId)->forceDelete();
|
||||||
$user->delete();
|
$user->delete();
|
||||||
});
|
});
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user